diff options
author | donal.k.fellows@manchester.ac.uk <dkf> | 2005-08-10 22:02:21 (GMT) |
---|---|---|
committer | donal.k.fellows@manchester.ac.uk <dkf> | 2005-08-10 22:02:21 (GMT) |
commit | 0a14a4ea9b113d11a59f643f4e3a8dd5e59e9a5e (patch) | |
tree | 9d4e60b064aa3377d392ff30035da3ba8ba121ae | |
parent | bfd202baf521dd08d16c667cb7940dda7181bc88 (diff) | |
download | tk-0a14a4ea9b113d11a59f643f4e3a8dd5e59e9a5e.zip tk-0a14a4ea9b113d11a59f643f4e3a8dd5e59e9a5e.tar.gz tk-0a14a4ea9b113d11a59f643f4e3a8dd5e59e9a5e.tar.bz2 |
Getting more systematic about style
Also start removing _ANSI_ARGS_; the core's required ANSI C for a while now
Also fix [Bug 1252702]; size_t doesn't mix with Tcl_GetStringFromObj
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | generic/tkBind.c | 3030 | ||||
-rw-r--r-- | generic/tkCanvLine.c | 8 | ||||
-rw-r--r-- | generic/tkCanvPoly.c | 8 | ||||
-rw-r--r-- | generic/tkCanvText.c | 20 | ||||
-rw-r--r-- | generic/tkCanvas.c | 8 | ||||
-rw-r--r-- | generic/tkConfig.c | 1830 | ||||
-rw-r--r-- | generic/tkEntry.c | 2973 | ||||
-rw-r--r-- | generic/tkFocus.c | 573 | ||||
-rw-r--r-- | generic/tkFont.c | 1721 | ||||
-rw-r--r-- | generic/tkFrame.c | 853 | ||||
-rw-r--r-- | generic/tkGrid.c | 1140 | ||||
-rw-r--r-- | generic/tkImage.c | 775 | ||||
-rw-r--r-- | generic/tkImgGIF.c | 293 | ||||
-rw-r--r-- | generic/tkImgPPM.c | 238 | ||||
-rw-r--r-- | generic/tkImgPhoto.c | 2156 | ||||
-rw-r--r-- | generic/tkObj.c | 362 | ||||
-rw-r--r-- | generic/tkOption.c | 766 | ||||
-rw-r--r-- | generic/tkPack.c | 724 | ||||
-rw-r--r-- | generic/tkRectOval.c | 650 | ||||
-rw-r--r-- | generic/tkText.c | 5116 | ||||
-rw-r--r-- | generic/tkTextImage.c | 447 | ||||
-rw-r--r-- | generic/tkTextIndex.c | 1206 | ||||
-rw-r--r-- | generic/tkTextTag.c | 1782 | ||||
-rw-r--r-- | unix/tkUnix.c | 33 | ||||
-rw-r--r-- | win/tkWinDialog.c | 1652 | ||||
-rw-r--r-- | win/tkWinMenu.c | 1870 |
27 files changed, 15183 insertions, 15057 deletions
@@ -1,3 +1,9 @@ +2005-08-10 Donal K. Fellows <dkf@users.sf.net> + + * generic/tkFrame.c (CreateFrame) and others: Don't use size_t + when working with Tcl_GetStringFromObj because it is not 64-bit + clean. [Bug 1252702] + 2005-08-04 Vince Darley <vincentdarley@users.sourceforge.net> * doc/text.n: Clarify behaviour of tab stops (as per [Bug 1247835]) diff --git a/generic/tkBind.c b/generic/tkBind.c index c8a5b78..c6df007 100644 --- a/generic/tkBind.c +++ b/generic/tkBind.c @@ -1,17 +1,17 @@ -/* +/* * tkBind.c -- * - * This file provides procedures that associate Tcl commands - * with X events or sequences of X events. + * This file provides functions that associate Tcl commands with X events + * or sequences of X events. * * Copyright (c) 1989-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 1998 by Scriptics Corporation. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkBind.c,v 1.35 2004/08/29 09:27:35 dkf Exp $ + * RCS: @(#) $Id: tkBind.c,v 1.36 2005/08/10 22:02:22 dkf Exp $ */ #include "tkPort.h" @@ -25,7 +25,6 @@ #include "tkUnixInt.h" #endif - /* * File structure: * @@ -46,111 +45,109 @@ * Non-package-specific helpers. */ - /* - * The following union is used to hold the detail information from an - * XEvent (including Tk's XVirtualEvent extension). + * The following union is used to hold the detail information from an XEvent + * (including Tk's XVirtualEvent extension). */ + typedef union { - KeySym keySym; /* KeySym that corresponds to xkey.keycode. */ - int button; /* Button that was pressed (xbutton.button). */ - Tk_Uid name; /* Tk_Uid of virtual event. */ - ClientData clientData; /* Used when type of Detail is unknown, and to - * ensure that all bytes of Detail are initialized - * when this structure is used in a hash key. */ + KeySym keySym; /* KeySym that corresponds to xkey.keycode. */ + int button; /* Button that was pressed (xbutton.button). */ + Tk_Uid name; /* Tk_Uid of virtual event. */ + ClientData clientData; /* Used when type of Detail is unknown, and to + * ensure that all bytes of Detail are + * initialized when this structure is used in + * a hash key. */ } Detail; /* - * The structure below represents a binding table. A binding table - * represents a domain in which event bindings may occur. It includes - * a space of objects relative to which events occur (usually windows, - * but not always), a history of recent events in the domain, and - * a set of mappings that associate particular Tcl commands with sequences - * of events in the domain. Multiple binding tables may exist at once, - * either because there are multiple applications open, or because there - * are multiple domains within an application with separate event - * bindings for each (for example, each canvas widget has a separate - * binding table for associating events with the items in the canvas). - * - * Note: it is probably a bad idea to reduce EVENT_BUFFER_SIZE much - * below 30. To see this, consider a triple mouse button click while - * the Shift key is down (and auto-repeating). There may be as many - * as 3 auto-repeat events after each mouse button press or release - * (see the first large comment block within Tk_BindEvent for more on - * this), for a total of 20 events to cover the three button presses - * and two intervening releases. If you reduce EVENT_BUFFER_SIZE too - * much, shift multi-clicks will be lost. - * + * The structure below represents a binding table. A binding table represents + * a domain in which event bindings may occur. It includes a space of objects + * relative to which events occur (usually windows, but not always), a history + * of recent events in the domain, and a set of mappings that associate + * particular Tcl commands with sequences of events in the domain. Multiple + * binding tables may exist at once, either because there are multiple + * applications open, or because there are multiple domains within an + * application with separate event bindings for each (for example, each canvas + * widget has a separate binding table for associating events with the items + * in the canvas). + * + * Note: it is probably a bad idea to reduce EVENT_BUFFER_SIZE much below 30. + * To see this, consider a triple mouse button click while the Shift key is + * down (and auto-repeating). There may be as many as 3 auto-repeat events + * after each mouse button press or release (see the first large comment block + * within Tk_BindEvent for more on this), for a total of 20 events to cover + * the three button presses and two intervening releases. If you reduce + * EVENT_BUFFER_SIZE too much, shift multi-clicks will be lost. */ #define EVENT_BUFFER_SIZE 30 typedef struct BindingTable { - XEvent eventRing[EVENT_BUFFER_SIZE];/* Circular queue of recent events - * (higher indices are for more recent - * events). */ - Detail detailRing[EVENT_BUFFER_SIZE];/* "Detail" information (keySym, - * button, Tk_Uid, or 0) for each - * entry in eventRing. */ - int curEvent; /* Index in eventRing of most recent - * event. Newer events have higher - * indices. */ - Tcl_HashTable patternTable; /* Used to map from an event to a - * list of patterns that may match that - * event. Keys are PatternTableKey - * structs, values are (PatSeq *). */ - Tcl_HashTable objectTable; /* Used to map from an object to a - * list of patterns associated with - * that object. Keys are ClientData, - * values are (PatSeq *). */ - Tcl_Interp *interp; /* Interpreter in which commands are - * executed. */ + XEvent eventRing[EVENT_BUFFER_SIZE]; + /* Circular queue of recent events (higher + * indices are for more recent events). */ + Detail detailRing[EVENT_BUFFER_SIZE]; + /* "Detail" information (keySym, button, + * Tk_Uid, or 0) for each entry in + * eventRing. */ + int curEvent; /* Index in eventRing of most recent event. + * Newer events have higher indices. */ + Tcl_HashTable patternTable; /* Used to map from an event to a list of + * patterns that may match that event. Keys + * are PatternTableKey structs, values are + * (PatSeq *). */ + Tcl_HashTable objectTable; /* Used to map from an object to a list of + * patterns associated with that object. Keys + * are ClientData, values are (PatSeq *). */ + Tcl_Interp *interp; /* Interpreter in which commands are + * executed. */ } BindingTable; /* - * The following structure represents virtual event table. A virtual event - * table provides a way to map from platform-specific physical events such - * as button clicks or key presses to virtual events such as <<Paste>>, + * The following structure represents virtual event table. A virtual event + * table provides a way to map from platform-specific physical events such as + * button clicks or key presses to virtual events such as <<Paste>>, * <<Close>>, or <<ScrollWindow>>. * * A virtual event is usually never part of the event stream, but instead is - * synthesized inline by matching low-level events. However, a virtual - * event may be generated by platform-specific code or by Tcl scripts. In - * that case, no lookup of the virtual event will need to be done using - * this table, because the virtual event is actually in the event stream. + * synthesized inline by matching low-level events. However, a virtual event + * may be generated by platform-specific code or by Tcl scripts. In that case, + * no lookup of the virtual event will need to be done using this table, + * because the virtual event is actually in the event stream. */ typedef struct VirtualEventTable { - Tcl_HashTable patternTable; /* Used to map from a physical event to - * a list of patterns that may match that - * event. Keys are PatternTableKey - * structs, values are (PatSeq *). */ - Tcl_HashTable nameTable; /* Used to map a virtual event name to - * the array of physical events that can - * trigger it. Keys are the Tk_Uid names - * of the virtual events, values are - * PhysicalsOwned structs. */ + Tcl_HashTable patternTable; /* Used to map from a physical event to a list + * of patterns that may match that event. Keys + * are PatternTableKey structs, values are + * (PatSeq *). */ + Tcl_HashTable nameTable; /* Used to map a virtual event name to the + * array of physical events that can trigger + * it. Keys are the Tk_Uid names of the + * virtual events, values are PhysicalsOwned + * structs. */ } VirtualEventTable; /* - * The following structure is used as a key in a patternTable for both - * binding tables and a virtual event tables. + * The following structure is used as a key in a patternTable for both binding + * tables and a virtual event tables. * - * In a binding table, the object field corresponds to the binding tag - * for the widget whose bindings are being accessed. + * In a binding table, the object field corresponds to the binding tag for the + * widget whose bindings are being accessed. * - * In a virtual event table, the object field is always NULL. Virtual - * events are a global definiton and are not tied to a particular - * binding tag. + * In a virtual event table, the object field is always NULL. Virtual events + * are a global definiton and are not tied to a particular binding tag. * - * The same key is used for both types of pattern tables so that the - * helper functions that traverse and match patterns will work for both - * binding tables and virtual event tables. + * The same key is used for both types of pattern tables so that the helper + * functions that traverse and match patterns will work for both binding + * tables and virtual event tables. */ + typedef struct PatternTableKey { ClientData object; /* For binding table, identifies the binding * tag of the object (or class of objects) - * relative to which the event occurred. - * For virtual event table, always NULL. */ + * relative to which the event occurred. For + * virtual event table, always NULL. */ int type; /* Type of event (from X). */ Detail detail; /* Additional information, such as keysym, * button, Tk_Uid, or 0 if nothing @@ -164,37 +161,34 @@ typedef struct PatternTableKey { typedef struct Pattern { int eventType; /* Type of X event, e.g. ButtonPress. */ - int needMods; /* Mask of modifiers that must be - * present (0 means no modifiers are - * required). */ - Detail detail; /* Additional information that must - * match event. Normally this is 0, - * meaning no additional information - * must match. For KeyPress and - * KeyRelease events, a keySym may - * be specified to select a - * particular keystroke (0 means any - * keystrokes). For button events, - * specifies a particular button (0 - * means any buttons are OK). For virtual - * events, specifies the Tk_Uid of the + int needMods; /* Mask of modifiers that must be present (0 + * means no modifiers are required). */ + Detail detail; /* Additional information that must match + * event. Normally this is 0, meaning no + * additional information must match. For + * KeyPress and KeyRelease events, a keySym + * may be specified to select a particular + * keystroke (0 means any keystrokes). For + * button events, specifies a particular + * button (0 means any buttons are OK). For + * virtual events, specifies the Tk_Uid of the * virtual event name (never 0). */ } Pattern; /* * The following structure defines a pattern sequence, which consists of one - * or more patterns. In order to trigger, a pattern sequence must match - * the most recent X events (first pattern to most recent event, next - * pattern to next event, and so on). It is used as the hash value in a - * patternTable for both binding tables and virtual event tables. - * - * In a binding table, it is the sequence of physical events that make up - * a binding for an object. - * - * In a virtual event table, it is the sequence of physical events that - * define a virtual event. - * - * The same structure is used for both types of pattern tables so that the + * or more patterns. In order to trigger, a pattern sequence must match the + * most recent X events (first pattern to most recent event, next pattern to + * next event, and so on). It is used as the hash value in a patternTable for + * both binding tables and virtual event tables. + * + * In a binding table, it is the sequence of physical events that make up a + * binding for an object. + * + * In a virtual event table, it is the sequence of physical events that define + * a virtual event. + * + * The same structure is used for both types of pattern tables so that the * helper functions that traverse and match patterns will work for both * binding tables and virtual event tables. */ @@ -202,57 +196,57 @@ typedef struct Pattern { typedef struct PatSeq { int numPats; /* Number of patterns in sequence (usually * 1). */ - TkBindEvalProc *eventProc; /* The procedure that will be invoked on - * the clientData when this pattern sequence + TkBindEvalProc *eventProc; /* The function that will be invoked on the + * clientData when this pattern sequence * matches. */ - TkBindFreeProc *freeProc; /* The procedure that will be invoked to + TkBindFreeProc *freeProc; /* The function that will be invoked to * release the clientData when this pattern * sequence is freed. */ ClientData clientData; /* Arbitray data passed to eventProc and * freeProc when sequence matches. */ int flags; /* Miscellaneous flag values; see below for * definitions. */ - int refCount; /* Number of times that this binding is in - * the midst of executing. If greater than 1, - * then a recursive invocation is happening. - * Only when this is zero can the binding - * actually be freed. */ - struct PatSeq *nextSeqPtr; /* Next in list of all pattern sequences - * that have the same initial pattern. NULL - * means end of list. */ - Tcl_HashEntry *hPtr; /* Pointer to hash table entry for the - * initial pattern. This is the head of the - * list of which nextSeqPtr forms a part. */ - struct VirtualOwners *voPtr;/* In a binding table, always NULL. In a + int refCount; /* Number of times that this binding is in the + * midst of executing. If greater than 1, then + * a recursive invocation is happening. Only + * when this is zero can the binding actually + * be freed. */ + struct PatSeq *nextSeqPtr; /* Next in list of all pattern sequences that + * have the same initial pattern. NULL means + * end of list. */ + Tcl_HashEntry *hPtr; /* Pointer to hash table entry for the initial + * pattern. This is the head of the list of + * which nextSeqPtr forms a part. */ + struct VirtualOwners *voPtr;/* In a binding table, always NULL. In a * virtual event table, identifies the array * of virtual events that can be triggered by * this event. */ - struct PatSeq *nextObjPtr; /* In a binding table, next in list of all + struct PatSeq *nextObjPtr; /* In a binding table, next in list of all * pattern sequences for the same object (NULL - * for end of list). Needed to implement - * Tk_DeleteAllBindings. In a virtual event + * for end of list). Needed to implement + * Tk_DeleteAllBindings. In a virtual event * table, always NULL. */ - Pattern pats[1]; /* Array of "numPats" patterns. Only one + Pattern pats[1]; /* Array of "numPats" patterns. Only one * element is declared here but in actuality - * enough space will be allocated for "numPats" - * patterns. To match, pats[0] must match - * event n, pats[1] must match event n-1, etc. + * enough space will be allocated for + * "numPats" patterns. To match, pats[0] must + * match event n, pats[1] must match event + * n-1, etc. */ } PatSeq; /* * Flag values for PatSeq structures: * - * PAT_NEARBY 1 means that all of the events matching - * this sequence must occur with nearby X - * and Y mouse coordinates and close in time. - * This is typically used to restrict multiple - * button presses. + * PAT_NEARBY 1 means that all of the events matching this sequence + * must occur with nearby X and Y mouse coordinates and + * close in time. This is typically used to restrict + * multiple button presses. * MARKED_DELETED 1 means that this binding has been marked as deleted * and removed from the binding table, but its memory - * could not be released because it was already queued for - * execution. When the binding is actually about to be - * executed, this flag will be checked and the binding + * could not be released because it was already queued + * for execution. When the binding is actually about to + * be executed, this flag will be checked and the binding * skipped if set. */ @@ -260,52 +254,49 @@ typedef struct PatSeq { #define MARKED_DELETED 0x2 /* - * Constants that define how close together two events must be - * in milliseconds or pixels to meet the PAT_NEARBY constraint: + * Constants that define how close together two events must be in milliseconds + * or pixels to meet the PAT_NEARBY constraint: */ #define NEARBY_PIXELS 5 #define NEARBY_MS 500 - /* * The following structure keeps track of all the virtual events that are - * associated with a particular physical event. It is pointed to by the - * voPtr field in a PatSeq in the patternTable of a virtual event table. + * associated with a particular physical event. It is pointed to by the voPtr + * field in a PatSeq in the patternTable of a virtual event table. */ typedef struct VirtualOwners { - int numOwners; /* Number of virtual events to trigger. */ - Tcl_HashEntry *owners[1]; /* Array of pointers to entries in - * nameTable. Enough space will - * actually be allocated for numOwners - * hash entries. */ + int numOwners; /* Number of virtual events to trigger. */ + Tcl_HashEntry *owners[1]; /* Array of pointers to entries in nameTable. + * Enough space will actually be allocated for + * numOwners hash entries. */ } VirtualOwners; /* - * The following structure is used in the nameTable of a virtual event - * table to associate a virtual event with all the physical events that can - * trigger it. + * The following structure is used in the nameTable of a virtual event table + * to associate a virtual event with all the physical events that can trigger + * it. */ typedef struct PhysicalsOwned { - int numOwned; /* Number of physical events owned. */ - PatSeq *patSeqs[1]; /* Array of pointers to physical event - * patterns. Enough space will actually - * be allocated to hold numOwned. */ + int numOwned; /* Number of physical events owned. */ + PatSeq *patSeqs[1]; /* Array of pointers to physical event + * patterns. Enough space will actually be + * allocated to hold numOwned. */ } PhysicalsOwned; /* - * One of the following structures exists for each interpreter. This - * structure keeps track of the current display and screen in the - * interpreter, so that a script can be invoked whenever the display/screen - * changes (the script does things like point tk::Priv at a display-specific - * structure). + * One of the following structures exists for each interpreter. This structure + * keeps track of the current display and screen in the interpreter, so that a + * script can be invoked whenever the display/screen changes (the script does + * things like point tk::Priv at a display-specific structure). */ typedef struct { - TkDisplay *curDispPtr; /* Display for last binding command invoked - * in this application. */ - int curScreenIndex; /* Index of screen for last binding command. */ + TkDisplay *curDispPtr; /* Display for last binding command invoked in + * this application. */ + int curScreenIndex; /* Index of screen for last binding command */ int bindingDepth; /* Number of active instances of Tk_BindEvent * in this application. */ } ScreenInfo; @@ -313,21 +304,21 @@ typedef struct { /* * The following structure is used to keep track of all the C bindings that * are awaiting invocation and whether the window they refer to has been - * destroyed. If the window is destroyed, then all pending callbacks for - * that window will be cancelled. The Tcl bindings will still all be - * invoked, however. + * destroyed. If the window is destroyed, then all pending callbacks for that + * window will be cancelled. The Tcl bindings will still all be invoked, + * however. */ typedef struct PendingBinding { struct PendingBinding *nextPtr; - /* Next in chain of pending bindings, in - * case a recursive binding evaluation is in + /* Next in chain of pending bindings, in case + * a recursive binding evaluation is in * progress. */ Tk_Window tkwin; /* The window that the following bindings * depend upon. */ - int deleted; /* Set to non-zero by window cleanup code - * if tkwin is deleted. */ - PatSeq *matchArray[5]; /* Array of pending C bindings. The actual + int deleted; /* Set to non-zero by window cleanup code if + * tkwin is deleted. */ + PatSeq *matchArray[5]; /* Array of pending C bindings. The actual * size of this depends on how many C bindings * matched the event passed to Tk_BindEvent. * THIS FIELD MUST BE THE LAST IN THE @@ -335,8 +326,8 @@ typedef struct PendingBinding { } PendingBinding; /* - * The following structure keeps track of all the information local to - * the binding package on a per interpreter basis. + * The following structure keeps track of all the information local to the + * binding package on a per interpreter basis. */ typedef struct BindInfo { @@ -344,30 +335,29 @@ typedef struct BindInfo { /* The virtual events that exist in this * interpreter. */ ScreenInfo screenInfo; /* Keeps track of the current display and - * screen, so it can be restored after - * a binding has executed. */ + * screen, so it can be restored after a + * binding has executed. */ PendingBinding *pendingList;/* The list of pending C bindings, kept in * case a C or Tcl binding causes the target * window to be deleted. */ - int deleted; /* 1 the application has been deleted but - * the structure has been preserved. */ + int deleted; /* 1 the application has been deleted but the + * structure has been preserved. */ } BindInfo; - + /* - * In X11R4 and earlier versions, XStringToKeysym is ridiculously - * slow. The data structure and hash table below, along with the - * code that uses them, implement a fast mapping from strings to - * keysyms. In X11R5 and later releases XStringToKeysym is plenty - * fast so this stuff isn't needed. The #define REDO_KEYSYM_LOOKUP - * is normally undefined, so that XStringToKeysym gets used. It - * can be set in the Makefile to enable the use of the hash table - * below. + * In X11R4 and earlier versions, XStringToKeysym is ridiculously slow. The + * data structure and hash table below, along with the code that uses them, + * implement a fast mapping from strings to keysyms. In X11R5 and later + * releases XStringToKeysym is plenty fast so this stuff isn't needed. The + * #define REDO_KEYSYM_LOOKUP is normally undefined, so that XStringToKeysym + * gets used. It can be set in the Makefile to enable the use of the hash + * table below. */ #ifdef REDO_KEYSYM_LOOKUP typedef struct { - char *name; /* Name of keysym. */ - KeySym value; /* Numeric identifier for keysym. */ + char *name; /* Name of keysym. */ + KeySym value; /* Numeric identifier for keysym. */ } KeySymInfo; static KeySymInfo keyArray[] = { #ifndef lint @@ -375,8 +365,8 @@ static KeySymInfo keyArray[] = { #endif {(char *) NULL, 0} }; -static Tcl_HashTable keySymTable; /* keyArray hashed by keysym value. */ -static Tcl_HashTable nameTable; /* keyArray hashed by keysym name. */ +static Tcl_HashTable keySymTable; /* keyArray hashed by keysym value. */ +static Tcl_HashTable nameTable; /* keyArray hashed by keysym name. */ #endif /* REDO_KEYSYM_LOOKUP */ /* @@ -388,16 +378,17 @@ static int initialized = 0; TCL_DECLARE_MUTEX(bindMutex) /* - * A hash table is kept to map from the string names of event - * modifiers to information about those modifiers. The structure - * for storing this information, and the hash table built at - * initialization time, are defined below. + * A hash table is kept to map from the string names of event modifiers to + * information about those modifiers. The structure for storing this + * information, and the hash table built at initialization time, are defined + * below. */ typedef struct { char *name; /* Name of modifier. */ - int mask; /* Button/modifier mask value, * such as Button1Mask. */ - int flags; /* Various flags; see below for + int mask; /* Button/modifier mask value, such as + * Button1Mask. */ + int flags; /* Various flags; see below for * definitions. */ } ModInfo; @@ -451,32 +442,29 @@ static ModInfo modArray[] = { {"Double", 0, DOUBLE}, {"Triple", 0, TRIPLE}, {"Quadruple", 0, QUADRUPLE}, - {"Any", 0, 0}, /* Ignored: historical relic. */ + {"Any", 0, 0}, /* Ignored: historical relic */ {NULL, 0, 0} }; static Tcl_HashTable modTable; /* - * This module also keeps a hash table mapping from event names - * to information about those events. The structure, an array - * to use to initialize the hash table, and the hash table are - * all defined below. + * This module also keeps a hash table mapping from event names to information + * about those events. The structure, an array to use to initialize the hash + * table, and the hash table are all defined below. */ typedef struct { char *name; /* Name of event. */ - int type; /* Event type for X, such as - * ButtonPress. */ - int eventMask; /* Mask bits (for XSelectInput) - * for this event type. */ + int type; /* Event type for X, such as ButtonPress. */ + int eventMask; /* Mask bits (for XSelectInput) for this event + * type. */ } EventInfo; /* - * Note: some of the masks below are an OR-ed combination of - * several masks. This is necessary because X doesn't report - * up events unless you also ask for down events. Also, X - * doesn't report button state in motion events unless you've - * asked about button events. + * Note: some of the masks below are an OR-ed combination of several masks. + * This is necessary because X doesn't report up events unless you also ask + * for down events. Also, X doesn't report button state in motion events + * unless you've asked about button events. */ static EventInfo eventArray[] = { @@ -510,18 +498,18 @@ static EventInfo eventArray[] = { {"CirculateRequest", CirculateRequest, SubstructureRedirectMask}, {"ConfigureRequest", ConfigureRequest, SubstructureRedirectMask}, {"Create", CreateNotify, SubstructureNotifyMask}, - {"MapRequest", MapRequest, SubstructureRedirectMask}, + {"MapRequest", MapRequest, SubstructureRedirectMask}, {"ResizeRequest", ResizeRequest, ResizeRedirectMask}, {(char *) NULL, 0, 0} }; static Tcl_HashTable eventTable; /* - * The defines and table below are used to classify events into - * various groups. The reason for this is that logically identical - * fields (e.g. "state") appear at different places in different - * types of events. The classification masks can be used to figure - * out quickly where to extract information from events. + * The defines and table below are used to classify events into various + * groups. The reason for this is that logically identical fields (e.g. + * "state") appear at different places in different types of events. The + * classification masks can be used to figure out quickly where to extract + * information from events. */ #define KEY 0x1 @@ -588,17 +576,16 @@ static int flagArray[TK_LASTEVENT] = { /* ClientMessage */ 0, /* MappingNotify */ 0, /* VirtualEvent */ VIRTUAL, - /* Activate */ ACTIVATE, + /* Activate */ ACTIVATE, /* Deactivate */ ACTIVATE, /* MouseWheel */ KEY }; /* - * The following table is used to map between the location where an - * generated event should be queued and the string used to specify the - * location. + * The following table is used to map between the location where an generated + * event should be queued and the string used to specify the location. */ - + static TkStateMap queuePosition[] = { {-1, "now"}, {TCL_QUEUE_HEAD, "head"}, @@ -608,10 +595,10 @@ static TkStateMap queuePosition[] = { }; /* - * The following tables are used as a two-way map between X's internal - * numeric values for fields in an XEvent and the strings used in Tcl. The - * tables are used both when constructing an XEvent from user input and - * when providing data from an XEvent to the user. + * The following tables are used as a two-way map between X's internal numeric + * values for fields in an XEvent and the strings used in Tcl. The tables are + * used both when constructing an XEvent from user input and when providing + * data from an XEvent to the user. */ static TkStateMap notifyMode[] = { @@ -641,9 +628,9 @@ static TkStateMap circPlace[] = { }; static TkStateMap visNotify[] = { - {VisibilityUnobscured, "VisibilityUnobscured"}, - {VisibilityPartiallyObscured, "VisibilityPartiallyObscured"}, - {VisibilityFullyObscured, "VisibilityFullyObscured"}, + {VisibilityUnobscured, "VisibilityUnobscured"}, + {VisibilityPartiallyObscured, "VisibilityPartiallyObscured"}, + {VisibilityFullyObscured, "VisibilityFullyObscured"}, {-1, NULL} }; @@ -664,58 +651,52 @@ static TkStateMap propNotify[] = { }; /* - * Prototypes for local procedures defined in this file: + * Prototypes for local functions defined in this file: */ -static void ChangeScreen _ANSI_ARGS_((Tcl_Interp *interp, - char *dispName, int screenIndex)); -static int CreateVirtualEvent _ANSI_ARGS_((Tcl_Interp *interp, +static void ChangeScreen(Tcl_Interp *interp, char *dispName, + int screenIndex); +static int CreateVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr, char *virtString, - char *eventString)); -static int DeleteVirtualEvent _ANSI_ARGS_((Tcl_Interp *interp, + char *eventString); +static int DeleteVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr, char *virtString, - char *eventString)); -static void DeleteVirtualEventTable _ANSI_ARGS_(( - VirtualEventTable *vetPtr)); -static void ExpandPercents _ANSI_ARGS_((TkWindow *winPtr, - CONST char *before, XEvent *eventPtr, KeySym keySym, - Tcl_DString *dsPtr)); -static void FreeTclBinding _ANSI_ARGS_((ClientData clientData)); -static PatSeq * FindSequence _ANSI_ARGS_((Tcl_Interp *interp, + char *eventString); +static void DeleteVirtualEventTable(VirtualEventTable *vetPtr); +static void ExpandPercents(TkWindow *winPtr, CONST char *before, + XEvent *eventPtr,KeySym keySym,Tcl_DString *dsPtr); +static void FreeTclBinding(ClientData clientData); +static PatSeq * FindSequence(Tcl_Interp *interp, Tcl_HashTable *patternTablePtr, ClientData object, CONST char *eventString, int create, - int allowVirtual, unsigned long *maskPtr)); -static void GetAllVirtualEvents _ANSI_ARGS_((Tcl_Interp *interp, - VirtualEventTable *vetPtr)); -static char * GetField _ANSI_ARGS_((char *p, char *copy, int size)); -static void GetPatternString _ANSI_ARGS_((PatSeq *psPtr, - Tcl_DString *dsPtr)); -static int GetVirtualEvent _ANSI_ARGS_((Tcl_Interp *interp, - VirtualEventTable *vetPtr, char *virtString)); -static Tk_Uid GetVirtualEventUid _ANSI_ARGS_((Tcl_Interp *interp, - char *virtString)); -static int HandleEventGenerate _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window main, int objc, - Tcl_Obj *CONST objv[])); -static void InitVirtualEventTable _ANSI_ARGS_(( - VirtualEventTable *vetPtr)); -static PatSeq * MatchPatterns _ANSI_ARGS_((TkDisplay *dispPtr, + int allowVirtual, unsigned long *maskPtr); +static void GetAllVirtualEvents(Tcl_Interp *interp, + VirtualEventTable *vetPtr); +static char * GetField(char *p, char *copy, int size); +static void GetPatternString(PatSeq *psPtr, Tcl_DString *dsPtr); +static int GetVirtualEvent(Tcl_Interp *interp, + VirtualEventTable *vetPtr, char *virtString); +static Tk_Uid GetVirtualEventUid(Tcl_Interp *interp, + char *virtString); +static int HandleEventGenerate(Tcl_Interp *interp, Tk_Window main, + int objc, Tcl_Obj *CONST objv[]); +static void InitVirtualEventTable(VirtualEventTable *vetPtr); +static PatSeq * MatchPatterns(TkDisplay *dispPtr, BindingTable *bindPtr, PatSeq *psPtr, PatSeq *bestPtr, ClientData *objectPtr, - PatSeq **sourcePtrPtr)); -static int NameToWindow _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window main, Tcl_Obj *objPtr, - Tk_Window *tkwinPtr)); -static int ParseEventDescription _ANSI_ARGS_((Tcl_Interp *interp, + PatSeq **sourcePtrPtr); +static int NameToWindow(Tcl_Interp *interp, Tk_Window main, + Tcl_Obj *objPtr, Tk_Window *tkwinPtr); +static int ParseEventDescription(Tcl_Interp *interp, CONST char **eventStringPtr, Pattern *patPtr, - unsigned long *eventMaskPtr)); -static void DoWarp _ANSI_ARGS_((ClientData clientData)); + unsigned long *eventMaskPtr); +static void DoWarp(ClientData clientData); /* - * The following define is used as a short circuit for the callback - * procedure to evaluate a TclBinding. The actual evaluation of the - * binding is handled inline, because special things have to be done - * with a Tcl binding before evaluation time. + * The following define is used as a short circuit for the callback function + * to evaluate a TclBinding. The actual evaluation of the binding is handled + * inline, because special things have to be done with a Tcl binding before + * evaluation time. */ #define EvalTclBinding ((TkBindEvalProc *) 1) @@ -726,10 +707,9 @@ static void DoWarp _ANSI_ARGS_((ClientData clientData)); * * TkBindInit -- * - * This procedure is called when an application is created. It - * initializes all the structures used by bindings and virtual - * events. It must be called before any other functions in this - * file are called. + * This function is called when an application is created. It initializes + * all the structures used by bindings and virtual events. It must be + * called before any other functions in this file are called. * * Results: * None. @@ -751,13 +731,12 @@ TkBindInit(mainPtr) } /* - * Initialize the static data structures used by the binding package. - * They are only initialized once, no matter how many interps are - * created. + * Initialize the static data structures used by the binding package. They + * are only initialized once, no matter how many interps are created. */ if (!initialized) { - Tcl_MutexLock(&bindMutex); + Tcl_MutexLock(&bindMutex); if (!initialized) { Tcl_HashEntry *hPtr; ModInfo *modPtr; @@ -770,28 +749,28 @@ TkBindInit(mainPtr) Tcl_InitHashTable(&keySymTable, TCL_STRING_KEYS); Tcl_InitHashTable(&nameTable, TCL_ONE_WORD_KEYS); for (kPtr = keyArray; kPtr->name != NULL; kPtr++) { - hPtr = Tcl_CreateHashEntry(&keySymTable, kPtr->name, &dummy); + hPtr = Tcl_CreateHashEntry(&keySymTable, kPtr->name, &dummy); Tcl_SetHashValue(hPtr, kPtr->value); hPtr = Tcl_CreateHashEntry(&nameTable, (char *) kPtr->value, - &dummy); + &dummy); Tcl_SetHashValue(hPtr, kPtr->name); } #endif /* REDO_KEYSYM_LOOKUP */ Tcl_InitHashTable(&modTable, TCL_STRING_KEYS); for (modPtr = modArray; modPtr->name != NULL; modPtr++) { - hPtr = Tcl_CreateHashEntry(&modTable, modPtr->name, &dummy); + hPtr = Tcl_CreateHashEntry(&modTable, modPtr->name, &dummy); Tcl_SetHashValue(hPtr, modPtr); } - + Tcl_InitHashTable(&eventTable, TCL_STRING_KEYS); for (eiPtr = eventArray; eiPtr->name != NULL; eiPtr++) { - hPtr = Tcl_CreateHashEntry(&eventTable, eiPtr->name, &dummy); + hPtr = Tcl_CreateHashEntry(&eventTable, eiPtr->name, &dummy); Tcl_SetHashValue(hPtr, eiPtr); } initialized = 1; } - Tcl_MutexUnlock(&bindMutex); + Tcl_MutexUnlock(&bindMutex); } mainPtr->bindingTable = Tk_CreateBindingTable(mainPtr->interp); @@ -813,8 +792,8 @@ TkBindInit(mainPtr) * * TkBindFree -- * - * This procedure is called when an application is deleted. It - * deletes all the structures used by bindings and virtual events. + * This function is called when an application is deleted. It deletes all + * the structures used by bindings and virtual events. * * Results: * None. @@ -830,7 +809,7 @@ TkBindFree(mainPtr) TkMainInfo *mainPtr; /* The newly created application. */ { BindInfo *bindInfoPtr; - + Tk_DeleteBindingTable(mainPtr->bindingTable); mainPtr->bindingTable = NULL; @@ -849,8 +828,8 @@ TkBindFree(mainPtr) * Set up a new domain in which event bindings may be created. * * Results: - * The return value is a token for the new table, which must - * be passed to procedures like Tk_CreateBinding. + * The return value is a token for the new table, which must be passed to + * functions like Tk_CreateBinding. * * Side effects: * Memory is allocated for the new table. @@ -861,7 +840,7 @@ TkBindFree(mainPtr) Tk_BindingTable Tk_CreateBindingTable(interp) Tcl_Interp *interp; /* Interpreter to associate with the binding - * table: commands are executed in this + * table: commands are executed in this * interpreter. */ { BindingTable *bindPtr; @@ -888,9 +867,8 @@ Tk_CreateBindingTable(interp) * * Tk_DeleteBindingTable -- * - * Destroy a binding table and free up all its memory. - * The caller should not use bindingTable again after - * this procedure returns. + * Destroy a binding table and free up all its memory. The caller should + * not use bindingTable again after this function returns. * * Results: * None. @@ -903,8 +881,8 @@ Tk_CreateBindingTable(interp) void Tk_DeleteBindingTable(bindingTable) - Tk_BindingTable bindingTable; /* Token for the binding table to - * destroy. */ + Tk_BindingTable bindingTable; + /* Token for the binding table to destroy. */ { BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr, *nextPtr; @@ -912,8 +890,7 @@ Tk_DeleteBindingTable(bindingTable) Tcl_HashSearch search; /* - * Find and delete all of the patterns associated with the binding - * table. + * Find and delete all of the patterns associated with the binding table. */ for (hPtr = Tcl_FirstHashEntry(&bindPtr->patternTable, &search); @@ -932,8 +909,7 @@ Tk_DeleteBindingTable(bindingTable) } /* - * Clean up the rest of the information associated with the - * binding table. + * Clean up the rest of the information associated with the binding table. */ Tcl_DeleteHashTable(&bindPtr->patternTable); @@ -946,23 +922,21 @@ Tk_DeleteBindingTable(bindingTable) * * Tk_CreateBinding -- * - * Add a binding to a binding table, so that future calls to - * Tk_BindEvent may execute the command in the binding. + * Add a binding to a binding table, so that future calls to Tk_BindEvent + * may execute the command in the binding. * * Results: - * The return value is 0 if an error occurred while setting - * up the binding. In this case, an error message will be - * left in the interp's result. If all went well then the return - * value is a mask of the event types that must be made - * available to Tk_BindEvent in order to properly detect when - * this binding triggers. This value can be used to determine + * The return value is 0 if an error occurred while setting up the + * binding. In this case, an error message will be left in the interp's + * result. If all went well then the return value is a mask of the event + * types that must be made available to Tk_BindEvent in order to properly + * detect when this binding triggers. This value can be used to determine * what events to select for in a window, for example. * * Side effects: - * An existing binding on the same event sequence may be - * replaced. - * The new binding may cause future calls to Tk_BindEvent to - * behave differently than they did previously. + * An existing binding on the same event sequence may be replaced. The + * new binding may cause future calls to Tk_BindEvent to behave + * differently than they did previously. * *-------------------------------------------------------------- */ @@ -980,7 +954,7 @@ Tk_CreateBinding(interp, bindingTable, object, eventString, command, append) * binding triggers. */ int append; /* 0 means replace any existing binding for * eventString; 1 means append to that - * binding. If the existing binding is for a + * binding. If the existing binding is for a * callback function and not a Tcl command * string, the existing binding will always be * replaced. */ @@ -998,12 +972,11 @@ Tk_CreateBinding(interp, bindingTable, object, eventString, command, append) if (psPtr->eventProc == NULL) { int new; Tcl_HashEntry *hPtr; - + /* - * This pattern sequence was just created. - * Link the pattern into the list associated with the object, so - * that if the object goes away, these bindings will all - * automatically be deleted. + * This pattern sequence was just created. Link the pattern into the + * list associated with the object, so that if the object goes away, + * these bindings will all automatically be deleted. */ hPtr = Tcl_CreateHashEntry(&bindPtr->objectTable, (char *) object, @@ -1049,23 +1022,22 @@ Tk_CreateBinding(interp, bindingTable, object, eventString, command, append) /* *--------------------------------------------------------------------------- * - * TkCreateBindingProcedure -- + * TkCreateBindingFunction -- * * Add a C binding to a binding table, so that future calls to - * Tk_BindEvent may callback the procedure in the binding. + * Tk_BindEvent may callback the function in the binding. * * Results: - * The return value is 0 if an error occurred while setting - * up the binding. In this case, an error message will be - * left in the interp's result. If all went well then the return - * value is a mask of the event types that must be made - * available to Tk_BindEvent in order to properly detect when - * this binding triggers. This value can be used to determine + + * The return value is 0 if an error occurred while setting up the + * binding. In this case, an error message will be left in the interp's + * result. If all went well then the return value is a mask of the event + * types that must be made available to Tk_BindEvent in order to properly + * detect when this binding triggers. This value can be used to determine * what events to select for in a window, for example. * * Side effects: - * Any existing binding on the same event sequence will be - * replaced. + * Any existing binding on the same event sequence will be replaced. * *--------------------------------------------------------------------------- */ @@ -1080,10 +1052,10 @@ TkCreateBindingProcedure(interp, bindingTable, object, eventString, * associated. */ CONST char *eventString; /* String describing event sequence that * triggers binding. */ - TkBindEvalProc *eventProc; /* Procedure to invoke when binding - * triggers. Must not be NULL. */ - TkBindFreeProc *freeProc; /* Procedure to invoke when binding is - * freed. May be NULL for no procedure. */ + TkBindEvalProc *eventProc; /* Function to invoke when binding triggers. + * Must not be NULL. */ + TkBindFreeProc *freeProc; /* Function to invoke when binding is freed. + * May be NULL for no function. */ ClientData clientData; /* Arbitrary ClientData to pass to eventProc * and freeProc. */ { @@ -1099,12 +1071,11 @@ TkCreateBindingProcedure(interp, bindingTable, object, eventString, if (psPtr->eventProc == NULL) { int new; Tcl_HashEntry *hPtr; - + /* - * This pattern sequence was just created. - * Link the pattern into the list associated with the object, so - * that if the object goes away, these bindings will all - * automatically be deleted. + * This pattern sequence was just created. Link the pattern into the + * list associated with the object, so that if the object goes away, + * these bindings will all automatically be deleted. */ hPtr = Tcl_CreateHashEntry(&bindPtr->objectTable, (char *) object, @@ -1140,24 +1111,25 @@ TkCreateBindingProcedure(interp, bindingTable, object, eventString, * Remove an event binding from a binding table. * * Results: - * The result is a standard Tcl return value. If an error - * occurs then the interp's result will contain an error message. + * The result is a standard Tcl return value. If an error occurs then the + * interp's result will contain an error message. * * Side effects: - * The binding given by object and eventString is removed - * from bindingTable. + * The binding given by object and eventString is removed from + * bindingTable. * *-------------------------------------------------------------- */ int Tk_DeleteBinding(interp, bindingTable, object, eventString) - Tcl_Interp *interp; /* Used for error reporting. */ - Tk_BindingTable bindingTable; /* Table in which to delete binding. */ - ClientData object; /* Token for object with which binding - * is associated. */ - CONST char *eventString; /* String describing event sequence - * that triggers binding. */ + Tcl_Interp *interp; /* Used for error reporting. */ + Tk_BindingTable bindingTable; + /* Table in which to delete binding. */ + ClientData object; /* Token for object with which binding is + * associated. */ + CONST char *eventString; /* String describing event sequence that + * triggers binding. */ { BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr, *prevPtr; @@ -1172,8 +1144,8 @@ Tk_DeleteBinding(interp, bindingTable, object, eventString) } /* - * Unlink the binding from the list for its object, then from the - * list for its pattern. + * Unlink the binding from the list for its object, then from the list for + * its pattern. */ hPtr = Tcl_FindHashEntry(&bindPtr->objectTable, (char *) object); @@ -1231,13 +1203,12 @@ Tk_DeleteBinding(interp, bindingTable, object, eventString) * Return the command associated with a given event string. * * Results: - * The return value is a pointer to the command string - * associated with eventString for object in the domain - * given by bindingTable. If there is no binding for - * eventString, or if eventString is improperly formed, - * then NULL is returned and an error message is left in - * the interp's result. The return value is semi-static: it - * will persist until the binding is changed or deleted. + * The return value is a pointer to the command string associated with + * eventString for object in the domain given by bindingTable. If there + * is no binding for eventString, or if eventString is improperly formed, + * then NULL is returned and an error message is left in the interp's + * result. The return value is semi-static: it will persist until the + * binding is changed or deleted. * * Side effects: * None. @@ -1247,13 +1218,13 @@ Tk_DeleteBinding(interp, bindingTable, object, eventString) CONST char * Tk_GetBinding(interp, bindingTable, object, eventString) - Tcl_Interp *interp; /* Interpreter for error reporting. */ - Tk_BindingTable bindingTable; /* Table in which to look for - * binding. */ - ClientData object; /* Token for object with which binding - * is associated. */ - CONST char *eventString; /* String describing event sequence - * that triggers binding. */ + Tcl_Interp *interp; /* Interpreter for error reporting. */ + Tk_BindingTable bindingTable; + /* Table in which to look for binding. */ + ClientData object; /* Token for object with which binding is + * associated. */ + CONST char *eventString; /* String describing event sequence that + * triggers binding. */ { BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr; @@ -1275,14 +1246,14 @@ Tk_GetBinding(interp, bindingTable, object, eventString) * * Tk_GetAllBindings -- * - * Return a list of event strings for all the bindings - * associated with a given object. + * Return a list of event strings for all the bindings associated with a + * given object. * * Results: - * There is no return value. The interp's result is modified to - * hold a Tcl list with one entry for each binding associated - * with object in bindingTable. Each entry in the list - * contains the event string associated with one binding. + * There is no return value. The interp's result is modified to hold a + * Tcl list with one entry for each binding associated with object in + * bindingTable. Each entry in the list contains the event string + * associated with one binding. * * Side effects: * None. @@ -1292,12 +1263,10 @@ Tk_GetBinding(interp, bindingTable, object, eventString) void Tk_GetAllBindings(interp, bindingTable, object) - Tcl_Interp *interp; /* Interpreter returning result or - * error. */ - Tk_BindingTable bindingTable; /* Table in which to look for - * bindings. */ - ClientData object; /* Token for object. */ - + Tcl_Interp *interp; /* Interpreter returning result or error. */ + Tk_BindingTable bindingTable; + /* Table in which to look for bindings. */ + ClientData object; /* Token for object. */ { BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr; @@ -1311,11 +1280,11 @@ Tk_GetAllBindings(interp, bindingTable, object) Tcl_DStringInit(&ds); for (psPtr = (PatSeq *) Tcl_GetHashValue(hPtr); psPtr != NULL; psPtr = psPtr->nextObjPtr) { - /* - * For each binding, output information about each of the - * patterns in its sequence. + /* + * For each binding, output information about each of the patterns in + * its sequence. */ - + Tcl_DStringSetLength(&ds, 0); GetPatternString(psPtr, &ds); Tcl_AppendElement(interp, Tcl_DStringValue(&ds)); @@ -1328,12 +1297,11 @@ Tk_GetAllBindings(interp, bindingTable, object) * * Tk_DeleteAllBindings -- * - * Remove all bindings associated with a given object in a - * given binding table. + * Remove all bindings associated with a given object in a given binding + * table. * * Results: - * All bindings associated with object are removed from - * bindingTable. + * All bindings associated with object are removed from bindingTable. * * Side effects: * None. @@ -1343,9 +1311,9 @@ Tk_GetAllBindings(interp, bindingTable, object) void Tk_DeleteAllBindings(bindingTable, object) - Tk_BindingTable bindingTable; /* Table in which to delete - * bindings. */ - ClientData object; /* Token for object. */ + Tk_BindingTable bindingTable; + /* Table in which to delete bindings. */ + ClientData object; /* Token for object. */ { BindingTable *bindPtr = (BindingTable *) bindingTable; PatSeq *psPtr, *prevPtr; @@ -1361,9 +1329,9 @@ Tk_DeleteAllBindings(bindingTable, object) nextPtr = psPtr->nextObjPtr; /* - * Be sure to remove each binding from its hash chain in the - * pattern table. If this is the last pattern in the chain, - * then delete the hash entry too. + * Be sure to remove each binding from its hash chain in the pattern + * table. If this is the last pattern in the chain, then delete the + * hash entry too. */ prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr); @@ -1401,11 +1369,10 @@ Tk_DeleteAllBindings(bindingTable, object) * * Tk_BindEvent -- * - * This procedure is invoked to process an X event. The - * event is added to those recorded for the binding table. - * Then each of the objects at *objectPtr is checked in - * order to see if it has a binding that matches the recent - * events. If so, the most specific binding is invoked for + * This function is invoked to process an X event. The event is added to + * those recorded for the binding table. Then each of the objects at + * *objectPtr is checked in order to see if it has a binding that matches + * the recent events. If so, the most specific binding is invoked for * each object. * * Results: @@ -1414,32 +1381,32 @@ Tk_DeleteAllBindings(bindingTable, object) * Side effects: * Depends on the command associated with the matching binding. * - * All Tcl bindings scripts for each object are accumulated before - * the first binding is evaluated. If the action of a Tcl binding - * is to change or delete a binding, or delete the window associated - * with the binding, all the original Tcl binding scripts will still - * fire. Contrast this with C binding procedures. If a pending C - * binding (one that hasn't fired yet, but is queued to be fired for - * this window) is deleted, it will not be called, and if it is - * changed, then the new binding procedure will be called. If the - * window itself is deleted, no further C binding procedures will be - * called for this window. When both Tcl binding scripts and C binding - * procedures are interleaved, the above rules still apply. + * All Tcl bindings scripts for each object are accumulated before the + * first binding is evaluated. If the action of a Tcl binding is to + * change or delete a binding, or delete the window associated with the + * binding, all the original Tcl binding scripts will still fire. + * Contrast this with C binding functions. If a pending C binding (one + * that hasn't fired yet, but is queued to be fired for this window) is + * deleted, it will not be called, and if it is changed, then the new + * binding function will be called. If the window itself is deleted, no + * further C binding functions will be called for this window. When both + * Tcl binding scripts and C binding functions are interleaved, the above + * rules still apply. * *--------------------------------------------------------------------------- */ void Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) - Tk_BindingTable bindingTable; /* Table in which to look for - * bindings. */ - XEvent *eventPtr; /* What actually happened. */ - Tk_Window tkwin; /* Window on display where event - * occurred (needed in order to - * locate display information). */ - int numObjects; /* Number of objects at *objectPtr. */ - ClientData *objectPtr; /* Array of one or more objects - * to check for a matching binding. */ + Tk_BindingTable bindingTable; + /* Table in which to look for bindings. */ + XEvent *eventPtr; /* What actually happened. */ + Tk_Window tkwin; /* Window on display where event occurred + * (needed in order to locate display + * information). */ + int numObjects; /* Number of objects at *objectPtr. */ + ClientData *objectPtr; /* Array of one or more objects to check for a + * matching binding. */ { BindingTable *bindPtr; TkDisplay *dispPtr; @@ -1459,10 +1426,10 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) TkWindow *winPtr = (TkWindow *)tkwin; PatternTableKey key; Tk_ClassModalProc *modalProc; + /* - * Ignore events on windows that don't have names: these are windows - * like wrapper windows that shouldn't be visible to the - * application. + * Ignore events on windows that don't have names: these are windows like + * wrapper windows that shouldn't be visible to the application. */ if (winPtr->pathName == NULL) { @@ -1470,13 +1437,12 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) } /* - * Ignore the event completely if it is an Enter, Leave, FocusIn, - * or FocusOut event with detail NotifyInferior. The reason for - * ignoring these events is that we don't want transitions between - * a window and its children to visible to bindings on the parent: - * this would cause problems for mega-widgets, since the internal - * structure of a mega-widget isn't supposed to be visible to - * people watching the parent. + * Ignore the event completely if it is an Enter, Leave, FocusIn, or + * FocusOut event with detail NotifyInferior. The reason for ignoring + * these events is that we don't want transitions between a window and its + * children to visible to bindings on the parent: this would cause + * problems for mega-widgets, since the internal structure of a + * mega-widget isn't supposed to be visible to people watching the parent. */ if ((eventPtr->type == EnterNotify) || (eventPtr->type == LeaveNotify)) { @@ -1495,20 +1461,19 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) bindInfoPtr = (BindInfo *) winPtr->mainPtr->bindInfo; /* - * Add the new event to the ring of saved events for the - * binding table. Two tricky points: + * Add the new event to the ring of saved events for the binding table. + * Two tricky points: * - * 1. Combine consecutive MotionNotify events. Do this by putting - * the new event *on top* of the previous event. + * 1. Combine consecutive MotionNotify events. Do this by putting the new + * event *on top* of the previous event. * 2. If a modifier key is held down, it auto-repeats to generate - * continuous KeyPress and KeyRelease events. These can flush - * the event ring so that valuable information is lost (such - * as repeated button clicks). To handle this, check for the - * special case of a modifier KeyPress arriving when the previous - * two events are a KeyRelease and KeyPress of the same key. - * If this happens, mark the most recent event (the KeyRelease) - * invalid and put the new event on top of the event before that - * (the KeyPress). + * continuous KeyPress and KeyRelease events. These can flush the event + * ring so that valuable information is lost (such as repeated button + * clicks). To handle this, check for the special case of a modifier + * KeyPress arriving when the previous two events are a KeyRelease and + * KeyPress of the same key. If this happens, mark the most recent + * event (the KeyRelease) invalid and put the new event on top of the + * event before that (the KeyPress). */ if ((eventPtr->type == MotionNotify) @@ -1518,6 +1483,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) */ } else if (eventPtr->type == KeyPress) { int i; + for (i = 0; ; i++) { if (i >= dispPtr->numModKeyCodes) { goto advanceRingPointer; @@ -1544,7 +1510,8 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) bindPtr->eventRing[bindPtr->curEvent].type = -1; bindPtr->curEvent = i; } else { - advanceRingPointer: + + advanceRingPointer: bindPtr->curEvent++; if (bindPtr->curEvent >= EVENT_BUFFER_SIZE) { bindPtr->curEvent = 0; @@ -1581,9 +1548,9 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) veptPtr = &bindInfoPtr->virtualEventTable.patternTable; - key.object = NULL; - key.type = ringPtr->type; - key.detail = detail; + key.object = NULL; + key.type = ringPtr->type; + key.detail = detail; hPtr = Tcl_FindHashEntry(veptPtr, (char *) &key); if (hPtr != NULL) { @@ -1594,19 +1561,19 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) key.detail.clientData = 0; hPtr = Tcl_FindHashEntry(veptPtr, (char *) &key); if (hPtr != NULL) { - vMatchNoDetailList = (PatSeq *) Tcl_GetHashValue(hPtr); + vMatchNoDetailList = (PatSeq *) Tcl_GetHashValue(hPtr); } } } /* - * Loop over all the binding tags, finding the binding script or - * callback for each one. Append all of the binding scripts, with - * %-sequences expanded, to "scripts", with null characters separating - * the scripts for each object. Append all the callbacks to the array - * of pending callbacks. + * Loop over all the binding tags, finding the binding script or callback + * for each one. Append all of the binding scripts, with %-sequences + * expanded, to "scripts", with null characters separating the scripts for + * each object. Append all the callbacks to the array of pending + * callbacks. */ - + pendingPtr = &staticPending; matchCount = 0; matchSpace = sizeof(staticPending.matchArray) / sizeof(PatSeq *); @@ -1621,10 +1588,10 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) /* * Match the new event against those recorded in the pattern table, - * saving the longest matching pattern. For events with details - * (button and key events), look for a binding for the specific - * key or button. First see if the event matches a physical event - * that the object is interested in, then look for a virtual event. + * saving the longest matching pattern. For events with details + * (button and key events), look for a binding for the specific key or + * button. First see if the event matches a physical event that the + * object is interested in, then look for a virtual event. */ key.object = *objectPtr; @@ -1632,7 +1599,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) key.detail = detail; hPtr = Tcl_FindHashEntry(&bindPtr->patternTable, (char *) &key); if (hPtr != NULL) { - matchPtr = MatchPatterns(dispPtr, bindPtr, + matchPtr = MatchPatterns(dispPtr, bindPtr, (PatSeq *) Tcl_GetHashValue(hPtr), matchPtr, NULL, &sourcePtr); } @@ -1644,7 +1611,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) /* * If no match was found, look for a binding for all keys or buttons - * (detail of 0). Again, first match on a virtual event. + * (detail of 0). Again, first match on a virtual event. */ if ((detail.clientData != 0) && (matchPtr == NULL)) { @@ -1657,12 +1624,12 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) } if (vMatchNoDetailList != NULL) { - matchPtr = MatchPatterns(dispPtr, bindPtr, vMatchNoDetailList, + matchPtr = MatchPatterns(dispPtr, bindPtr, vMatchNoDetailList, matchPtr, objectPtr, &sourcePtr); } } - + if (matchPtr != NULL) { if (sourcePtr->eventProc == NULL) { Tcl_Panic("Tk_BindEvent: missing command"); @@ -1674,7 +1641,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (matchCount >= matchSpace) { PendingBinding *new; unsigned int oldSize, newSize; - + oldSize = sizeof(staticPending) - sizeof(staticPending.matchArray) + matchSpace * sizeof(PatSeq*); @@ -1693,9 +1660,10 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) pendingPtr->matchArray[matchCount] = sourcePtr; matchCount++; } + /* - * A "" is added to the scripts string to separate the - * various scripts that should be invoked. + * A "" is added to the scripts string to separate the various + * scripts that should be invoked. */ Tcl_DStringAppend(&scripts, "", 1); @@ -1706,29 +1674,28 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) } /* - * Now go back through and evaluate the binding for each object, - * in order, dealing with "break" and "continue" exceptions - * appropriately. + * Now go back through and evaluate the binding for each object, in order, + * dealing with "break" and "continue" exceptions appropriately. * * There are two tricks here: - * 1. Bindings can be invoked from in the middle of Tcl commands, - * where the interp's result is significant (for example, a widget - * might be deleted because of an error in creating it, so the - * result contains an error message that is eventually going to - * be returned by the creating command). To preserve the result, - * we save it in a dynamic string. - * 2. The binding's action can potentially delete the binding, - * so bindPtr may not point to anything valid once the action - * completes. Thus we have to save bindPtr->interp in a - * local variable in order to restore the result. + * 1. Bindings can be invoked from in the middle of Tcl commands, where + * the interp's result is significant (for example, a widget might be + * deleted because of an error in creating it, so the result contains + * an error message that is eventually going to be returned by the + * creating command). To preserve the result, we save it in a dynamic + * string. + * 2. The binding's action can potentially delete the binding, so bindPtr + * may not point to anything valid once the action completes. Thus we + * have to save bindPtr->interp in a local variable in order to restore + * the result. */ interp = bindPtr->interp; Tcl_DStringInit(&savedResult); /* - * Save information about the current screen, then invoke a script - * if the screen has changed. + * Save information about the current screen, then invoke a script if the + * screen has changed. */ Tcl_DStringGetResult(interp, &savedResult); @@ -1745,9 +1712,8 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (matchCount > 0) { /* * Remember the list of pending C binding callbacks, so we can mark - * them as deleted and not call them if the act of evaluating a C - * or Tcl binding deletes a C binding callback or even the whole - * window. + * them as deleted and not call them if the act of evaluating a C or + * Tcl binding deletes a C binding callback or even the whole window. */ pendingPtr->nextPtr = bindInfoPtr->pendingList; @@ -1755,11 +1721,11 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) pendingPtr->deleted = 0; bindInfoPtr->pendingList = pendingPtr; } - + /* - * Save the current value of the TK_DEFER_MODAL flag so we can - * restore it at the end of the loop. Clear the flag so we can - * detect any recursive requests for a modal loop. + * Save the current value of the TK_DEFER_MODAL flag so we can restore it + * at the end of the loop. Clear the flag so we can detect any recursive + * requests for a modal loop. */ flags = winPtr->flags; @@ -1770,16 +1736,15 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) i = 0; /* - * Be carefule when dereferencing screenPtr or bindInfoPtr. If we - * evaluate something that destroys ".", bindInfoPtr would have been - * freed, but we can tell that by first checking to see if - * winPtr->mainPtr == NULL. + * Be carefule when dereferencing screenPtr or bindInfoPtr. If we evaluate + * something that destroys ".", bindInfoPtr would have been freed, but we + * can tell that by first checking to see if winPtr->mainPtr == NULL. */ Tcl_Preserve((ClientData) bindInfoPtr); while (p < end) { int code; - + if (!bindInfoPtr->deleted) { screenPtr->bindingDepth++; } @@ -1787,7 +1752,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (*p == '\0') { PatSeq *psPtr; - + psPtr = pendingPtr->matchArray[i]; i++; code = TCL_OK; @@ -1815,7 +1780,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (code != TCL_OK) { if (code == TCL_CONTINUE) { /* - * Do nothing: just go on to the next command. + * Do nothing: just go on to the next command. */ } else if (code == TCL_BREAK) { break; @@ -1829,13 +1794,13 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (matchCount > 0 && !pendingPtr->deleted) { /* - * Restore the original modal flag value and invoke the modal loop - * if needed. + * Restore the original modal flag value and invoke the modal loop if + * needed. */ deferModal = winPtr->flags & TK_DEFER_MODAL; - winPtr->flags = (winPtr->flags & (unsigned int) ~TK_DEFER_MODAL) - | (flags & TK_DEFER_MODAL); + winPtr->flags = (winPtr->flags & (unsigned int) ~TK_DEFER_MODAL) + | (flags & TK_DEFER_MODAL); if (deferModal) { modalProc = Tk_GetClassProc(winPtr->classProcsPtr, modalProc); if (modalProc != NULL) { @@ -1846,12 +1811,10 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (!bindInfoPtr->deleted && (screenPtr->bindingDepth != 0) && ((oldDispPtr != screenPtr->curDispPtr) - || (oldScreen != screenPtr->curScreenIndex))) { - + || (oldScreen != screenPtr->curScreenIndex))) { /* - * Some other binding script is currently executing, but its - * screen is no longer current. Change the current display - * back again. + * Some other binding script is currently executing, but its screen is + * no longer current. Change the current display back again. */ screenPtr->curDispPtr = oldDispPtr; @@ -1864,10 +1827,10 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) if (matchCount > 0) { if (!bindInfoPtr->deleted) { /* - * Delete the pending list from the list of pending scripts - * for this window. + * Delete the pending list from the list of pending scripts for + * this window. */ - + PendingBinding **curPtrPtr; for (curPtrPtr = &bindInfoPtr->pendingList; ; ) { @@ -1890,8 +1853,8 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) * * TkBindDeadWindow -- * - * This procedure is invoked when it is determined that a window is - * dead. It cleans up bind-related information about the window + * This function is invoked when it is determined that a window is dead. + * It cleans up bind-related information about the window * * Results: * None. @@ -1901,7 +1864,7 @@ Tk_BindEvent(bindingTable, eventPtr, tkwin, numObjects, objectPtr) * *--------------------------------------------------------------------------- */ - + void TkBindDeadWindow(winPtr) TkWindow *winPtr; /* The window that is being deleted. */ @@ -1910,11 +1873,13 @@ TkBindDeadWindow(winPtr) PendingBinding *curPtr; /* - * Certain special windows like those used for send and clipboard - * have no mainPtr. + * Certain special windows like those used for send and clipboard have no + * mainPtr. */ - if (winPtr->mainPtr == NULL) - return; + + if (winPtr->mainPtr == NULL) { + return; + } bindInfoPtr = (BindInfo *) winPtr->mainPtr->bindInfo; curPtr = bindInfoPtr->pendingList; @@ -1931,33 +1896,34 @@ TkBindDeadWindow(winPtr) * * MatchPatterns -- * - * Given a list of pattern sequences and a list of recent events, - * return the pattern sequence that best matches the event list, - * if there is one. + * Given a list of pattern sequences and a list of recent events, return + * the pattern sequence that best matches the event list, if there is + * one. * - * This procedure is used in two different ways. In the simplest - * use, "object" is NULL and psPtr is a list of pattern sequences, - * each of which corresponds to a binding. In this case, the - * procedure finds the pattern sequences that match the event list - * and returns the most specific of those, if there is more than one. + * This function is used in two different ways. In the simplest use, + * "object" is NULL and psPtr is a list of pattern sequences, each of + * which corresponds to a binding. In this case, the function finds the + * pattern sequences that match the event list and returns the most + * specific of those, if there is more than one. * - * In the second case, psPtr is a list of pattern sequences, each - * of which corresponds to a definition for a virtual binding. - * In order for one of these sequences to "match", it must match - * the events (as above) but in addition there must be a binding - * for its associated virtual event on the current object. The - * "object" argument indicates which object the binding must be for. + * In the second case, psPtr is a list of pattern sequences, each of + * which corresponds to a definition for a virtual binding. In order for + * one of these sequences to "match", it must match the events (as above) + * but in addition there must be a binding for its associated virtual + * event on the current object. The "object" argument indicates which + * object the binding must be for. * * Results: - * The return value is NULL if bestPtr is NULL and no pattern matches - * the recent events from bindPtr. Otherwise the return value is - * the most specific pattern sequence among bestPtr and all those - * at psPtr that match the event list and object. If a pattern - * sequence other than bestPtr is returned, then *bestCommandPtr - * is filled in with a pointer to the command from the best sequence. + + * The return value is NULL if bestPtr is NULL and no pattern matches the + * recent events from bindPtr. Otherwise the return value is the most + * specific pattern sequence among bestPtr and all those at psPtr that + * match the event list and object. If a pattern sequence other than + * bestPtr is returned, then *bestCommandPtr is filled in with a pointer + * to the command from the best sequence. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ @@ -1967,22 +1933,22 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) BindingTable *bindPtr; /* Information about binding table, such as * ring of recent events. */ PatSeq *psPtr; /* List of pattern sequences. */ - PatSeq *bestPtr; /* The best match seen so far, from a - * previous call to this procedure. NULL - * means no prior best match. */ - ClientData *objectPtr; /* If NULL, the sequences at psPtr - * correspond to "normal" bindings. If - * non-NULL, the sequences at psPtr correspond - * to virtual bindings; in order to match each - * sequence must correspond to a virtual - * binding for which a binding exists for - * object in bindPtr. */ + PatSeq *bestPtr; /* The best match seen so far, from a previous + * call to this function. NULL means no prior + * best match. */ + ClientData *objectPtr; /* If NULL, the sequences at psPtr correspond + * to "normal" bindings. If non-NULL, the + * sequences at psPtr correspond to virtual + * bindings; in order to match each sequence + * must correspond to a virtual binding for + * which a binding exists for object in + * bindPtr. */ PatSeq **sourcePtrPtr; /* Filled with the pattern sequence that * contains the eventProc and clientData - * associated with the best match. If this + * associated with the best match. If this * differs from the return value, it is the * virtual event that most closely matched the - * return value (a physical event). Not + * return value (a physical event). Not * modified unless a result other than bestPtr * is returned. */ { @@ -2003,8 +1969,8 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) int modMask; /* - * Iterate over all the patterns in a sequence to be - * sure that they all match. + * Iterate over all the patterns in a sequence to be sure that they + * all match. */ eventPtr = &bindPtr->eventRing[bindPtr->curEvent]; @@ -2019,21 +1985,21 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) } if (eventPtr->xany.type != patPtr->eventType) { /* - * Most of the event types are considered superfluous - * in that they are ignored if they occur in the middle - * of a pattern sequence and have mismatching types. The - * only ones that cannot be ignored are ButtonPress and - * ButtonRelease events (if the next event in the pattern - * is a KeyPress or KeyRelease) and KeyPress and KeyRelease - * events (if the next pattern event is a ButtonPress or - * ButtonRelease). Here are some tricky cases to consider: + * Most of the event types are considered superfluous in that + * they are ignored if they occur in the middle of a pattern + * sequence and have mismatching types. The only ones that + * cannot be ignored are ButtonPress and ButtonRelease events + * (if the next event in the pattern is a KeyPress or + * KeyRelease) and KeyPress and KeyRelease events (if the next + * pattern event is a ButtonPress or ButtonRelease). Here are + * some tricky cases to consider: * 1. Double-Button or Double-Key events. * 2. Double-ButtonRelease or Double-KeyRelease events. - * 3. The arrival of various events like Enter and Leave - * and FocusIn and GraphicsExpose between two button - * presses or key presses. - * 4. Modifier keys like Shift and Control shouldn't - * generate conflicts with button events. + * 3. The arrival of various events like Enter and Leave and + * FocusIn and GraphicsExpose between two button presses or + * key presses. + * 4. Modifier keys like Shift and Control shouldn't generate + * conflicts with button events. */ if ((patPtr->eventType == KeyPress) @@ -2067,27 +2033,25 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) goto nextEvent; } if (eventPtr->xany.type == CreateNotify - && eventPtr->xcreatewindow.parent != window) { + && eventPtr->xcreatewindow.parent != window) { goto nextSequence; - } else - if (eventPtr->xany.window != window) { + } else if (eventPtr->xany.window != window) { goto nextSequence; } /* - * Note: it's important for the keysym check to go before - * the modifier check, so we can ignore unwanted modifier - * keys before choking on the modifier check. + * Note: it's important for the keysym check to go before the + * modifier check, so we can ignore unwanted modifier keys before + * choking on the modifier check. */ if ((patPtr->detail.clientData != 0) && (patPtr->detail.clientData != detailPtr->clientData)) { /* - * The detail appears not to match. However, if the event - * is a KeyPress for a modifier key then just ignore the - * event. Otherwise event sequences like "aD" never match - * because the shift key goes down between the "a" and the - * "D". + * The detail appears not to match. However, if the event is a + * KeyPress for a modifier key then just ignore the event. + * Otherwise event sequences like "aD" never match because the + * shift key goes down between the "a" and the "D". */ if (eventPtr->xany.type == KeyPress) { @@ -2149,7 +2113,7 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) } patPtr++; patCount--; - nextEvent: + nextEvent: if (eventPtr == bindPtr->eventRing) { eventPtr = &bindPtr->eventRing[EVENT_BUFFER_SIZE-1]; detailPtr = &bindPtr->detailRing[EVENT_BUFFER_SIZE-1]; @@ -2169,9 +2133,9 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) PatternTableKey key; /* - * The sequence matches the physical constraints. - * Is this object interested in any of the virtual events - * that correspond to this sequence? + * The sequence matches the physical constraints. Is this object + * interested in any of the virtual events that correspond to this + * sequence? */ voPtr = psPtr->voPtr; @@ -2182,9 +2146,9 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) key.detail.clientData = 0; for (iVirt = 0; iVirt < voPtr->numOwners; iVirt++) { - Tcl_HashEntry *hPtr = voPtr->owners[iVirt]; + Tcl_HashEntry *hPtr = voPtr->owners[iVirt]; - key.detail.name = (Tk_Uid) Tcl_GetHashKey(hPtr->tablePtr, + key.detail.name = (Tk_Uid) Tcl_GetHashKey(hPtr->tablePtr, hPtr); hPtr = Tcl_FindHashEntry(&bindPtr->patternTable, (char *) &key); @@ -2212,14 +2176,15 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) * The physical event matches a virtual event's definition, but * the tag isn't interested in it. */ + goto nextSequence; } - match: + match: /* - * This sequence matches. If we've already got another match, - * pick whichever is most specific. Detail is most important, - * then needMods. + * This sequence matches. If we've already got another match, pick + * whichever is most specific. Detail is most important, then + * needMods. */ if (bestPtr != NULL) { @@ -2255,28 +2220,27 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) /* * Tie goes to current best pattern. * - * (1) For virtual vs. virtual, the least recently defined - * virtual wins, because virtuals are examined in order of - * definition. This order is _not_ guaranteed in the - * documentation. + * (1) For virtual vs. virtual, the least recently defined virtual + * wins, because virtuals are examined in order of definition. + * This order is _not_ guaranteed in the documentation. * - * (2) For virtual vs. physical, the physical wins because all - * the physicals are examined before the virtuals. This order - * is guaranteed in the documentation. + * (2) For virtual vs. physical, the physical wins because all the + * physicals are examined before the virtuals. This order is + * guaranteed in the documentation. * * (3) For physical vs. physical pattern, the most recently * defined physical wins, because physicals are examined in - * reverse order of definition. This order is guaranteed in - * the documentation. + * reverse order of definition. This order is guaranteed in the + * documentation. */ - goto nextSequence; + goto nextSequence; } - newBest: + newBest: bestPtr = matchPtr; bestSourcePtr = sourcePtr; - nextSequence: + nextSequence: continue; } @@ -2290,13 +2254,12 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) * * ExpandPercents -- * - * Given a command and an event, produce a new command - * by replacing % constructs in the original command - * with information from the X event. + * Given a command and an event, produce a new command by replacing % + * constructs in the original command with information from the X event. * * Results: - * The new expanded command is appended to the dynamic string - * given by dsPtr. + * The new expanded command is appended to the dynamic string given by + * dsPtr. * * Side effects: * None. @@ -2306,12 +2269,12 @@ MatchPatterns(dispPtr, bindPtr, psPtr, bestPtr, objectPtr, sourcePtrPtr) static void ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr) - TkWindow *winPtr; /* Window where event occurred: needed to - * get input context. */ - CONST char *before; /* Command containing percent expressions - * to be replaced. */ - XEvent *eventPtr; /* X event containing information to be - * used in % replacements. */ + TkWindow *winPtr; /* Window where event occurred: needed to get + * input context. */ + CONST char *before; /* Command containing percent expressions to + * be replaced. */ + XEvent *eventPtr; /* X event containing information to be used + * in % replacements. */ KeySym keySym; /* KeySym: only relevant for KeyPress and * KeyRelease events). */ Tcl_DString *dsPtr; /* Dynamic string in which to append new @@ -2332,10 +2295,11 @@ ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr) } else { flags = 0; } + while (1) { /* - * Find everything up to the next % character and append it - * to the result string. + * Find everything up to the next % character and append it to the + * result string. */ for (string = before; (*string != 0) && (*string != '%'); string++) { @@ -2350,331 +2314,336 @@ ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr) } /* - * There's a percent sequence here. Process it. + * There's a percent sequence here. Process it. */ number = 0; string = "??"; switch (before[1]) { - case '#': - number = eventPtr->xany.serial; - goto doNumber; - case 'a': - if (flags & CONFIG) { - TkpPrintWindowId(numStorage, eventPtr->xconfigure.above); - string = numStorage; - } - goto doString; - case 'b': - if (flags & BUTTON) { - number = eventPtr->xbutton.button; - goto doNumber; - } - goto doString; - case 'c': - if (flags & EXPOSE) { - number = eventPtr->xexpose.count; - goto doNumber; - } - goto doString; - case 'd': - if (flags & (CROSSING|FOCUS)) { - if (flags & FOCUS) { - number = eventPtr->xfocus.detail; - } else { - number = eventPtr->xcrossing.detail; - } - string = TkFindStateString(notifyDetail, number); - } else if (flags & CONFIGREQ) { - if (eventPtr->xconfigurerequest.value_mask & CWStackMode) { - string = TkFindStateString(configureRequestDetail, - eventPtr->xconfigurerequest.detail); - } else { - string = ""; - } - } else if (flags & VIRTUAL) { - XVirtualEvent *vePtr = (XVirtualEvent *) eventPtr; - - if (vePtr->user_data != NULL) { - string = Tcl_GetString(vePtr->user_data); - } else { - string = ""; - } - } - goto doString; - case 'f': - if (flags & CROSSING) { - number = eventPtr->xcrossing.focus; - goto doNumber; - } - goto doString; - case 'h': - if (flags & EXPOSE) { - number = eventPtr->xexpose.height; - } else if (flags & (CONFIG)) { - number = eventPtr->xconfigure.height; - } else if (flags & CREATE) { - number = eventPtr->xcreatewindow.height; - } else if (flags & CONFIGREQ) { - number = eventPtr->xconfigurerequest.height; - } else if (flags & RESIZEREQ) { - number = eventPtr->xresizerequest.height; - } else { - goto doString; - } - goto doNumber; - case 'i': - if (flags & CREATE) { - TkpPrintWindowId(numStorage, eventPtr->xcreatewindow.window); - } else if (flags & CONFIGREQ) { - TkpPrintWindowId(numStorage, eventPtr->xconfigurerequest.window); - } else if (flags & MAPREQ) { - TkpPrintWindowId(numStorage, eventPtr->xmaprequest.window); - } else { - TkpPrintWindowId(numStorage, eventPtr->xany.window); - } + case '#': + number = eventPtr->xany.serial; + goto doNumber; + case 'a': + if (flags & CONFIG) { + TkpPrintWindowId(numStorage, eventPtr->xconfigure.above); string = numStorage; - goto doString; - case 'k': - if (flags & KEY) { - number = eventPtr->xkey.keycode; - goto doNumber; - } - goto doString; - case 'm': - if (flags & CROSSING) { - number = eventPtr->xcrossing.mode; - string = TkFindStateString(notifyMode, number); - } else if (flags & FOCUS) { - number = eventPtr->xfocus.mode; - string = TkFindStateString(notifyMode, number); - } - goto doString; - case 'o': - if (flags & CREATE) { - number = eventPtr->xcreatewindow.override_redirect; - } else if (flags & MAP) { - number = eventPtr->xmap.override_redirect; - } else if (flags & REPARENT) { - number = eventPtr->xreparent.override_redirect; - } else if (flags & CONFIG) { - number = eventPtr->xconfigure.override_redirect; - } else { - goto doString; - } - goto doNumber; - case 'p': - if (flags & CIRC) { - string = TkFindStateString(circPlace, eventPtr->xcirculate.place); - } else if (flags & CIRCREQ) { - string = TkFindStateString(circPlace, eventPtr->xcirculaterequest.place); - } - goto doString; - case 's': - if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { - number = eventPtr->xkey.state; - } else if (flags & CROSSING) { - number = eventPtr->xcrossing.state; - } else if (flags & PROP) { - string = TkFindStateString(propNotify, - eventPtr->xproperty.state); - goto doString; - } else if (flags & VISIBILITY) { - string = TkFindStateString(visNotify, - eventPtr->xvisibility.state); - goto doString; - } else { - goto doString; - } - goto doNumber; - case 't': - if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { - number = (int) eventPtr->xkey.time; - } else if (flags & CROSSING) { - number = (int) eventPtr->xcrossing.time; - } else if (flags & PROP) { - number = (int) eventPtr->xproperty.time; - } else { - goto doString; - } + } + goto doString; + case 'b': + if (flags & BUTTON) { + number = eventPtr->xbutton.button; goto doNumber; - case 'v': - number = eventPtr->xconfigurerequest.value_mask; + } + goto doString; + case 'c': + if (flags & EXPOSE) { + number = eventPtr->xexpose.count; goto doNumber; - case 'w': - if (flags & EXPOSE) { - number = eventPtr->xexpose.width; - } else if (flags & CONFIG) { - number = eventPtr->xconfigure.width; - } else if (flags & CREATE) { - number = eventPtr->xcreatewindow.width; - } else if (flags & CONFIGREQ) { - number = eventPtr->xconfigurerequest.width; - } else if (flags & RESIZEREQ) { - number = eventPtr->xresizerequest.width; + } + goto doString; + case 'd': + if (flags & (CROSSING|FOCUS)) { + if (flags & FOCUS) { + number = eventPtr->xfocus.detail; } else { - goto doString; + number = eventPtr->xcrossing.detail; } - goto doNumber; - case 'x': - if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { - number = eventPtr->xkey.x; - } else if (flags & CROSSING) { - number = eventPtr->xcrossing.x; - } else if (flags & EXPOSE) { - number = eventPtr->xexpose.x; - } else if (flags & (CREATE|CONFIG|GRAVITY)) { - number = eventPtr->xcreatewindow.x; - } else if (flags & REPARENT) { - number = eventPtr->xreparent.x; - } else if (flags & CREATE) { - number = eventPtr->xcreatewindow.x; - } else if (flags & CONFIGREQ) { - number = eventPtr->xconfigurerequest.x; + string = TkFindStateString(notifyDetail, number); + } else if (flags & CONFIGREQ) { + if (eventPtr->xconfigurerequest.value_mask & CWStackMode) { + string = TkFindStateString(configureRequestDetail, + eventPtr->xconfigurerequest.detail); } else { - goto doString; + string = ""; } - goto doNumber; - case 'y': - if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { - number = eventPtr->xkey.y; - } else if (flags & EXPOSE) { - number = eventPtr->xexpose.y; - } else if (flags & (CREATE|CONFIG|GRAVITY)) { - number = eventPtr->xcreatewindow.y; - } else if (flags & REPARENT) { - number = eventPtr->xreparent.y; - } else if (flags & CROSSING) { - number = eventPtr->xcrossing.y; - } else if (flags & CREATE) { - number = eventPtr->xcreatewindow.y; - } else if (flags & CONFIGREQ) { - number = eventPtr->xconfigurerequest.y; + } else if (flags & VIRTUAL) { + XVirtualEvent *vePtr = (XVirtualEvent *) eventPtr; + + if (vePtr->user_data != NULL) { + string = Tcl_GetString(vePtr->user_data); } else { - goto doString; + string = ""; } + } + goto doString; + case 'f': + if (flags & CROSSING) { + number = eventPtr->xcrossing.focus; goto doNumber; - case 'A': - if (flags & KEY) { - Tcl_DStringFree(&buf); - string = TkpGetString(winPtr, eventPtr, &buf); - } + } + goto doString; + case 'h': + if (flags & EXPOSE) { + number = eventPtr->xexpose.height; + } else if (flags & (CONFIG)) { + number = eventPtr->xconfigure.height; + } else if (flags & CREATE) { + number = eventPtr->xcreatewindow.height; + } else if (flags & CONFIGREQ) { + number = eventPtr->xconfigurerequest.height; + } else if (flags & RESIZEREQ) { + number = eventPtr->xresizerequest.height; + } else { goto doString; - case 'B': - if (flags & CREATE) { - number = eventPtr->xcreatewindow.border_width; - } else if (flags & CONFIGREQ) { - number = eventPtr->xconfigurerequest.border_width; - } else if (flags & CONFIG) { - number = eventPtr->xconfigure.border_width; - } else { - goto doString; - } + } + goto doNumber; + case 'i': + if (flags & CREATE) { + TkpPrintWindowId(numStorage, eventPtr->xcreatewindow.window); + } else if (flags & CONFIGREQ) { + TkpPrintWindowId(numStorage, + eventPtr->xconfigurerequest.window); + } else if (flags & MAPREQ) { + TkpPrintWindowId(numStorage, eventPtr->xmaprequest.window); + } else { + TkpPrintWindowId(numStorage, eventPtr->xany.window); + } + string = numStorage; + goto doString; + case 'k': + if (flags & KEY) { + number = eventPtr->xkey.keycode; goto doNumber; - case 'D': - /* - * This is used only by the MouseWheel event. - */ - if (flags & KEY) { - number = eventPtr->xkey.keycode; - goto doNumber; - } + } + goto doString; + case 'm': + if (flags & CROSSING) { + number = eventPtr->xcrossing.mode; + string = TkFindStateString(notifyMode, number); + } else if (flags & FOCUS) { + number = eventPtr->xfocus.mode; + string = TkFindStateString(notifyMode, number); + } + goto doString; + case 'o': + if (flags & CREATE) { + number = eventPtr->xcreatewindow.override_redirect; + } else if (flags & MAP) { + number = eventPtr->xmap.override_redirect; + } else if (flags & REPARENT) { + number = eventPtr->xreparent.override_redirect; + } else if (flags & CONFIG) { + number = eventPtr->xconfigure.override_redirect; + } else { goto doString; - case 'E': - number = (int) eventPtr->xany.send_event; - goto doNumber; - case 'K': - if (flags & KEY) { - char *name; - - name = TkKeysymToString(keySym); - if (name != NULL) { - string = name; - } - } + } + goto doNumber; + case 'p': + if (flags & CIRC) { + string = TkFindStateString(circPlace, + eventPtr->xcirculate.place); + } else if (flags & CIRCREQ) { + string = TkFindStateString(circPlace, + eventPtr->xcirculaterequest.place); + } + goto doString; + case 's': + if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { + number = eventPtr->xkey.state; + } else if (flags & CROSSING) { + number = eventPtr->xcrossing.state; + } else if (flags & PROP) { + string = TkFindStateString(propNotify, + eventPtr->xproperty.state); goto doString; - case 'N': - if (flags & KEY) { - number = (int) keySym; - goto doNumber; - } + } else if (flags & VISIBILITY) { + string = TkFindStateString(visNotify, + eventPtr->xvisibility.state); goto doString; - case 'P': - if (flags & PROP) { - string = Tk_GetAtomName((Tk_Window) winPtr, eventPtr->xproperty.atom); - } + } else { goto doString; - case 'R': - if (flags & KEY_BUTTON_MOTION_CROSSING) { - TkpPrintWindowId(numStorage, eventPtr->xkey.root); - string = numStorage; - } + } + goto doNumber; + case 't': + if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { + number = (int) eventPtr->xkey.time; + } else if (flags & CROSSING) { + number = (int) eventPtr->xcrossing.time; + } else if (flags & PROP) { + number = (int) eventPtr->xproperty.time; + } else { goto doString; - case 'S': - if (flags & KEY_BUTTON_MOTION_CROSSING) { - TkpPrintWindowId(numStorage, eventPtr->xkey.subwindow); - string = numStorage; - } + } + goto doNumber; + case 'v': + number = eventPtr->xconfigurerequest.value_mask; + goto doNumber; + case 'w': + if (flags & EXPOSE) { + number = eventPtr->xexpose.width; + } else if (flags & CONFIG) { + number = eventPtr->xconfigure.width; + } else if (flags & CREATE) { + number = eventPtr->xcreatewindow.width; + } else if (flags & CONFIGREQ) { + number = eventPtr->xconfigurerequest.width; + } else if (flags & RESIZEREQ) { + number = eventPtr->xresizerequest.width; + } else { goto doString; - case 'T': - number = eventPtr->type; + } + goto doNumber; + case 'x': + if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { + number = eventPtr->xkey.x; + } else if (flags & CROSSING) { + number = eventPtr->xcrossing.x; + } else if (flags & EXPOSE) { + number = eventPtr->xexpose.x; + } else if (flags & (CREATE|CONFIG|GRAVITY)) { + number = eventPtr->xcreatewindow.x; + } else if (flags & REPARENT) { + number = eventPtr->xreparent.x; + } else if (flags & CREATE) { + number = eventPtr->xcreatewindow.x; + } else if (flags & CONFIGREQ) { + number = eventPtr->xconfigurerequest.x; + } else { + goto doString; + } + goto doNumber; + case 'y': + if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { + number = eventPtr->xkey.y; + } else if (flags & EXPOSE) { + number = eventPtr->xexpose.y; + } else if (flags & (CREATE|CONFIG|GRAVITY)) { + number = eventPtr->xcreatewindow.y; + } else if (flags & REPARENT) { + number = eventPtr->xreparent.y; + } else if (flags & CROSSING) { + number = eventPtr->xcrossing.y; + } else if (flags & CREATE) { + number = eventPtr->xcreatewindow.y; + } else if (flags & CONFIGREQ) { + number = eventPtr->xconfigurerequest.y; + } else { + goto doString; + } + goto doNumber; + case 'A': + if (flags & KEY) { + Tcl_DStringFree(&buf); + string = TkpGetString(winPtr, eventPtr, &buf); + } + goto doString; + case 'B': + if (flags & CREATE) { + number = eventPtr->xcreatewindow.border_width; + } else if (flags & CONFIGREQ) { + number = eventPtr->xconfigurerequest.border_width; + } else if (flags & CONFIG) { + number = eventPtr->xconfigure.border_width; + } else { + goto doString; + } + goto doNumber; + case 'D': + /* + * This is used only by the MouseWheel event. + */ + + if (flags & KEY) { + number = eventPtr->xkey.keycode; + goto doNumber; + } + goto doString; + case 'E': + number = (int) eventPtr->xany.send_event; + goto doNumber; + case 'K': + if (flags & KEY) { + char *name; + + name = TkKeysymToString(keySym); + if (name != NULL) { + string = name; + } + } + goto doString; + case 'N': + if (flags & KEY) { + number = (int) keySym; goto doNumber; - case 'W': { + } + goto doString; + case 'P': + if (flags & PROP) { + string = Tk_GetAtomName((Tk_Window) winPtr, + eventPtr->xproperty.atom); + } + goto doString; + case 'R': + if (flags & KEY_BUTTON_MOTION_CROSSING) { + TkpPrintWindowId(numStorage, eventPtr->xkey.root); + string = numStorage; + } + goto doString; + case 'S': + if (flags & KEY_BUTTON_MOTION_CROSSING) { + TkpPrintWindowId(numStorage, eventPtr->xkey.subwindow); + string = numStorage; + } + goto doString; + case 'T': + number = eventPtr->type; + goto doNumber; + case 'W': { + Tk_Window tkwin; + + tkwin = Tk_IdToWindow(eventPtr->xany.display, + eventPtr->xany.window); + if (tkwin != NULL) { + string = Tk_PathName(tkwin); + } else { + string = "??"; + } + goto doString; + } + case 'X': + if (flags & KEY_BUTTON_MOTION_CROSSING) { Tk_Window tkwin; + int x, y; + int width, height; + number = eventPtr->xkey.x_root; tkwin = Tk_IdToWindow(eventPtr->xany.display, eventPtr->xany.window); if (tkwin != NULL) { - string = Tk_PathName(tkwin); - } else { - string = "??"; + Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); + number -= x; } - goto doString; + goto doNumber; } - case 'X': - if (flags & KEY_BUTTON_MOTION_CROSSING) { - Tk_Window tkwin; - int x, y; - int width, height; - - number = eventPtr->xkey.x_root; - tkwin = Tk_IdToWindow(eventPtr->xany.display, - eventPtr->xany.window); - if (tkwin != NULL) { - Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - number -= x; - } - goto doNumber; - } - goto doString; - case 'Y': - if (flags & KEY_BUTTON_MOTION_CROSSING) { - Tk_Window tkwin; - int x, y; - int width, height; - - number = eventPtr->xkey.y_root; - tkwin = Tk_IdToWindow(eventPtr->xany.display, - eventPtr->xany.window); - if (tkwin != NULL) { - Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); - number -= y; - } - goto doNumber; + goto doString; + case 'Y': + if (flags & KEY_BUTTON_MOTION_CROSSING) { + Tk_Window tkwin; + int x, y; + int width, height; + + number = eventPtr->xkey.y_root; + tkwin = Tk_IdToWindow(eventPtr->xany.display, + eventPtr->xany.window); + if (tkwin != NULL) { + Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height); + number -= y; } - goto doString; - default: - numStorage[0] = before[1]; - numStorage[1] = '\0'; - string = numStorage; - goto doString; + goto doNumber; + } + goto doString; + default: + numStorage[0] = before[1]; + numStorage[1] = '\0'; + string = numStorage; + goto doString; } - doNumber: + doNumber: sprintf(numStorage, "%d", number); string = numStorage; - doString: + doString: spaceNeeded = Tcl_ScanElement(string, &cvtFlags); length = Tcl_DStringLength(dsPtr); Tcl_DStringSetLength(dsPtr, length + spaceNeeded); @@ -2692,28 +2661,27 @@ ExpandPercents(winPtr, before, eventPtr, keySym, dsPtr) * * ChangeScreen -- * - * This procedure is invoked whenever the current screen changes - * in an application. It invokes a Tcl procedure named - * "tk::ScreenChanged", passing it the screen name as argument. - * tk::ScreenChanged does things like making the tk::Priv variable - * point to an array for the current display. + * This function is invoked whenever the current screen changes in an + * application. It invokes a Tcl function named "tk::ScreenChanged", + * passing it the screen name as argument. tk::ScreenChanged does things + * like making the tk::Priv variable point to an array for the current + * display. * * Results: * None. * * Side effects: - * Depends on what tk::ScreenChanged does. If an error occurs - * them bgerror will be invoked. + * Depends on what tk::ScreenChanged does. If an error occurs them + * bgerror will be invoked. * *---------------------------------------------------------------------- */ static void ChangeScreen(interp, dispName, screenIndex) - Tcl_Interp *interp; /* Interpreter in which to invoke - * command. */ - char *dispName; /* Name of new display. */ - int screenIndex; /* Index of new screen. */ + Tcl_Interp *interp; /* Interpreter in which to invoke command. */ + char *dispName; /* Name of new display. */ + int screenIndex; /* Index of new screen. */ { Tcl_DString cmd; int code; @@ -2738,8 +2706,8 @@ ChangeScreen(interp, dispName, screenIndex) * * Tk_EventCmd -- * - * This procedure is invoked to process the "event" Tcl command. - * It is used to define and generate events. + * This function is invoked to process the "event" Tcl command. It is + * used to define and generate events. * * Results: * A standard Tcl result. @@ -2783,64 +2751,61 @@ Tk_EventObjCmd(clientData, interp, objc, objv) } switch ((enum options) index) { - case EVENT_ADD: { - int i; - char *name, *event; - - if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, - "virtual sequence ?sequence ...?"); - return TCL_ERROR; - } - name = Tcl_GetStringFromObj(objv[2], NULL); - for (i = 3; i < objc; i++) { - event = Tcl_GetStringFromObj(objv[i], NULL); - if (CreateVirtualEvent(interp, vetPtr, name, event) != TCL_OK) { - return TCL_ERROR; - } - } - break; + case EVENT_ADD: { + int i; + char *name, *event; + + if (objc < 4) { + Tcl_WrongNumArgs(interp, 2, objv, + "virtual sequence ?sequence ...?"); + return TCL_ERROR; } - case EVENT_DELETE: { - int i; - char *name, *event; - - if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, - "virtual ?sequence sequence ...?"); + name = Tcl_GetStringFromObj(objv[2], NULL); + for (i = 3; i < objc; i++) { + event = Tcl_GetStringFromObj(objv[i], NULL); + if (CreateVirtualEvent(interp, vetPtr, name, event) != TCL_OK) { return TCL_ERROR; } - name = Tcl_GetStringFromObj(objv[2], NULL); - if (objc == 3) { - return DeleteVirtualEvent(interp, vetPtr, name, NULL); - } - for (i = 3; i < objc; i++) { - event = Tcl_GetStringFromObj(objv[i], NULL); - if (DeleteVirtualEvent(interp, vetPtr, name, event) != TCL_OK) { - return TCL_ERROR; - } - } - break; } - case EVENT_GENERATE: { - if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, "window event ?options?"); - return TCL_ERROR; - } - return HandleEventGenerate(interp, tkwin, objc - 2, objv + 2); + break; + } + case EVENT_DELETE: { + int i; + char *name, *event; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, + "virtual ?sequence sequence ...?"); + return TCL_ERROR; } - case EVENT_INFO: { - if (objc == 2) { - GetAllVirtualEvents(interp, vetPtr); - return TCL_OK; - } else if (objc == 3) { - return GetVirtualEvent(interp, vetPtr, - Tcl_GetStringFromObj(objv[2], NULL)); - } else { - Tcl_WrongNumArgs(interp, 2, objv, "?virtual?"); + name = Tcl_GetStringFromObj(objv[2], NULL); + if (objc == 3) { + return DeleteVirtualEvent(interp, vetPtr, name, NULL); + } + for (i = 3; i < objc; i++) { + event = Tcl_GetStringFromObj(objv[i], NULL); + if (DeleteVirtualEvent(interp, vetPtr, name, event) != TCL_OK) { return TCL_ERROR; } } + break; + } + case EVENT_GENERATE: + if (objc < 4) { + Tcl_WrongNumArgs(interp, 2, objv, "window event ?options?"); + return TCL_ERROR; + } + return HandleEventGenerate(interp, tkwin, objc - 2, objv + 2); + case EVENT_INFO: + if (objc == 2) { + GetAllVirtualEvents(interp, vetPtr); + return TCL_OK; + } else if (objc == 3) { + return GetVirtualEvent(interp, vetPtr, Tcl_GetString(objv[2])); + } else { + Tcl_WrongNumArgs(interp, 2, objv, "?virtual?"); + return TCL_ERROR; + } } return TCL_OK; } @@ -2850,8 +2815,8 @@ Tk_EventObjCmd(clientData, interp, objc, objv) * * InitVirtualEventTable -- * - * Given storage for a virtual event table, set up the fields to - * prepare a new domain in which virtual events may be defined. + * Given storage for a virtual event table, set up the fields to prepare + * a new domain in which virtual events may be defined. * * Results: * None. @@ -2864,8 +2829,8 @@ Tk_EventObjCmd(clientData, interp, objc, objv) static void InitVirtualEventTable(vetPtr) - VirtualEventTable *vetPtr; /* Pointer to virtual event table. Memory - * is supplied by the caller. */ + VirtualEventTable *vetPtr; /* Pointer to virtual event table. Memory is + * supplied by the caller. */ { Tcl_InitHashTable(&vetPtr->patternTable, sizeof(PatternTableKey) / sizeof(int)); @@ -2877,7 +2842,7 @@ InitVirtualEventTable(vetPtr) * * DeleteVirtualEventTable -- * - * Delete the contents of a virtual event table. The caller is + * Delete the contents of a virtual event table. The caller is * responsible for freeing any memory used by the table itself. * * Results: @@ -2910,7 +2875,7 @@ DeleteVirtualEventTable(vetPtr) hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search); for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - ckfree((char *) Tcl_GetHashValue(hPtr)); + ckfree((char *) Tcl_GetHashValue(hPtr)); } Tcl_DeleteHashTable(&vetPtr->nameTable); } @@ -2920,19 +2885,17 @@ DeleteVirtualEventTable(vetPtr) * * CreateVirtualEvent -- * - * Add a new definition for a virtual event. If the virtual event - * is already defined, the new definition augments those that - * already exist. + * Add a new definition for a virtual event. If the virtual event is + * already defined, the new definition augments those that already exist. * * Results: - * The return value is TCL_ERROR if an error occured while - * creating the virtual binding. In this case, an error message - * will be left in the interp's result. If all went well then the - * return value is TCL_OK. + * The return value is TCL_ERROR if an error occured while creating the + * virtual binding. In this case, an error message will be left in the + * interp's result. If all went well then the return value is TCL_OK. * * Side effects: - * The virtual event may cause future calls to Tk_BindEvent to - * behave differently than they did previously. + * The virtual event may cause future calls to Tk_BindEvent to behave + * differently than they did previously. * *---------------------------------------------------------------------- */ @@ -2940,7 +2903,7 @@ DeleteVirtualEventTable(vetPtr) static int CreateVirtualEvent(interp, vetPtr, virtString, eventString) Tcl_Interp *interp; /* Used for error reporting. */ - VirtualEventTable *vetPtr;/* Table in which to augment virtual event. */ + VirtualEventTable *vetPtr; /* Table in which to augment virtual event. */ char *virtString; /* Name of new virtual event. */ char *eventString; /* String describing physical event that * triggers virtual event. */ @@ -2952,10 +2915,10 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString) PhysicalsOwned *poPtr; VirtualOwners *voPtr; Tk_Uid virtUid; - + virtUid = GetVirtualEventUid(interp, virtString); if (virtUid == NULL) { - return TCL_ERROR; + return TCL_ERROR; } /* @@ -2965,7 +2928,7 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString) psPtr = FindSequence(interp, &vetPtr->patternTable, NULL, eventString, 1, 0, &eventMask); if (psPtr == NULL) { - return TCL_ERROR; + return TCL_ERROR; } /* @@ -2983,20 +2946,21 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString) poPtr = (PhysicalsOwned *) ckalloc(sizeof(PhysicalsOwned)); poPtr->numOwned = 0; } else { - /* + /* * See if this virtual event is already defined for this physical * event and just return if it is. */ int i; + for (i = 0; i < poPtr->numOwned; i++) { if (poPtr->patSeqs[i] == psPtr) { - return TCL_OK; + return TCL_OK; } } poPtr = (PhysicalsOwned *) ckrealloc((char *) poPtr, sizeof(PhysicalsOwned) + poPtr->numOwned * sizeof(PatSeq *)); - } + } Tcl_SetHashValue(vhPtr, (ClientData) poPtr); poPtr->patSeqs[poPtr->numOwned] = psPtr; poPtr->numOwned++; @@ -3007,10 +2971,10 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString) voPtr = psPtr->voPtr; if (voPtr == NULL) { - voPtr = (VirtualOwners *) ckalloc(sizeof(VirtualOwners)); + voPtr = (VirtualOwners *) ckalloc(sizeof(VirtualOwners)); voPtr->numOwners = 0; } else { - voPtr = (VirtualOwners *) ckrealloc((char *) voPtr, + voPtr = (VirtualOwners *) ckrealloc((char *) voPtr, sizeof(VirtualOwners) + voPtr->numOwners * sizeof(Tcl_HashEntry *)); } @@ -3026,20 +2990,20 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString) * * DeleteVirtualEvent -- * - * Remove the definition of a given virtual event. If the - * event string is NULL, all definitions of the virtual event - * will be removed. Otherwise, just the specified definition - * of the virtual event will be removed. + * Remove the definition of a given virtual event. If the event string is + * NULL, all definitions of the virtual event will be removed. + * Otherwise, just the specified definition of the virtual event will be + * removed. * * Results: - * The result is a standard Tcl return value. If an error - * occurs then the interp's result will contain an error message. - * It is not an error to attempt to delete a virtual event that - * does not exist or a definition that does not exist. + * The result is a standard Tcl return value. If an error occurs then the + * interp's result will contain an error message. It is not an error to + * attempt to delete a virtual event that does not exist or a definition + * that does not exist. * * Side effects: - * The virtual event given by virtString may be removed from the - * virtual event table. + * The virtual event given by virtString may be removed from the virtual + * event table. * *-------------------------------------------------------------- */ @@ -3047,7 +3011,7 @@ CreateVirtualEvent(interp, vetPtr, virtString, eventString) static int DeleteVirtualEvent(interp, vetPtr, virtString, eventString) Tcl_Interp *interp; /* Used for error reporting. */ - VirtualEventTable *vetPtr;/* Table in which to delete event. */ + VirtualEventTable *vetPtr; /* Table in which to delete event. */ char *virtString; /* String describing event sequence that * triggers binding. */ char *eventString; /* The event sequence that should be deleted, @@ -3062,12 +3026,12 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) virtUid = GetVirtualEventUid(interp, virtString); if (virtUid == NULL) { - return TCL_ERROR; + return TCL_ERROR; } - + vhPtr = Tcl_FindHashEntry(&vetPtr->nameTable, virtUid); if (vhPtr == NULL) { - return TCL_OK; + return TCL_OK; } poPtr = (PhysicalsOwned *) Tcl_GetHashValue(vhPtr); @@ -3076,10 +3040,9 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) unsigned long eventMask; /* - * Delete only the specific physical event associated with the - * virtual event. If the physical event doesn't already exist, or - * the virtual event doesn't own that physical event, return w/o - * doing anything. + * Delete only the specific physical event associated with the virtual + * event. If the physical event doesn't already exist, or the virtual + * event doesn't own that physical event, return w/o doing anything. */ eventPSPtr = FindSequence(interp, &vetPtr->patternTable, NULL, @@ -3087,7 +3050,7 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) if (eventPSPtr == NULL) { CONST char *string; - string = Tcl_GetStringResult(interp); + string = Tcl_GetStringResult(interp); return (string[0] != '\0') ? TCL_ERROR : TCL_OK; } } @@ -3097,7 +3060,7 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) if ((eventPSPtr == NULL) || (psPtr == eventPSPtr)) { int iVirt; VirtualOwners *voPtr; - + /* * Remove association between this physical event and the given * virtual event that it triggers. @@ -3115,10 +3078,12 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) voPtr->numOwners--; if (voPtr->numOwners == 0) { /* - * Removed last reference to this physical event, so - * remove it from physical->virtual map. + * Removed last reference to this physical event, so remove it + * from physical->virtual map. */ + PatSeq *prevPtr = (PatSeq *) Tcl_GetHashValue(psPtr->hPtr); + if (prevPtr == psPtr) { if (psPtr->nextSeqPtr == NULL) { Tcl_DeleteHashEntry(psPtr->hPtr); @@ -3142,23 +3107,23 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) } else { /* * This physical event still triggers some other virtual - * event(s). Consolidate the list of virtual owners for - * this physical event so it no longer triggers the - * given virtual event. + * event(s). Consolidate the list of virtual owners for this + * physical event so it no longer triggers the given virtual + * event. */ + voPtr->owners[iVirt] = voPtr->owners[voPtr->numOwners]; } /* - * Now delete the virtual event's reference to the physical - * event. + * Now delete the virtual event's reference to the physical event. */ poPtr->numOwned--; if (eventPSPtr != NULL && poPtr->numOwned != 0) { - /* - * Just deleting this one physical event. Consolidate list - * of owned physical events and return. + /* + * Just deleting this one physical event. Consolidate list of + * owned physical events and return. */ poPtr->patSeqs[iPhys] = poPtr->patSeqs[poPtr->numOwned]; @@ -3169,10 +3134,10 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) if (poPtr->numOwned == 0) { /* - * All the physical events for this virtual event were deleted, - * either because there was only one associated physical event or - * because the caller was deleting the entire virtual event. Now - * the virtual event itself should be deleted. + * All the physical events for this virtual event were deleted, either + * because there was only one associated physical event or because the + * caller was deleting the entire virtual event. Now the virtual event + * itself should be deleted. */ ckfree((char *) poPtr); @@ -3186,16 +3151,16 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) * * GetVirtualEvent -- * - * Return the list of physical events that can invoke the - * given virtual event. + * Return the list of physical events that can invoke the given virtual + * event. * * Results: * The return value is TCL_OK and the interp's result is filled with the * string representation of the physical events associated with the * virtual event; if there are no physical events for the given virtual - * event, the interp's result is filled with and empty string. If the - * virtual event string is improperly formed, then TCL_ERROR is - * returned and an error message is left in the interp's result. + * event, the interp's result is filled with and empty string. If the + * virtual event string is improperly formed, then TCL_ERROR is returned + * and an error message is left in the interp's result. * * Side effects: * None. @@ -3206,7 +3171,7 @@ DeleteVirtualEvent(interp, vetPtr, virtString, eventString) static int GetVirtualEvent(interp, vetPtr, virtString) Tcl_Interp *interp; /* Interpreter for reporting. */ - VirtualEventTable *vetPtr;/* Table in which to look for event. */ + VirtualEventTable *vetPtr; /* Table in which to look for event. */ char *virtString; /* String describing virtual event. */ { Tcl_HashEntry *vhPtr; @@ -3217,12 +3182,12 @@ GetVirtualEvent(interp, vetPtr, virtString) virtUid = GetVirtualEventUid(interp, virtString); if (virtUid == NULL) { - return TCL_ERROR; + return TCL_ERROR; } vhPtr = Tcl_FindHashEntry(&vetPtr->nameTable, virtUid); if (vhPtr == NULL) { - return TCL_OK; + return TCL_OK; } Tcl_DStringInit(&ds); @@ -3243,13 +3208,12 @@ GetVirtualEvent(interp, vetPtr, virtString) * * GetAllVirtualEvents -- * - * Return a list that contains the names of all the virtual - * event defined. + * Return a list that contains the names of all the virtual event + * defined. * * Results: - * There is no return value. The interp's result is modified to - * hold a Tcl list with one entry for each virtual event in - * nameTable. + * There is no return value. The interp's result is modified to hold a + * Tcl list with one entry for each virtual event in nameTable. * * Side effects: * None. @@ -3270,11 +3234,11 @@ GetAllVirtualEvents(interp, vetPtr) hPtr = Tcl_FirstHashEntry(&vetPtr->nameTable, &search); for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - Tcl_DStringSetLength(&ds, 0); + Tcl_DStringSetLength(&ds, 0); Tcl_DStringAppend(&ds, "<<", 2); Tcl_DStringAppend(&ds, Tcl_GetHashKey(hPtr->tablePtr, hPtr), -1); Tcl_DStringAppend(&ds, ">>", 2); - Tcl_AppendElement(interp, Tcl_DStringValue(&ds)); + Tcl_AppendElement(interp, Tcl_DStringValue(&ds)); } Tcl_DStringFree(&ds); @@ -3285,36 +3249,36 @@ GetAllVirtualEvents(interp, vetPtr) * * HandleEventGenerate -- * - * Helper function for the "event generate" command. Generate and - * process an XEvent, constructed from information parsed from the - * event description string and its optional arguments. + * Helper function for the "event generate" command. Generate and process + * an XEvent, constructed from information parsed from the event + * description string and its optional arguments. * * argv[0] contains name of the target window. * argv[1] contains pattern string for one event (e.g, <Control-v>). - * argv[2..argc-1] contains -field/option pairs for specifying - * additional detail in the generated event. + * argv[2..argc-1] contains -field/option pairs for specifying additional + * detail in the generated event. * - * Either virtual or physical events can be generated this way. - * The event description string must contain the specification - * for only one event. + * Either virtual or physical events can be generated this way. The event + * description string must contain the specification for only one event. * * Results: * None. * * Side effects: - * When constructing the event, - * event.xany.serial is filled with the current X serial number. - * event.xany.window is filled with the target window. - * event.xany.display is filled with the target window's display. + * When constructing the event, + * event.xany.serial is filled with the current X serial number. + * event.xany.window is filled with the target window. + * event.xany.display is filled with the target window's display. * Any other fields in eventPtr which are not specified by the pattern * string or the optional arguments, are set to 0. * - * The event may be handled sychronously or asynchronously, depending - * on the value specified by the optional "-when" option. The - * default setting is synchronous. + * The event may be handled sychronously or asynchronously, depending on + * the value specified by the optional "-when" option. The default + * setting is synchronous. * *--------------------------------------------------------------------------- */ + static int HandleEventGenerate(interp, mainWin, objc, objv) Tcl_Interp *interp; /* Interp for errors return and name lookup. */ @@ -3322,7 +3286,7 @@ HandleEventGenerate(interp, mainWin, objc, objv) int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ { - XEvent event; + XEvent event; CONST char *p; char *name, *windowName; int count, flags, synch, i, number, warp; @@ -3366,7 +3330,7 @@ HandleEventGenerate(interp, mainWin, objc, objv) char *name; name = Tcl_GetStringFromObj(objv[0], NULL); - Tcl_AppendResult(interp, "window id \"", name, + Tcl_AppendResult(interp, "window id \"", name, "\" doesn't exist in this application", (char *) NULL); return TCL_ERROR; } @@ -3398,16 +3362,17 @@ HandleEventGenerate(interp, mainWin, objc, objv) if (windowName[0]) { event.xany.window = Tk_WindowId(tkwin); } else { - event.xany.window = RootWindow(Tk_Display(tkwin), Tk_ScreenNumber(tkwin)); + event.xany.window = + RootWindow(Tk_Display(tkwin), Tk_ScreenNumber(tkwin)); } event.xany.display = Tk_Display(tkwin); flags = flagArray[event.xany.type]; if (flags & DESTROY) { /* - * Event DesotryNotify should be generated by destroying - * the window. + * Event DesotryNotify should be generated by destroying the window. */ + Tk_DestroyWindow(tkwin); return TCL_OK; } @@ -3431,8 +3396,8 @@ HandleEventGenerate(interp, mainWin, objc, objv) } /* - * Process the remaining arguments to fill in additional fields - * of the event. + * Process the remaining arguments to fill in additional fields of the + * event. */ synch = 1; @@ -3441,7 +3406,7 @@ HandleEventGenerate(interp, mainWin, objc, objv) for (i = 2; i < objc; i += 2) { Tcl_Obj *optionPtr, *valuePtr; int index; - + optionPtr = objv[i]; valuePtr = objv[i + 1]; @@ -3451,10 +3416,10 @@ HandleEventGenerate(interp, mainWin, objc, objv) } if (objc & 1) { /* - * This test occurs after Tcl_GetIndexFromObj() so that - * "event generate <Button> -xyz" will return the error message - * that "-xyz" is a bad option, rather than that the value - * for "-xyz" is missing. + * This test occurs after Tcl_GetIndexFromObj() so that "event + * generate <Button> -xyz" will return the error message that + * "-xyz" is a bad option, rather than that the value for "-xyz" + * is missing. */ Tcl_AppendResult(interp, "value for \"", @@ -3464,406 +3429,378 @@ HandleEventGenerate(interp, mainWin, objc, objv) } switch ((enum field) index) { - case EVENT_WARP: { - if (Tcl_GetBooleanFromObj(interp, valuePtr, &warp) != TCL_OK) { - return TCL_ERROR; - } - if (!(flags & (KEY_BUTTON_MOTION_VIRTUAL))) { - goto badopt; - } - break; + case EVENT_WARP: + if (Tcl_GetBooleanFromObj(interp, valuePtr, &warp) != TCL_OK) { + return TCL_ERROR; } - case EVENT_WHEN: { - pos = (Tcl_QueuePosition) TkFindStateNumObj(interp, optionPtr, - queuePosition, valuePtr); - if ((int) pos < -1) { - return TCL_ERROR; - } - synch = 0; - if ((int) pos == -1) { - synch = 1; - } - break; + if (!(flags & (KEY_BUTTON_MOTION_VIRTUAL))) { + goto badopt; } - case EVENT_ABOVE: { - if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { - return TCL_ERROR; - } - if (flags & CONFIG) { - event.xconfigure.above = Tk_WindowId(tkwin2); - } else { - goto badopt; - } - break; + break; + case EVENT_WHEN: + pos = (Tcl_QueuePosition) TkFindStateNumObj(interp, optionPtr, + queuePosition, valuePtr); + if ((int) pos < -1) { + return TCL_ERROR; } - case EVENT_BORDER: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & (CREATE|CONFIG)) { - event.xcreatewindow.border_width = number; - } else { - goto badopt; - } - break; + synch = 0; + if ((int) pos == -1) { + synch = 1; } - case EVENT_BUTTON: { - if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & BUTTON) { - event.xbutton.button = number; - } else { - goto badopt; - } - break; + break; + case EVENT_ABOVE: + if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { + return TCL_ERROR; } - case EVENT_COUNT: { - if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & EXPOSE) { - event.xexpose.count = number; - } else { - goto badopt; - } - break; + if (flags & CONFIG) { + event.xconfigure.above = Tk_WindowId(tkwin2); + } else { + goto badopt; } - case EVENT_DATA: - if (flags & VIRTUAL) { - /* - * Do not increment reference count until after - * parsing completes and we know that the event - * generation is really going to happen. - */ - userDataObj = valuePtr; - } else { - goto badopt; - } - break; - case EVENT_DELTA: { - if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if ((flags & KEY) && (event.xkey.type == MouseWheelEvent)) { - event.xkey.keycode = number; - } else { - goto badopt; - } - break; + break; + case EVENT_BORDER: + if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) { + return TCL_ERROR; } - case EVENT_DETAIL: { - number = TkFindStateNumObj(interp, optionPtr, notifyDetail, - valuePtr); - if (number < 0) { - return TCL_ERROR; - } - if (flags & FOCUS) { - event.xfocus.detail = number; - } else if (flags & CROSSING) { - event.xcrossing.detail = number; - } else { - goto badopt; - } - break; + if (flags & (CREATE|CONFIG)) { + event.xcreatewindow.border_width = number; + } else { + goto badopt; } - case EVENT_FOCUS: { - if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & CROSSING) { - event.xcrossing.focus = number; - } else { - goto badopt; - } - break; + break; + case EVENT_BUTTON: + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; } - case EVENT_HEIGHT: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & EXPOSE) { - event.xexpose.height = number; - } else if (flags & CONFIG) { - event.xconfigure.height = number; - } else { - goto badopt; - } - break; + if (flags & BUTTON) { + event.xbutton.button = number; + } else { + goto badopt; } - case EVENT_KEYCODE: { - if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if ((flags & KEY) && (event.xkey.type != MouseWheelEvent)) { - event.xkey.keycode = number; - } else { - goto badopt; - } - break; + break; + case EVENT_COUNT: + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & EXPOSE) { + event.xexpose.count = number; + } else { + goto badopt; } - case EVENT_KEYSYM: { - KeySym keysym; - char *value; + break; + case EVENT_DATA: + if (flags & VIRTUAL) { + /* + * Do not increment reference count until after parsing + * completes and we know that the event generation is really + * going to happen. + */ - value = Tcl_GetStringFromObj(valuePtr, NULL); - keysym = TkStringToKeysym(value); - if (keysym == NoSymbol) { - Tcl_AppendResult(interp, "unknown keysym \"", value, "\"", - (char *) NULL); - return TCL_ERROR; - } + userDataObj = valuePtr; + } else { + goto badopt; + } + break; + case EVENT_DELTA: + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if ((flags & KEY) && (event.xkey.type == MouseWheelEvent)) { + event.xkey.keycode = number; + } else { + goto badopt; + } + break; + case EVENT_DETAIL: + number = TkFindStateNumObj(interp, optionPtr, notifyDetail, + valuePtr); + if (number < 0) { + return TCL_ERROR; + } + if (flags & FOCUS) { + event.xfocus.detail = number; + } else if (flags & CROSSING) { + event.xcrossing.detail = number; + } else { + goto badopt; + } + break; + case EVENT_FOCUS: + if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & CROSSING) { + event.xcrossing.focus = number; + } else { + goto badopt; + } + break; + case EVENT_HEIGHT: + if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, + &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & EXPOSE) { + event.xexpose.height = number; + } else if (flags & CONFIG) { + event.xconfigure.height = number; + } else { + goto badopt; + } + break; + case EVENT_KEYCODE: + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if ((flags & KEY) && (event.xkey.type != MouseWheelEvent)) { + event.xkey.keycode = number; + } else { + goto badopt; + } + break; + case EVENT_KEYSYM: { + KeySym keysym; + char *value; + + value = Tcl_GetStringFromObj(valuePtr, NULL); + keysym = TkStringToKeysym(value); + if (keysym == NoSymbol) { + Tcl_AppendResult(interp, "unknown keysym \"", value, "\"", + (char *) NULL); + return TCL_ERROR; + } - TkpSetKeycodeAndState(tkwin, keysym, &event); - if (event.xkey.keycode == 0) { - Tcl_AppendResult(interp, "no keycode for keysym \"", value, - "\"", (char *) NULL); - return TCL_ERROR; - } - if (!(flags & KEY) || (event.xkey.type == MouseWheelEvent)) { - goto badopt; - } - break; + TkpSetKeycodeAndState(tkwin, keysym, &event); + if (event.xkey.keycode == 0) { + Tcl_AppendResult(interp, "no keycode for keysym \"", value, + "\"", (char *) NULL); + return TCL_ERROR; } - case EVENT_MODE: { - number = TkFindStateNumObj(interp, optionPtr, notifyMode, - valuePtr); - if (number < 0) { - return TCL_ERROR; - } - if (flags & CROSSING) { - event.xcrossing.mode = number; - } else if (flags & FOCUS) { - event.xfocus.mode = number; - } else { - goto badopt; - } - break; + if (!(flags & KEY) || (event.xkey.type == MouseWheelEvent)) { + goto badopt; } - case EVENT_OVERRIDE: { - if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & CREATE) { - event.xcreatewindow.override_redirect = number; - } else if (flags & MAP) { - event.xmap.override_redirect = number; - } else if (flags & REPARENT) { - event.xreparent.override_redirect = number; - } else if (flags & CONFIG) { - event.xconfigure.override_redirect = number; - } else { - goto badopt; - } - break; + break; + } + case EVENT_MODE: + number = TkFindStateNumObj(interp,optionPtr,notifyMode,valuePtr); + if (number < 0) { + return TCL_ERROR; } - case EVENT_PLACE: { - number = TkFindStateNumObj(interp, optionPtr, circPlace, - valuePtr); - if (number < 0) { - return TCL_ERROR; - } - if (flags & CIRC) { - event.xcirculate.place = number; - } else { - goto badopt; - } - break; + if (flags & CROSSING) { + event.xcrossing.mode = number; + } else if (flags & FOCUS) { + event.xfocus.mode = number; + } else { + goto badopt; } - case EVENT_ROOT: { - if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.root = Tk_WindowId(tkwin2); - } else { - goto badopt; - } - break; + break; + case EVENT_OVERRIDE: + if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; } - case EVENT_ROOTX: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.x_root = number; - } else { - goto badopt; - } - break; + if (flags & CREATE) { + event.xcreatewindow.override_redirect = number; + } else if (flags & MAP) { + event.xmap.override_redirect = number; + } else if (flags & REPARENT) { + event.xreparent.override_redirect = number; + } else if (flags & CONFIG) { + event.xconfigure.override_redirect = number; + } else { + goto badopt; } - case EVENT_ROOTY: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.y_root = number; - } else { - goto badopt; - } - break; + break; + case EVENT_PLACE: + number = TkFindStateNumObj(interp, optionPtr, circPlace, valuePtr); + if (number < 0) { + return TCL_ERROR; + } + if (flags & CIRC) { + event.xcirculate.place = number; + } else { + goto badopt; + } + break; + case EVENT_ROOT: + if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.root = Tk_WindowId(tkwin2); + } else { + goto badopt; + } + break; + case EVENT_ROOTX: + if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.x_root = number; + } else { + goto badopt; + } + break; + case EVENT_ROOTY: + if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.y_root = number; + } else { + goto badopt; } - case EVENT_SEND: { - CONST char *value; + break; + case EVENT_SEND: { + CONST char *value; - value = Tcl_GetStringFromObj(valuePtr, NULL); - if (isdigit(UCHAR(value[0]))) { - /* - * Allow arbitrary integer values for the field; they - * are needed by a few of the tests in the Tk test suite. - */ + value = Tcl_GetStringFromObj(valuePtr, NULL); + if (isdigit(UCHAR(value[0]))) { + /* + * Allow arbitrary integer values for the field; they are + * needed by a few of the tests in the Tk test suite. + */ - if (Tcl_GetIntFromObj(interp, valuePtr, &number) - != TCL_OK) { - return TCL_ERROR; - } - } else { - if (Tcl_GetBooleanFromObj(interp, valuePtr, &number) - != TCL_OK) { - return TCL_ERROR; - } - } - event.xany.send_event = number; - break; - } - case EVENT_SERIAL: { if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } - event.xany.serial = number; - break; - } - case EVENT_STATE: { - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - if (Tcl_GetIntFromObj(interp, valuePtr, &number) - != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { - event.xkey.state = number; - } else { - event.xcrossing.state = number; - } - } else if (flags & VISIBILITY) { - number = TkFindStateNumObj(interp, optionPtr, visNotify, - valuePtr); - if (number < 0) { - return TCL_ERROR; - } - event.xvisibility.state = number; - } else { - goto badopt; - } - break; - } - case EVENT_SUBWINDOW: { - if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { + } else { + if (Tcl_GetBooleanFromObj(interp,valuePtr,&number) != TCL_OK) { return TCL_ERROR; } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.subwindow = Tk_WindowId(tkwin2); - } else { - goto badopt; - } - break; } - case EVENT_TIME: { + event.xany.send_event = number; + break; + } + case EVENT_SERIAL: + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + event.xany.serial = number; + break; + case EVENT_STATE: + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.time = (Time) number; - } else if (flags & PROP) { - event.xproperty.time = (Time) number; + if (flags & (KEY_BUTTON_MOTION_VIRTUAL)) { + event.xkey.state = number; } else { - goto badopt; + event.xcrossing.state = number; } - break; - } - case EVENT_WIDTH: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) - != TCL_OK) { + } else if (flags & VISIBILITY) { + number = TkFindStateNumObj(interp, optionPtr, visNotify, + valuePtr); + if (number < 0) { return TCL_ERROR; } - if (flags & EXPOSE) { - event.xexpose.width = number; - } else if (flags & (CREATE|CONFIG)) { - event.xcreatewindow.width = number; - } else { - goto badopt; - } - break; + event.xvisibility.state = number; + } else { + goto badopt; } - case EVENT_WINDOW: { - if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { - return TCL_ERROR; - } - if (flags & (CREATE|UNMAP|MAP|REPARENT|CONFIG - |GRAVITY|CIRC)) { - event.xcreatewindow.window = Tk_WindowId(tkwin2); - } else { - goto badopt; - } - break; + break; + case EVENT_SUBWINDOW: + if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { + return TCL_ERROR; } - case EVENT_X: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) - != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.x = number; - /* - * Only modify rootx as well if it hasn't been changed. - */ - if (event.xkey.x_root == -1) { - int rootX, rootY; + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.subwindow = Tk_WindowId(tkwin2); + } else { + goto badopt; + } + break; + case EVENT_TIME: + if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.time = (Time) number; + } else if (flags & PROP) { + event.xproperty.time = (Time) number; + } else { + goto badopt; + } + break; + case EVENT_WIDTH: + if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & EXPOSE) { + event.xexpose.width = number; + } else if (flags & (CREATE|CONFIG)) { + event.xcreatewindow.width = number; + } else { + goto badopt; + } + break; + case EVENT_WINDOW: + if (NameToWindow(interp, tkwin, valuePtr, &tkwin2) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (CREATE|UNMAP|MAP|REPARENT|CONFIG|GRAVITY|CIRC)) { + event.xcreatewindow.window = Tk_WindowId(tkwin2); + } else { + goto badopt; + } + break; + case EVENT_X: + if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.x = number; - Tk_GetRootCoords(tkwin, &rootX, &rootY); - event.xkey.x_root = rootX + number; - } - } else if (flags & EXPOSE) { - event.xexpose.x = number; - } else if (flags & (CREATE|CONFIG|GRAVITY)) { - event.xcreatewindow.x = number; - } else if (flags & REPARENT) { - event.xreparent.x = number; - } else { - goto badopt; + /* + * Only modify rootx as well if it hasn't been changed. + */ + + if (event.xkey.x_root == -1) { + int rootX, rootY; + + Tk_GetRootCoords(tkwin, &rootX, &rootY); + event.xkey.x_root = rootX + number; } - break; + } else if (flags & EXPOSE) { + event.xexpose.x = number; + } else if (flags & (CREATE|CONFIG|GRAVITY)) { + event.xcreatewindow.x = number; + } else if (flags & REPARENT) { + event.xreparent.x = number; + } else { + goto badopt; } - case EVENT_Y: { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, &number) - != TCL_OK) { - return TCL_ERROR; - } - if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { - event.xkey.y = number; - /* - * Only modify rooty as well if it hasn't been changed. - */ - if (event.xkey.y_root == -1) { - int rootX, rootY; + break; + case EVENT_Y: + if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) { + return TCL_ERROR; + } + if (flags & (KEY_BUTTON_MOTION_VIRTUAL|CROSSING)) { + event.xkey.y = number; - Tk_GetRootCoords(tkwin, &rootX, &rootY); - event.xkey.y_root = rootY + number; - } - } else if (flags & EXPOSE) { - event.xexpose.y = number; - } else if (flags & (CREATE|CONFIG|GRAVITY)) { - event.xcreatewindow.y = number; - } else if (flags & REPARENT) { - event.xreparent.y = number; - } else { - goto badopt; + /* + * Only modify rooty as well if it hasn't been changed. + */ + + if (event.xkey.y_root == -1) { + int rootX, rootY; + + Tk_GetRootCoords(tkwin, &rootX, &rootY); + event.xkey.y_root = rootY + number; } - break; + } else if (flags & EXPOSE) { + event.xexpose.y = number; + } else if (flags & (CREATE|CONFIG|GRAVITY)) { + event.xcreatewindow.y = number; + } else if (flags & REPARENT) { + event.xreparent.y = number; + } else { + goto badopt; } + break; } continue; - - badopt: + + badopt: Tcl_AppendResult(interp, name, " event doesn't accept \"", Tcl_GetStringFromObj(optionPtr, NULL), "\" option", NULL); return TCL_ERROR; @@ -3872,23 +3809,31 @@ HandleEventGenerate(interp, mainWin, objc, objv) XVirtualEvent *vePtr = (XVirtualEvent *) &event; /* - * Must be virtual event to set that variable to non-NULL. - * Now we want to install the object into the event. Note - * that we must incr the refcount before firing it into the - * low-level event subsystem; the refcount will be decremented - * once the event has been processed. + * Must be virtual event to set that variable to non-NULL. Now we want + * to install the object into the event. Note that we must incr the + * refcount before firing it into the low-level event subsystem; the + * refcount will be decremented once the event has been processed. */ + vePtr->user_data = userDataObj; Tcl_IncrRefCount(userDataObj); } + + /* + * Now we have constructed the event, inject it into the event handling + * code. + */ + if (synch != 0) { Tk_HandleEvent(&event); } else { Tk_QueueWindowEvent(&event, pos); } + /* - * We only allow warping if the window is mapped + * We only allow warping if the window is mapped. */ + if ((warp != 0) && Tk_IsMapped(tkwin)) { TkDisplay *dispPtr; dispPtr = TkGetDisplay(event.xmotion.display); @@ -3902,8 +3847,8 @@ HandleEventGenerate(interp, mainWin, objc, objv) } Tcl_ResetResult(interp); return TCL_OK; - } + static int NameToWindow(interp, mainWin, objPtr, tkwinPtr) Tcl_Interp *interp; /* Interp for error return and name lookup. */ @@ -3925,7 +3870,7 @@ NameToWindow(interp, mainWin, objPtr, tkwinPtr) } else { /* * Check for the winPtr being valid, even if it looks ok to - * TkpScanWindowId. [Bug #411307] + * TkpScanWindowId. [Bug #411307] */ if ((TkpScanWindowId(NULL, name, &id) != TCL_OK) || @@ -3961,7 +3906,7 @@ DoWarp(clientData) TkDisplay *dispPtr = (TkDisplay *) clientData; XWarpPointer(dispPtr->display, (Window) None, (Window) dispPtr->warpWindow, - 0, 0, 0, 0, (int) dispPtr->warpX, (int) dispPtr->warpY); + 0, 0, 0, 0, (int) dispPtr->warpX, (int) dispPtr->warpY); XForceScreenSaver(dispPtr->display, ScreenSaverReset); dispPtr->flags &= ~TK_DISPLAY_IN_WARP; } @@ -3971,20 +3916,21 @@ DoWarp(clientData) * * GetVirtualEventUid -- * - * Determine if the given string is in the proper format for a - * virtual event. + * Determine if the given string is in the proper format for a virtual + * event. * * Results: - * The return value is NULL if the virtual event string was - * not in the proper format. In this case, an error message - * will be left in the interp's result. Otherwise the return - * value is a Tk_Uid that represents the virtual event. + * The return value is NULL if the virtual event string was not in the + * proper format. In this case, an error message will be left in the + * interp's result. Otherwise the return value is a Tk_Uid that + * represents the virtual event. * * Side effects: * None. * *------------------------------------------------------------------------- */ + static Tk_Uid GetVirtualEventUid(interp, virtString) Tcl_Interp *interp; @@ -3997,9 +3943,9 @@ GetVirtualEventUid(interp, virtString) if (length < 5 || virtString[0] != '<' || virtString[1] != '<' || virtString[length - 2] != '>' || virtString[length - 1] != '>') { - Tcl_AppendResult(interp, "virtual event \"", virtString, + Tcl_AppendResult(interp, "virtual event \"", virtString, "\" is badly formed", (char *) NULL); - return NULL; + return NULL; } virtString[length - 2] = '\0'; uid = Tk_GetUid(virtString + 2); @@ -4007,27 +3953,24 @@ GetVirtualEventUid(interp, virtString) return uid; } - /* *---------------------------------------------------------------------- * * FindSequence -- * - * Find the entry in the pattern table that corresponds to a - * particular pattern string, and return a pointer to that - * entry. + * Find the entry in the pattern table that corresponds to a particular + * pattern string, and return a pointer to that entry. * * Results: - * The return value is normally a pointer to the PatSeq - * in patternTable that corresponds to eventString. If an error - * was found while parsing eventString, or if "create" is 0 and - * no pattern sequence previously existed, then NULL is returned - * and the interp's result contains a message describing the problem. - * If no pattern sequence previously existed for eventString, then - * a new one is created with a NULL command field. In a successful - * return, *maskPtr is filled in with a mask of the event types - * on which the pattern sequence depends. + * The return value is normally a pointer to the PatSeq in patternTable + * that corresponds to eventString. If an error was found while parsing + * eventString, or if "create" is 0 and no pattern sequence previously + * existed, then NULL is returned and the interp's result contains a + * message describing the problem. If no pattern sequence previously + * existed for eventString, then a new one is created with a NULL command + * field. In a successful return, *maskPtr is filled in with a mask of + * the event types on which the pattern sequence depends. * * Side effects: * A new pattern sequence may be allocated. @@ -4038,26 +3981,22 @@ GetVirtualEventUid(interp, virtString) static PatSeq * FindSequence(interp, patternTablePtr, object, eventString, create, allowVirtual, maskPtr) - Tcl_Interp *interp; /* Interpreter to use for error - * reporting. */ - Tcl_HashTable *patternTablePtr; /* Table to use for lookup. */ + Tcl_Interp *interp; /* Interpreter to use for error reporting. */ + Tcl_HashTable *patternTablePtr; + /* Table to use for lookup. */ ClientData object; /* For binding table, token for object with - * which binding is associated. - * For virtual event table, NULL. */ - CONST char *eventString; /* String description of pattern to - * match on. See user documentation - * for details. */ - int create; /* 0 means don't create the entry if - * it doesn't already exist. Non-zero - * means create. */ - int allowVirtual; /* 0 means that virtual events are not - * allowed in the sequence. Non-zero - * otherwise. */ - unsigned long *maskPtr; /* *maskPtr is filled in with the event - * types on which this pattern sequence - * depends. */ + * which binding is associated. For virtual + * event table, NULL. */ + CONST char *eventString; /* String description of pattern to match on. + * See user documentation for details. */ + int create; /* 0 means don't create the entry if it + * doesn't already exist. Non-zero means + * create. */ + int allowVirtual; /* 0 means that virtual events are not allowed + * in the sequence. Non-zero otherwise. */ + unsigned long *maskPtr; /* *maskPtr is filled in with the event types + * on which this pattern sequence depends. */ { - Pattern pats[EVENT_BUFFER_SIZE]; int numPats, virtualFound; CONST char *p; @@ -4071,10 +4010,9 @@ FindSequence(interp, patternTablePtr, object, eventString, create, /* *------------------------------------------------------------- - * Step 1: parse the pattern string to produce an array - * of Patterns. The array is generated backwards, so - * that the lowest-indexed pattern corresponds to the last - * event that must occur. + * Step 1: parse the pattern string to produce an array of Patterns. The + * array is generated backwards, so that the lowest-indexed pattern + * corresponds to the last event that must occur. *------------------------------------------------------------- */ @@ -4099,7 +4037,7 @@ FindSequence(interp, patternTablePtr, object, eventString, create, if (eventMask & VirtualEventMask) { if (allowVirtual == 0) { - Tcl_SetResult(interp, + Tcl_SetResult(interp, "virtual event not allowed in definition of another virtual event", TCL_STATIC); return NULL; @@ -4121,8 +4059,8 @@ FindSequence(interp, patternTablePtr, object, eventString, create, /* *------------------------------------------------------------- - * Step 2: find the sequence in the binding table if it exists, - * and add a new sequence to the table if it doesn't. + * Step 2: find the sequence in the binding table if it exists, and add a + * new sequence to the table if it doesn't. *------------------------------------------------------------- */ @@ -4135,7 +4073,7 @@ FindSequence(interp, patternTablePtr, object, eventString, create, TCL_STATIC); return NULL; } - + patPtr = &pats[EVENT_BUFFER_SIZE-numPats]; memset(&key, 0, sizeof(key)); key.object = object; @@ -4158,14 +4096,15 @@ FindSequence(interp, patternTablePtr, object, eventString, create, if (new) { Tcl_DeleteHashEntry(hPtr); } + /* - * No binding exists for the sequence, so return an empty error. - * This is a special error that the caller will check for in order - * to silently ignore this case. This is a hack that maintains - * backward compatibility for Tk_GetBinding but the various "bind" - * commands silently ignore missing bindings. + * No binding exists for the sequence, so return an empty error. This + * is a special error that the caller will check for in order to + * silently ignore this case. This is a hack that maintains backward + * compatibility for Tk_GetBinding but the various "bind" commands + * silently ignore missing bindings. */ - + return NULL; } psPtr = (PatSeq *) ckalloc((unsigned) (sizeof(PatSeq) @@ -4184,7 +4123,7 @@ FindSequence(interp, patternTablePtr, object, eventString, create, memcpy((VOID *) psPtr->pats, (VOID *) patPtr, sequenceSize); - done: + done: *maskPtr = eventMask; return psPtr; } @@ -4194,34 +4133,31 @@ FindSequence(interp, patternTablePtr, object, eventString, create, * * ParseEventDescription -- * - * Fill Pattern buffer with information about event from - * event string. + * Fill Pattern buffer with information about event from event string. * * Results: - * Leaves error message in interp and returns 0 if there was an - * error due to a badly formed event string. Returns 1 if proper - * event was specified, 2 if Double modifier was used in event - * string, or 3 if Triple was used. + * Leaves error message in interp and returns 0 if there was an error due + * to a badly formed event string. Returns 1 if proper event was + * specified, 2 if Double modifier was used in event string, or 3 if + * Triple was used. * * Side effects: * On exit, eventStringPtr points to rest of event string (after the - * closing '>', so that this procedure can be called repeatedly to - * parse all the events in the entire sequence. + * closing '>', so that this function can be called repeatedly to parse + * all the events in the entire sequence. * *--------------------------------------------------------------------------- */ static int -ParseEventDescription(interp, eventStringPtr, patPtr, - eventMaskPtr) +ParseEventDescription(interp, eventStringPtr, patPtr, eventMaskPtr) Tcl_Interp *interp; /* For error messages. */ - CONST char **eventStringPtr;/* On input, holds a pointer to start of - * event string. On exit, gets pointer to - * rest of string after parsed event. */ + CONST char **eventStringPtr;/* On input, holds a pointer to start of event + * string. On exit, gets pointer to rest of + * string after parsed event. */ Pattern *patPtr; /* Filled with the pattern parsed from the * event string. */ unsigned long *eventMaskPtr;/* Filled with event mask of matched event. */ - { char *p; unsigned long eventMask; @@ -4240,7 +4176,7 @@ ParseEventDescription(interp, eventStringPtr, patPtr, eventMask = 0; count = 1; - + /* * Handle simple ASCII characters. */ @@ -4258,7 +4194,7 @@ ParseEventDescription(interp, eventStringPtr, patPtr, patPtr->detail.keySym = *p; } else { char buf[64]; - + sprintf(buf, "bad ASCII character 0x%x", (unsigned char) *p); Tcl_SetResult(interp, buf, TCL_VOLATILE); count = 0; @@ -4270,8 +4206,8 @@ ParseEventDescription(interp, eventStringPtr, patPtr, } /* - * A fancier event description. This can be either a virtual event - * or a physical event. + * A fancier event description. This can be either a virtual event or a + * physical event. * * A virtual event description consists of: * @@ -4282,30 +4218,29 @@ ParseEventDescription(interp, eventStringPtr, patPtr, * A physical event description consists of: * * 1. open angle bracket. - * 2. any number of modifiers, each followed by spaces - * or dashes. + * 2. any number of modifiers, each followed by spaces or dashes. * 3. an optional event name. - * 4. an option button or keysym name. Either this or - * item 3 *must* be present; if both are present - * then they are separated by spaces or dashes. + * 4. an option button or keysym name. Either this or item 3 *must* be + * present; if both are present then they are separated by spaces or + * dashes. * 5. a close angle bracket. */ p++; if (*p == '<') { /* - * This is a virtual event: soak up all the characters up to - * the next '>'. + * This is a virtual event: soak up all the characters up to the next + * '>'. */ - char *field = p + 1; + char *field = p + 1; p = strchr(field, '>'); if (p == field) { Tcl_SetResult(interp, "virtual event \"<<>>\" is badly formed", TCL_STATIC); count = 0; goto done; - } + } if ((p == NULL) || (p[1] != '>')) { Tcl_SetResult(interp, "missing \">\" in virtual binding", TCL_STATIC); @@ -4328,9 +4263,10 @@ ParseEventDescription(interp, eventStringPtr, patPtr, if (*p == '>') { /* * This solves the problem of, e.g., <Control-M> being - * misinterpreted as Control + Meta + missing keysym - * instead of Control + KeyPress + M. + * misinterpreted as Control + Meta + missing keysym instead of + * Control + KeyPress + M. */ + break; } hPtr = Tcl_FindHashEntry(&modTable, field); @@ -4378,7 +4314,8 @@ ParseEventDescription(interp, eventStringPtr, patPtr, } patPtr->detail.button = (*field - '0'); } else { - getKeysym: + + getKeysym: patPtr->detail.keySym = TkStringToKeysym(field); if (patPtr->detail.keySym == NoSymbol) { Tcl_AppendResult(interp, "bad event type or keysym \"", @@ -4423,10 +4360,10 @@ ParseEventDescription(interp, eventStringPtr, patPtr, } p++; -end: + end: *eventStringPtr += (p - Tcl_DStringValue(©)); *eventMaskPtr |= eventMask; -done: + done: Tcl_DStringFree(©); return count; } @@ -4436,17 +4373,15 @@ done: * * GetField -- * - * Used to parse pattern descriptions. Copies up to - * size characters from p to copy, stopping at end of - * string, space, "-", ">", or whenever size is - * exceeded. + * Used to parse pattern descriptions. Copies up to size characters from + * p to copy, stopping at end of string, space, "-", ">", or whenever + * size is exceeded. * * Results: - * The return value is a pointer to the character just - * after the last one copied (usually "-" or space or - * ">", but could be anything if size was exceeded). - * Also places NULL-terminated string (up to size - * character, including NULL), at copy. + * The return value is a pointer to the character just after the last one + * copied (usually "-" or space or ">", but could be anything if size was + * exceeded). Also places NULL-terminated string (up to size character, + * including NULL), at copy. * * Side effects: * None. @@ -4456,10 +4391,9 @@ done: static char * GetField(p, copy, size) - char *p; /* Pointer to part of pattern. */ - char *copy; /* Place to copy field. */ - int size; /* Maximum number of characters to - * copy. */ + char *p; /* Pointer to part of pattern. */ + char *copy; /* Place to copy field. */ + int size; /* Maximum number of characters to copy. */ { while ((*p != '\0') && !isspace(UCHAR(*p)) && (*p != '>') && (*p != '-') && (size > 1)) { @@ -4477,18 +4411,19 @@ GetField(p, copy, size) * * GetPatternString -- * - * Produce a string version of the given event, for displaying to - * the user. + * Produce a string version of the given event, for displaying to the + * user. * * Results: * The string is left in dsPtr. * * Side effects: - * It is the caller's responsibility to initialize the DString before - * and to free it after calling this procedure. + * It is the caller's responsibility to initialize the DString before and + * to free it after calling this function. * *--------------------------------------------------------------------------- */ + static void GetPatternString(psPtr, dsPtr) PatSeq *psPtr; @@ -4513,7 +4448,7 @@ GetPatternString(psPtr, dsPtr) */ if ((patPtr->eventType == KeyPress) - && ((psPtr->flags & PAT_NEARBY) == 0) + && ((psPtr->flags & PAT_NEARBY) == 0) && (patPtr->needMods == 0) && (patPtr->detail.keySym < 128) && isprint(UCHAR(patPtr->detail.keySym)) @@ -4537,9 +4472,9 @@ GetPatternString(psPtr, dsPtr) } /* - * It's a more general event specification. First check - * for "Double", "Triple", "Quadruple", then modifiers, - * then event type, then keysym or button detail. + * It's a more general event specification. First check for "Double", + * "Triple", "Quadruple", then modifiers, then event type, then keysym + * or button detail. */ Tcl_DStringAppend(dsPtr, "<", 1); @@ -4605,8 +4540,8 @@ GetPatternString(psPtr, dsPtr) * * EvalTclBinding -- * - * The procedure that is invoked by Tk_BindEvent when a Tcl binding - * is fired. + * The function that is invoked by Tk_BindEvent when a Tcl binding is + * fired. * * Results: * A standard Tcl result code, the result of globally evaluating the @@ -4630,12 +4565,11 @@ FreeTclBinding(clientData) * * TkStringToKeysym -- * - * This procedure finds the keysym associated with a given keysym - * name. + * This function finds the keysym associated with a given keysym name. * * Results: - * The return value is the keysym that corresponds to name, or - * NoSymbol if there is no such keysym. + * The return value is the keysym that corresponds to name, or NoSymbol + * if there is no such keysym. * * Side effects: * None. @@ -4670,12 +4604,11 @@ TkStringToKeysym(name) * * TkKeysymToString -- * - * This procedure finds the keysym name associated with a given - * keysym. + * This function finds the keysym name associated with a given keysym. * * Results: - * The return value is a pointer to a static string containing - * the name of the given keysym, or NULL if there is no known name. + * The return value is a pointer to a static string containing the name + * of the given keysym, or NULL if there is no known name. * * Side effects: * None. @@ -4703,13 +4636,13 @@ TkKeysymToString(keysym) * * TkCopyAndGlobalEval -- * - * This procedure makes a copy of a script then calls Tcl_GlobalEval - * to evaluate it. It's used in situations where the execution of - * a command may cause the original command string to be reallocated. + * This function makes a copy of a script then calls Tcl_GlobalEval to + * evaluate it. It's used in situations where the execution of a command + * may cause the original command string to be reallocated. * * Results: - * Returns the result of evaluating script, including both a standard - * Tcl completion code and a string in the interp's result. + * Returns the result of evaluating script, including both a standard Tcl + * completion code and a string in the interp's result. * * Side effects: * None. @@ -4719,9 +4652,8 @@ TkKeysymToString(keysym) int TkCopyAndGlobalEval(interp, script) - Tcl_Interp *interp; /* Interpreter in which to evaluate - * script. */ - char *script; /* Script to evaluate. */ + Tcl_Interp *interp; /* Interpreter in which to evaluate script. */ + char *script; /* Script to evaluate. */ { Tcl_DString buffer; int code; @@ -4738,13 +4670,13 @@ TkCopyAndGlobalEval(interp, script) * * TkpGetBindingXEvent -- * - * This procedure returns the XEvent associated with the - * currently executing binding. This procedure can only - * be invoked while a binding is executing. + * This function returns the XEvent associated with the currently + * executing binding. This function can only be invoked while a binding + * is executing. * * Results: - * Returns a pointer to the XEvent that caused the - * current binding code to be run. + * Returns a pointer to the XEvent that caused the current binding code + * to be run. * * Side effects: * None. @@ -4754,9 +4686,17 @@ TkCopyAndGlobalEval(interp, script) XEvent * TkpGetBindingXEvent(interp) - Tcl_Interp *interp; /* Interpreter. */ + Tcl_Interp *interp; /* Interpreter. */ { TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp); BindingTable *bindPtr = (BindingTable *) winPtr->mainPtr->bindingTable; return &(bindPtr->eventRing[bindPtr->curEvent]); } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkCanvLine.c b/generic/tkCanvLine.c index 8017829..a219b63 100644 --- a/generic/tkCanvLine.c +++ b/generic/tkCanvLine.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvLine.c,v 1.15 2004/06/08 20:28:19 dgp Exp $ + * RCS: @(#) $Id: tkCanvLine.c,v 1.16 2005/08/10 22:02:22 dkf Exp $ */ #include <stdio.h> @@ -1722,11 +1722,11 @@ GetLineIndex(interp, canvas, itemPtr, obj, indexPtr) int *indexPtr; /* Where to store converted index. */ { LineItem *linePtr = (LineItem *) itemPtr; - size_t length; - char *string = Tcl_GetStringFromObj(obj, (int *) &length); + int length; + char *string = Tcl_GetStringFromObj(obj, &length); if (string[0] == 'e') { - if (strncmp(string, "end", length) == 0) { + if (strncmp(string, "end", (unsigned) length) == 0) { *indexPtr = 2*linePtr->numPoints; } else { badIndex: diff --git a/generic/tkCanvPoly.c b/generic/tkCanvPoly.c index 3291300..060044e 100644 --- a/generic/tkCanvPoly.c +++ b/generic/tkCanvPoly.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvPoly.c,v 1.12 2004/01/13 02:06:00 davygrvy Exp $ + * RCS: @(#) $Id: tkCanvPoly.c,v 1.13 2005/08/10 22:02:22 dkf Exp $ */ #include <stdio.h> @@ -1662,11 +1662,11 @@ GetPolygonIndex(interp, canvas, itemPtr, obj, indexPtr) int *indexPtr; /* Where to store converted index. */ { PolygonItem *polyPtr = (PolygonItem *) itemPtr; - size_t length; - char *string = Tcl_GetStringFromObj(obj, (int *) &length); + int length; + char *string = Tcl_GetStringFromObj(obj, &length); if (string[0] == 'e') { - if (strncmp(string, "end", length) == 0) { + if (strncmp(string, "end", (unsigned)length) == 0) { *indexPtr = 2*(polyPtr->numPoints - polyPtr->autoClosed); } else { badIndex: diff --git a/generic/tkCanvText.c b/generic/tkCanvText.c index 5122fff..8cd3a4e 100644 --- a/generic/tkCanvText.c +++ b/generic/tkCanvText.c @@ -9,7 +9,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvText.c,v 1.17 2004/06/08 20:25:04 mdejong Exp $ + * RCS: @(#) $Id: tkCanvText.c,v 1.18 2005/08/10 22:02:22 dkf Exp $ */ #include <stdio.h> @@ -1247,28 +1247,28 @@ GetTextIndex(interp, canvas, itemPtr, obj, indexPtr) * index. */ { TextItem *textPtr = (TextItem *) itemPtr; - size_t length; + int length; int c; TkCanvas *canvasPtr = (TkCanvas *) canvas; Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; - char *string = Tcl_GetStringFromObj(obj, (int *) &length); + char *string = Tcl_GetStringFromObj(obj, &length); c = string[0]; - length = strlen(string); - if ((c == 'e') && (strncmp(string, "end", length) == 0)) { + if ((c == 'e') && (strncmp(string, "end", (unsigned) length) == 0)) { *indexPtr = textPtr->numChars; - } else if ((c == 'i') && (strncmp(string, "insert", length) == 0)) { + } else if ((c == 'i') + && (strncmp(string, "insert", (unsigned) length) == 0)) { *indexPtr = textPtr->insertPos; - } else if ((c == 's') && (strncmp(string, "sel.first", length) == 0) - && (length >= 5)) { + } else if ((c == 's') && (length >= 5) + && (strncmp(string, "sel.first", (unsigned) length) == 0)) { if (textInfoPtr->selItemPtr != itemPtr) { Tcl_SetResult(interp, "selection isn't in item", TCL_STATIC); return TCL_ERROR; } *indexPtr = textInfoPtr->selectFirst; - } else if ((c == 's') && (strncmp(string, "sel.last", length) == 0) - && (length >= 5)) { + } else if ((c == 's') && (length >= 5) + && (strncmp(string, "sel.last", (unsigned) length) == 0)) { if (textInfoPtr->selItemPtr != itemPtr) { Tcl_SetResult(interp, "selection isn't in item", TCL_STATIC); return TCL_ERROR; diff --git a/generic/tkCanvas.c b/generic/tkCanvas.c index 876c545..f5b3333 100644 --- a/generic/tkCanvas.c +++ b/generic/tkCanvas.c @@ -12,7 +12,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkCanvas.c,v 1.35 2005/06/01 19:44:45 dgp Exp $ + * RCS: @(#) $Id: tkCanvas.c,v 1.36 2005/08/10 22:02:22 dkf Exp $ */ /* #define USE_OLD_TAG_SEARCH 1 */ @@ -556,7 +556,6 @@ CanvasWidgetCmd(clientData, interp, objc, objv) Tcl_Obj *CONST objv[]; /* Argument objects. */ { TkCanvas *canvasPtr = (TkCanvas *) clientData; - unsigned int length; int c, result; Tk_Item *itemPtr = NULL; /* Initialization needed only to * prevent compiler warning. */ @@ -945,18 +944,19 @@ CanvasWidgetCmd(clientData, interp, objc, objv) int isNew = 0; Tcl_HashEntry *entryPtr; char *arg; + int length; if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "type coords ?arg arg ...?"); result = TCL_ERROR; goto done; } - arg = Tcl_GetStringFromObj(objv[2], (int *) &length); + arg = Tcl_GetStringFromObj(objv[2], &length); c = arg[0]; Tcl_MutexLock(&typeListMutex); for (typePtr = typeList; typePtr != NULL; typePtr = typePtr->nextPtr) { if ((c == typePtr->name[0]) - && (strncmp(arg, typePtr->name, length) == 0)) { + && (strncmp(arg, typePtr->name, (unsigned)length) == 0)) { if (matchPtr != NULL) { Tcl_MutexUnlock(&typeListMutex); badType: diff --git a/generic/tkConfig.c b/generic/tkConfig.c index 3cef314..f74ae7a 100644 --- a/generic/tkConfig.c +++ b/generic/tkConfig.c @@ -1,15 +1,15 @@ -/* +/* * tkConfig.c -- * - * This file contains procedures that manage configuration options - * for widgets and other things. + * This file contains functions that manage configuration options for + * widgets and other things. * * Copyright (c) 1997-1998 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkConfig.c,v 1.19 2004/01/13 02:06:00 davygrvy Exp $ + * RCS: @(#) $Id: tkConfig.c,v 1.20 2005/08/10 22:02:22 dkf Exp $ */ /* @@ -31,115 +31,111 @@ #include "tkFont.h" /* - * The following definition is an AssocData key used to keep track of - * all of the option tables that have been created for an interpreter. + * The following definition is an AssocData key used to keep track of all of + * the option tables that have been created for an interpreter. */ #define OPTION_HASH_KEY "TkOptionTable" /* - * The following two structures are used along with Tk_OptionSpec - * structures to manage configuration options. Tk_OptionSpec is - * static templates that are compiled into the code of a widget - * or other object manager. However, to look up options efficiently - * we need to supplement the static information with additional - * dynamic information, and this dynamic information may be different - * for each application. Thus we create structures of the following - * two types to hold all of the dynamic information; this is done - * by Tk_CreateOptionTable. - * - * One of the following structures corresponds to each Tk_OptionSpec. - * These structures exist as arrays inside TkOptionTable structures. + * The following two structures are used along with Tk_OptionSpec structures + * to manage configuration options. Tk_OptionSpec is static templates that are + * compiled into the code of a widget or other object manager. However, to + * look up options efficiently we need to supplement the static information + * with additional dynamic information, and this dynamic information may be + * different for each application. Thus we create structures of the following + * two types to hold all of the dynamic information; this is done by + * Tk_CreateOptionTable. + * + * One of the following structures corresponds to each Tk_OptionSpec. These + * structures exist as arrays inside TkOptionTable structures. */ typedef struct TkOption { - CONST Tk_OptionSpec *specPtr; /* The original spec from the template - * passed to Tk_CreateOptionTable.*/ - Tk_Uid dbNameUID; /* The Uid form of the option database - * name. */ - Tk_Uid dbClassUID; /* The Uid form of the option database - * class name. */ - Tcl_Obj *defaultPtr; /* Default value for this option. */ + CONST Tk_OptionSpec *specPtr; + /* The original spec from the template passed + * to Tk_CreateOptionTable.*/ + Tk_Uid dbNameUID; /* The Uid form of the option database + * name. */ + Tk_Uid dbClassUID; /* The Uid form of the option database class + * name. */ + Tcl_Obj *defaultPtr; /* Default value for this option. */ union { - Tcl_Obj *monoColorPtr; /* For color and border options, this - * is an alternate default value to - * use on monochrome displays. */ - struct TkOption *synonymPtr; /* For synonym options, this points to - * the master entry. */ - struct Tk_ObjCustomOption *custom; /* For TK_OPTION_CUSTOM. */ + Tcl_Obj *monoColorPtr; /* For color and border options, this is an + * alternate default value to use on + * monochrome displays. */ + struct TkOption *synonymPtr; + /* For synonym options, this points to the + * master entry. */ + struct Tk_ObjCustomOption *custom; + /* For TK_OPTION_CUSTOM. */ } extra; - int flags; /* Miscellaneous flag values; see - * below for definitions. */ + int flags; /* Miscellaneous flag values; see below for + * definitions. */ } Option; /* * Flag bits defined for Option structures: * - * OPTION_NEEDS_FREEING - 1 means that FreeResources must be - * invoke to free resources associated with - * the option when it is no longer needed. + * OPTION_NEEDS_FREEING - 1 means that FreeResources must be invoked to + * free resources associated with the option when + * it is no longer needed. */ #define OPTION_NEEDS_FREEING 1 /* - * One of the following exists for each Tk_OptionSpec array that has - * been passed to Tk_CreateOptionTable. + * One of the following exists for each Tk_OptionSpec array that has been + * passed to Tk_CreateOptionTable. */ typedef struct OptionTable { - int refCount; /* Counts the number of uses of this - * table (the number of times - * Tk_CreateOptionTable has returned - * it). This can be greater than 1 if - * it is shared along several option - * table chains, or if the same table - * is used for multiple purposes. */ - Tcl_HashEntry *hashEntryPtr; /* Hash table entry that refers to this - * table; used to delete the entry. */ - struct OptionTable *nextPtr; /* If templatePtr was part of a chain - * of templates, this points to the - * table corresponding to the next - * template in the chain. */ - int numOptions; /* The number of items in the options - * array below. */ - Option options[1]; /* Information about the individual - * options in the table. This must be - * the last field in the structure: - * the actual size of the array will - * be numOptions, not 1. */ + int refCount; /* Counts the number of uses of this table + * (the number of times Tk_CreateOptionTable + * has returned it). This can be greater than + * 1 if it is shared along several option + * table chains, or if the same table is used + * for multiple purposes. */ + Tcl_HashEntry *hashEntryPtr;/* Hash table entry that refers to this table; + * used to delete the entry. */ + struct OptionTable *nextPtr;/* If templatePtr was part of a chain of + * templates, this points to the table + * corresponding to the next template in the + * chain. */ + int numOptions; /* The number of items in the options array + * below. */ + Option options[1]; /* Information about the individual options in + * the table. This must be the last field in + * the structure: the actual size of the array + * will be numOptions, not 1. */ } OptionTable; /* - * Forward declarations for procedures defined later in this file: + * Forward declarations for functions defined later in this file: */ -static int DoObjConfig _ANSI_ARGS_((Tcl_Interp *interp, - char *recordPtr, Option *optionPtr, - Tcl_Obj *valuePtr, Tk_Window tkwin, - Tk_SavedOption *savePtr)); -static void DestroyOptionHashTable _ANSI_ARGS_(( - ClientData clientData, Tcl_Interp *interp)); -static void FreeResources _ANSI_ARGS_((Option *optionPtr, - Tcl_Obj *objPtr, char *internalPtr, - Tk_Window tkwin)); -static Tcl_Obj * GetConfigList _ANSI_ARGS_((char *recordPtr, - Option *optionPtr, Tk_Window tkwin)); -static Tcl_Obj * GetObjectForOption _ANSI_ARGS_((char *recordPtr, - Option *optionPtr, Tk_Window tkwin)); -static Option * GetOption _ANSI_ARGS_((CONST char *name, - OptionTable *tablePtr)); -static Option * GetOptionFromObj _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *objPtr, OptionTable *tablePtr)); -static int ObjectIsEmpty _ANSI_ARGS_((Tcl_Obj *objPtr)); -static int SetOptionFromAny _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *objPtr)); +static int DoObjConfig(Tcl_Interp *interp, char *recordPtr, + Option *optionPtr, Tcl_Obj *valuePtr, + Tk_Window tkwin, Tk_SavedOption *savePtr); +static void DestroyOptionHashTable(ClientData clientData, + Tcl_Interp *interp); +static void FreeResources(Option *optionPtr, Tcl_Obj *objPtr, + char *internalPtr, Tk_Window tkwin); +static Tcl_Obj * GetConfigList(char *recordPtr, + Option *optionPtr, Tk_Window tkwin); +static Tcl_Obj * GetObjectForOption(char *recordPtr, + Option *optionPtr, Tk_Window tkwin); +static Option * GetOption(CONST char *name, OptionTable *tablePtr); +static Option * GetOptionFromObj(Tcl_Interp *interp, + Tcl_Obj *objPtr, OptionTable *tablePtr); +static int ObjectIsEmpty(Tcl_Obj *objPtr); +static int SetOptionFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); /* - * The structure below defines an object type that is used to cache the - * result of looking up an option name. If an object has this type, then - * its internalPtr1 field points to the OptionTable in which it was looked up, - * and the internalPtr2 field points to the entry that matched. + * The structure below defines an object type that is used to cache the result + * of looking up an option name. If an object has this type, then its + * internalPtr1 field points to the OptionTable in which it was looked up, and + * the internalPtr2 field points to the entry that matched. */ Tcl_ObjType tkOptionObjType = { @@ -155,12 +151,12 @@ Tcl_ObjType tkOptionObjType = { * * Tk_CreateOptionTable -- * - * Given a template for configuration options, this procedure - * creates a table that may be used to look up options efficiently. + * Given a template for configuration options, this function creates a + * table that may be used to look up options efficiently. * * Results: - * Returns a token to a structure that can be passed to procedures - * such as Tk_InitOptions, Tk_SetOptions, and Tk_FreeConfigOptions. + * Returns a token to a structure that can be passed to functions such as + * Tk_InitOptions, Tk_SetOptions, and Tk_FreeConfigOptions. * * Side effects: * Storage is allocated. @@ -170,11 +166,11 @@ Tcl_ObjType tkOptionObjType = { Tk_OptionTable Tk_CreateOptionTable(interp, templatePtr) - Tcl_Interp *interp; /* Interpreter associated with the - * application in which this table - * will be used. */ - CONST Tk_OptionSpec *templatePtr; /* Static information about the - * configuration options. */ + Tcl_Interp *interp; /* Interpreter associated with the application + * in which this table will be used. */ + CONST Tk_OptionSpec *templatePtr; + /* Static information about the configuration + * options. */ { Tcl_HashTable *hashTablePtr; Tcl_HashEntry *hashEntryPtr; @@ -185,13 +181,13 @@ Tk_CreateOptionTable(interp, templatePtr) int numOptions, i; /* - * We use an AssocData value in the interpreter to keep a hash - * table of all the option tables we've created for this application. - * This is used for two purposes. First, it allows us to share the - * tables (e.g. in several chains) and second, we use the deletion - * callback for the AssocData to delete all the option tables when - * the interpreter is deleted. The code below finds the hash table - * or creates a new one if it doesn't already exist. + * We use an AssocData value in the interpreter to keep a hash table of + * all the option tables we've created for this application. This is used + * for two purposes. First, it allows us to share the tables (e.g. in + * several chains) and second, we use the deletion callback for the + * AssocData to delete all the option tables when the interpreter is + * deleted. The code below finds the hash table or creates a new one if it + * doesn't already exist. */ hashTablePtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, OPTION_HASH_KEY, @@ -204,8 +200,8 @@ Tk_CreateOptionTable(interp, templatePtr) } /* - * See if a table has already been created for this template. If - * so, just reuse the existing table. + * See if a table has already been created for this template. If so, just + * reuse the existing table. */ hashEntryPtr = Tcl_CreateHashEntry(hashTablePtr, (char *) templatePtr, @@ -217,8 +213,8 @@ Tk_CreateOptionTable(interp, templatePtr) } /* - * Count the number of options in the template, then create the - * table structure. + * Count the number of options in the template, then create the table + * structure. */ numOptions = 0; @@ -247,9 +243,8 @@ Tk_CreateOptionTable(interp, templatePtr) if (specPtr->type == TK_OPTION_SYNONYM) { /* - * This is a synonym option; find the master option that it - * refers to and create a pointer from the synonym to the - * master. + * This is a synonym option; find the master option that it refers + * to and create a pointer from the synonym to the master. */ for (specPtr2 = templatePtr, i = 0; ; specPtr2++, i++) { @@ -267,12 +262,10 @@ Tk_CreateOptionTable(interp, templatePtr) optionPtr->dbNameUID = Tk_GetUid(specPtr->dbName); } if (specPtr->dbClass != NULL) { - optionPtr->dbClassUID = - Tk_GetUid(specPtr->dbClass); + optionPtr->dbClassUID = Tk_GetUid(specPtr->dbClass); } if (specPtr->defValue != NULL) { - optionPtr->defaultPtr = - Tcl_NewStringObj(specPtr->defValue, -1); + optionPtr->defaultPtr = Tcl_NewStringObj(specPtr->defValue,-1); Tcl_IncrRefCount(optionPtr->defaultPtr); } if (((specPtr->type == TK_OPTION_COLOR) @@ -288,7 +281,7 @@ Tk_CreateOptionTable(interp, templatePtr) * Get the custom parsing, etc., functions. */ optionPtr->extra.custom = - (Tk_ObjCustomOption *)specPtr->clientData; + (Tk_ObjCustomOption *) specPtr->clientData; } } if (((specPtr->type == TK_OPTION_STRING) @@ -306,9 +299,9 @@ Tk_CreateOptionTable(interp, templatePtr) Tcl_SetHashValue(hashEntryPtr, tablePtr); /* - * Finally, check to see if this template chains to another template - * with additional options. If so, call ourselves recursively to - * create the next table(s). + * Finally, check to see if this template chains to another template with + * additional options. If so, call ourselves recursively to create the + * next table(s). */ if (specPtr->clientData != NULL) { @@ -324,22 +317,22 @@ Tk_CreateOptionTable(interp, templatePtr) * * Tk_DeleteOptionTable -- * - * Called to release resources used by an option table when - * the table is no longer needed. + * Called to release resources used by an option table when the table is + * no longer needed. * * Results: * None. * * Side effects: - * The option table and associated resources (such as additional - * option tables chained off it) are destroyed. + * The option table and associated resources (such as additional option + * tables chained off it) are destroyed. * *---------------------------------------------------------------------- */ void Tk_DeleteOptionTable(optionTable) - Tk_OptionTable optionTable; /* The option table to delete. */ + Tk_OptionTable optionTable; /* The option table to delete. */ { OptionTable *tablePtr = (OptionTable *) optionTable; Option *optionPtr; @@ -374,17 +367,17 @@ Tk_DeleteOptionTable(optionTable) * * DestroyOptionHashTable -- * - * This procedure is the deletion callback associated with the - * AssocData entry created by Tk_CreateOptionTable. It is - * invoked when an interpreter is deleted, and deletes all of - * the option tables associated with that interpreter. + * This function is the deletion callback associated with the AssocData + * entry created by Tk_CreateOptionTable. It is invoked when an + * interpreter is deleted, and deletes all of the option tables + * associated with that interpreter. * * Results: * None. * * Side effects: - * The option hash table is destroyed along with all of the - * OptionTable structures that it refers to. + * The option hash table is destroyed along with all of the OptionTable + * structures that it refers to. * *---------------------------------------------------------------------- */ @@ -406,13 +399,12 @@ DestroyOptionHashTable(clientData, interp) /* * The following statements do two tricky things: - * 1. They ensure that the option table is deleted, even if - * there are outstanding references to it. - * 2. They ensure that Tk_DeleteOptionTable doesn't delete - * other tables chained from this one; we'll do it when - * we come across the hash table entry for the chained - * table (in fact, the chained table may already have - * been deleted). + * 1. They ensure that the option table is deleted, even if there are + * outstanding references to it. + * 2. They ensure that Tk_DeleteOptionTable doesn't delete other + * tables chained from this one; we'll do it when we come across + * the hash table entry for the chained table (in fact, the chained + * table may already have been deleted). */ tablePtr->refCount = 1; @@ -428,16 +420,16 @@ DestroyOptionHashTable(clientData, interp) * * Tk_InitOptions -- * - * This procedure is invoked when an object such as a widget - * is created. It supplies an initial value for each configuration - * option (the value may come from the option database, a system - * default, or the default in the option table). + * This function is invoked when an object such as a widget is created. + * It supplies an initial value for each configuration option (the value + * may come from the option database, a system default, or the default in + * the option table). * * Results: - * The return value is TCL_OK if the procedure completed - * successfully, and TCL_ERROR if one of the initial values was - * bogus. If an error occurs and interp isn't NULL, then an - * error message will be left in its result. + * The return value is TCL_OK if the function completed successfully, and + * TCL_ERROR if one of the initial values was bogus. If an error occurs + * and interp isn't NULL, then an error message will be left in its + * result. * * Side effects: * Fields of recordPtr are filled in with initial values. @@ -447,20 +439,20 @@ DestroyOptionHashTable(clientData, interp) int Tk_InitOptions(interp, recordPtr, optionTable, tkwin) - Tcl_Interp *interp; /* Interpreter for error reporting. NULL - * means don't leave an error message. */ - char *recordPtr; /* Pointer to the record to configure. - * Note: the caller should have properly - * initialized the record with NULL - * pointers for each option value. */ - Tk_OptionTable optionTable; /* The token which matches the config - * specs for the widget in question. */ + Tcl_Interp *interp; /* Interpreter for error reporting. NULL means + * don't leave an error message. */ + char *recordPtr; /* Pointer to the record to configure. Note: + * the caller should have properly initialized + * the record with NULL pointers for each + * option value. */ + Tk_OptionTable optionTable; /* The token which matches the config specs + * for the widget in question. */ Tk_Window tkwin; /* Certain options types (such as - * TK_OPTION_COLOR) need fields out - * of the window they are used in to - * be able to calculate their values. - * Not needed unless one of these - * options is in the configSpecs record. */ + * TK_OPTION_COLOR) need fields out of the + * window they are used in to be able to + * calculate their values. Not needed unless + * one of these options is in the configSpecs + * record. */ { OptionTable *tablePtr = (OptionTable *) optionTable; Option *optionPtr; @@ -473,8 +465,8 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin) /* * If this table chains to other tables, handle their initialization - * first. That way, if both tables refer to the same field of the - * record, the value in the first table will win. + * first. That way, if both tables refer to the same field of the record, + * the value in the first table will win. */ if (tablePtr->nextPtr != NULL) { @@ -491,11 +483,11 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin) for (optionPtr = tablePtr->options, count = tablePtr->numOptions; count > 0; optionPtr++, count--) { - /* * If we specify TK_OPTION_DONT_SET_DEFAULT, then the user has * processed and set a default for this already. */ + if ((optionPtr->specPtr->type == TK_OPTION_SYNONYM) || (optionPtr->specPtr->flags & TK_OPTION_DONT_SET_DEFAULT)) { continue; @@ -504,12 +496,12 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin) /* * We look in three places for the initial value, using the first - * non-NULL value that we find. First, check the option database. + * non-NULL value that we find. First, check the option database. */ valuePtr = NULL; if (optionPtr->dbNameUID != NULL) { - value = Tk_GetOption(tkwin, optionPtr->dbNameUID, + value = Tk_GetOption(tkwin, optionPtr->dbNameUID, optionPtr->dbClassUID); if (value != NULL) { valuePtr = Tcl_NewStringObj(value, -1); @@ -520,6 +512,7 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin) /* * Second, check for a system-specific default value. */ + if ((valuePtr == NULL) && (optionPtr->dbNameUID != NULL)) { valuePtr = TkpGetSystemDefault(tkwin, optionPtr->dbNameUID, @@ -530,16 +523,16 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin) } /* - * Third and last, use the default value supplied by the option - * table. In the case of color objects, we pick one of two - * values depending on whether the screen is mono or color. + * Third and last, use the default value supplied by the option table. + * In the case of color objects, we pick one of two values depending + * on whether the screen is mono or color. */ if (valuePtr == NULL) { - if ((tkwin != NULL) + if ((tkwin != NULL) && ((optionPtr->specPtr->type == TK_OPTION_COLOR) || (optionPtr->specPtr->type == TK_OPTION_BORDER)) - && (Tk_Depth(tkwin) <= 1) + && (Tk_Depth(tkwin) <= 1) && (optionPtr->extra.monoColorPtr != NULL)) { valuePtr = optionPtr->extra.monoColorPtr; } else { @@ -556,25 +549,26 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin) * referenced here, and will be properly free'd when finished, * regardless of what DoObjConfig does. */ + Tcl_IncrRefCount(valuePtr); - + if (DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, (Tk_SavedOption *) NULL) != TCL_OK) { if (interp != NULL) { char msg[200]; - + switch (source) { - case OPTION_DATABASE: - sprintf(msg, "\n (database entry for \"%.50s\")", - optionPtr->specPtr->optionName); - break; - case SYSTEM_DEFAULT: - sprintf(msg, "\n (system default for \"%.50s\")", - optionPtr->specPtr->optionName); - break; - case TABLE_DEFAULT: - sprintf(msg, "\n (default value for \"%.50s\")", - optionPtr->specPtr->optionName); + case OPTION_DATABASE: + sprintf(msg, "\n (database entry for \"%.50s\")", + optionPtr->specPtr->optionName); + break; + case SYSTEM_DEFAULT: + sprintf(msg, "\n (system default for \"%.50s\")", + optionPtr->specPtr->optionName); + break; + case TABLE_DEFAULT: + sprintf(msg, "\n (default value for \"%.50s\")", + optionPtr->specPtr->optionName); } if (tkwin != NULL) { sprintf(msg + strlen(msg) - 1, " in widget \"%.50s\")", @@ -595,39 +589,37 @@ Tk_InitOptions(interp, recordPtr, optionTable, tkwin) * * DoObjConfig -- * - * This procedure applies a new value for a configuration option - * to the record being configured. + * This function applies a new value for a configuration option to the + * record being configured. * * Results: - * The return value is TCL_OK if the procedure completed - * successfully. If an error occurred then TCL_ERROR is - * returned and an error message is left in interp's result, if - * interp isn't NULL. In addition, if oldValuePtrPtr isn't - * NULL then it *oldValuePtrPtr is filled in with a pointer - * to the option's old value. + * The return value is TCL_OK if the function completed successfully. If + * an error occurred then TCL_ERROR is returned and an error message is + * left in interp's result, if interp isn't NULL. In addition, if + * oldValuePtrPtr isn't NULL then it *oldValuePtrPtr is filled in with a + * pointer to the option's old value. * * Side effects: - * RecordPtr gets modified to hold the new value in the form of - * a Tcl_Obj, an internal representation, or both. The old - * value is freed if oldValuePtrPtr is NULL. + * RecordPtr gets modified to hold the new value in the form of a + * Tcl_Obj, an internal representation, or both. The old value is freed + * if oldValuePtrPtr is NULL. * *-------------------------------------------------------------- */ static int DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, savedOptionPtr) - Tcl_Interp *interp; /* Interpreter for error reporting. If - * NULL, then no message is left if an error + Tcl_Interp *interp; /* Interpreter for error reporting. If NULL, + * then no message is left if an error * occurs. */ - char *recordPtr; /* The record to modify to hold the new - * option value. */ - Option *optionPtr; /* Pointer to information about the - * option. */ + char *recordPtr; /* The record to modify to hold the new option + * value. */ + Option *optionPtr; /* Pointer to information about the option. */ Tcl_Obj *valuePtr; /* New value for option. */ Tk_Window tkwin; /* Window in which option will be used (needed * to allocate resources for some options). - * May be NULL if the option doesn't - * require window-related resources. */ + * May be NULL if the option doesn't require + * window-related resources. */ Tk_SavedOption *savedOptionPtr; /* If NULL, the old value for the option will * be freed. If non-NULL, the old value will @@ -636,13 +628,14 @@ DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, savedOptionPtr) * free the old value). */ { Tcl_Obj **slotPtrPtr, *oldPtr; - char *internalPtr; /* Points to location in record where - * internal representation of value should - * be stored, or NULL. */ + char *internalPtr; /* Points to location in record where internal + * representation of value should be stored, + * or NULL. */ char *oldInternalPtr; /* Points to location in which to save old * internal representation of value. */ - Tk_SavedOption internal; /* Used to save the old internal representation - * of the value if savedOptionPtr is NULL. */ + Tk_SavedOption internal; /* Used to save the old internal + * representation of the value if + * savedOptionPtr is NULL. */ CONST Tk_OptionSpec *specPtr; int nullOK; @@ -660,8 +653,8 @@ DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, savedOptionPtr) } /* - * Apply the new value in a type-specific way. Also remember the - * old object and internal forms, if they exist. + * Apply the new value in a type-specific way. Also remember the old + * object and internal forms, if they exist. */ if (specPtr->internalOffset >= 0) { @@ -678,296 +671,293 @@ DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, savedOptionPtr) } nullOK = (optionPtr->specPtr->flags & TK_OPTION_NULL_OK); switch (optionPtr->specPtr->type) { - case TK_OPTION_BOOLEAN: { - int new; + case TK_OPTION_BOOLEAN: { + int newBool; - if (Tcl_GetBooleanFromObj(interp, valuePtr, &new) - != TCL_OK) { - return TCL_ERROR; - } - if (internalPtr != NULL) { - *((int *) oldInternalPtr) = *((int *) internalPtr); - *((int *) internalPtr) = new; - } - break; + if (Tcl_GetBooleanFromObj(interp, valuePtr, &newBool) != TCL_OK) { + return TCL_ERROR; } - case TK_OPTION_INT: { - int new; - - if (Tcl_GetIntFromObj(interp, valuePtr, &new) != TCL_OK) { - return TCL_ERROR; - } - if (internalPtr != NULL) { - *((int *) oldInternalPtr) = *((int *) internalPtr); - *((int *) internalPtr) = new; - } - break; + if (internalPtr != NULL) { + *((int *) oldInternalPtr) = *((int *) internalPtr); + *((int *) internalPtr) = newBool; } - case TK_OPTION_DOUBLE: { - double new; - - if (nullOK && ObjectIsEmpty(valuePtr)) { - valuePtr = NULL; - new = 0; - } else { - if (Tcl_GetDoubleFromObj(interp, valuePtr, &new) != TCL_OK) { - return TCL_ERROR; - } - } + break; + } + case TK_OPTION_INT: { + int newInt; - if (internalPtr != NULL) { - *((double *) oldInternalPtr) = *((double *) internalPtr); - *((double *) internalPtr) = new; - } - break; + if (Tcl_GetIntFromObj(interp, valuePtr, &newInt) != TCL_OK) { + return TCL_ERROR; } - case TK_OPTION_STRING: { - char *new, *value; - int length; - - if (nullOK && ObjectIsEmpty(valuePtr)) { - valuePtr = NULL; - } - if (internalPtr != NULL) { - if (valuePtr != NULL) { - value = Tcl_GetStringFromObj(valuePtr, &length); - new = ckalloc((unsigned) (length + 1)); - strcpy(new, value); - } else { - new = NULL; - } - *((char **) oldInternalPtr) = *((char **) internalPtr); - *((char **) internalPtr) = new; - } - break; + if (internalPtr != NULL) { + *((int *) oldInternalPtr) = *((int *) internalPtr); + *((int *) internalPtr) = newInt; } - case TK_OPTION_STRING_TABLE: { - int new; + break; + } + case TK_OPTION_DOUBLE: { + double newDbl; - if (Tcl_GetIndexFromObj(interp, valuePtr, - (CONST char **) optionPtr->specPtr->clientData, - optionPtr->specPtr->optionName+1, 0, &new) != TCL_OK) { + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + newDbl = 0; + } else { + if (Tcl_GetDoubleFromObj(interp, valuePtr, &newDbl) != TCL_OK) { return TCL_ERROR; } - if (internalPtr != NULL) { - *((int *) oldInternalPtr) = *((int *) internalPtr); - *((int *) internalPtr) = new; - } - break; } - case TK_OPTION_COLOR: { - XColor *newPtr; - if (nullOK && ObjectIsEmpty(valuePtr)) { - valuePtr = NULL; - newPtr = NULL; - } else { - newPtr = Tk_AllocColorFromObj(interp, tkwin, valuePtr); - if (newPtr == NULL) { - return TCL_ERROR; - } - } - if (internalPtr != NULL) { - *((XColor **) oldInternalPtr) = *((XColor **) internalPtr); - *((XColor **) internalPtr) = newPtr; - } - break; + if (internalPtr != NULL) { + *((double *) oldInternalPtr) = *((double *) internalPtr); + *((double *) internalPtr) = newDbl; } - case TK_OPTION_FONT: { - Tk_Font new; + break; + } + case TK_OPTION_STRING: { + char *newStr, *value; + int length; - if (nullOK && ObjectIsEmpty(valuePtr)) { - valuePtr = NULL; - new = NULL; + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + } + if (internalPtr != NULL) { + if (valuePtr != NULL) { + value = Tcl_GetStringFromObj(valuePtr, &length); + newStr = ckalloc((unsigned) (length + 1)); + strcpy(newStr, value); } else { - new = Tk_AllocFontFromObj(interp, tkwin, valuePtr); - if (new == NULL) { - return TCL_ERROR; - } - } - if (internalPtr != NULL) { - *((Tk_Font *) oldInternalPtr) = *((Tk_Font *) internalPtr); - *((Tk_Font *) internalPtr) = new; + newStr = NULL; } - break; + *((char **) oldInternalPtr) = *((char **) internalPtr); + *((char **) internalPtr) = newStr; } - case TK_OPTION_STYLE: { - Tk_Style new; + break; + } + case TK_OPTION_STRING_TABLE: { + int newValue; - if (nullOK && ObjectIsEmpty(valuePtr)) { - valuePtr = NULL; - new = NULL; - } else { - new = Tk_AllocStyleFromObj(interp, valuePtr); - if (new == NULL) { - return TCL_ERROR; - } - } - if (internalPtr != NULL) { - *((Tk_Style *) oldInternalPtr) = *((Tk_Style *) internalPtr); - *((Tk_Style *) internalPtr) = new; - } - break; + if (Tcl_GetIndexFromObj(interp, valuePtr, + (CONST char **) optionPtr->specPtr->clientData, + optionPtr->specPtr->optionName+1, 0, &newValue) != TCL_OK) { + return TCL_ERROR; } - case TK_OPTION_BITMAP: { - Pixmap new; + if (internalPtr != NULL) { + *((int *) oldInternalPtr) = *((int *) internalPtr); + *((int *) internalPtr) = newValue; + } + break; + } + case TK_OPTION_COLOR: { + XColor *newPtr; - if (nullOK && ObjectIsEmpty(valuePtr)) { - valuePtr = NULL; - new = None; - } else { - new = Tk_AllocBitmapFromObj(interp, tkwin, valuePtr); - if (new == None) { - return TCL_ERROR; - } - } - if (internalPtr != NULL) { - *((Pixmap *) oldInternalPtr) = *((Pixmap *) internalPtr); - *((Pixmap *) internalPtr) = new; + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + newPtr = NULL; + } else { + newPtr = Tk_AllocColorFromObj(interp, tkwin, valuePtr); + if (newPtr == NULL) { + return TCL_ERROR; } - break; } - case TK_OPTION_BORDER: { - Tk_3DBorder new; + if (internalPtr != NULL) { + *((XColor **) oldInternalPtr) = *((XColor **) internalPtr); + *((XColor **) internalPtr) = newPtr; + } + break; + } + case TK_OPTION_FONT: { + Tk_Font newFont; - if (nullOK && ObjectIsEmpty(valuePtr)) { - valuePtr = NULL; - new = NULL; - } else { - new = Tk_Alloc3DBorderFromObj(interp, tkwin, valuePtr); - if (new == NULL) { - return TCL_ERROR; - } - } - if (internalPtr != NULL) { - *((Tk_3DBorder *) oldInternalPtr) = - *((Tk_3DBorder *) internalPtr); - *((Tk_3DBorder *) internalPtr) = new; + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + newFont = NULL; + } else { + newFont = Tk_AllocFontFromObj(interp, tkwin, valuePtr); + if (newFont == NULL) { + return TCL_ERROR; } - break; } - case TK_OPTION_RELIEF: { - int new; + if (internalPtr != NULL) { + *((Tk_Font *) oldInternalPtr) = *((Tk_Font *) internalPtr); + *((Tk_Font *) internalPtr) = newFont; + } + break; + } + case TK_OPTION_STYLE: { + Tk_Style newStyle; - if (nullOK && ObjectIsEmpty(valuePtr)) { - valuePtr = NULL; - new = TK_RELIEF_NULL; - } else { - if (Tk_GetReliefFromObj(interp, valuePtr, &new) != TCL_OK) { - return TCL_ERROR; - } - } - if (internalPtr != NULL) { - *((int *) oldInternalPtr) = *((int *) internalPtr); - *((int *) internalPtr) = new; + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + newStyle = NULL; + } else { + newStyle = Tk_AllocStyleFromObj(interp, valuePtr); + if (newStyle == NULL) { + return TCL_ERROR; } - break; } - case TK_OPTION_CURSOR: { - Tk_Cursor new; + if (internalPtr != NULL) { + *((Tk_Style *) oldInternalPtr) = *((Tk_Style *) internalPtr); + *((Tk_Style *) internalPtr) = newStyle; + } + break; + } + case TK_OPTION_BITMAP: { + Pixmap newBitmap; - if (nullOK && ObjectIsEmpty(valuePtr)) { - new = None; - valuePtr = NULL; - } else { - new = Tk_AllocCursorFromObj(interp, tkwin, valuePtr); - if (new == None) { - return TCL_ERROR; - } - } - if (internalPtr != NULL) { - *((Tk_Cursor *) oldInternalPtr) = *((Tk_Cursor *) internalPtr); - *((Tk_Cursor *) internalPtr) = new; + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + newBitmap = None; + } else { + newBitmap = Tk_AllocBitmapFromObj(interp, tkwin, valuePtr); + if (newBitmap == None) { + return TCL_ERROR; } - Tk_DefineCursor(tkwin, new); - break; } - case TK_OPTION_JUSTIFY: { - Tk_Justify new; + if (internalPtr != NULL) { + *((Pixmap *) oldInternalPtr) = *((Pixmap *) internalPtr); + *((Pixmap *) internalPtr) = newBitmap; + } + break; + } + case TK_OPTION_BORDER: { + Tk_3DBorder newBorder; - if (Tk_GetJustifyFromObj(interp, valuePtr, &new) != TCL_OK) { + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + newBorder = NULL; + } else { + newBorder = Tk_Alloc3DBorderFromObj(interp, tkwin, valuePtr); + if (newBorder == NULL) { return TCL_ERROR; } - if (internalPtr != NULL) { - *((Tk_Justify *) oldInternalPtr) - = *((Tk_Justify *) internalPtr); - *((Tk_Justify *) internalPtr) = new; - } - break; } - case TK_OPTION_ANCHOR: { - Tk_Anchor new; + if (internalPtr != NULL) { + *((Tk_3DBorder *) oldInternalPtr) = *((Tk_3DBorder *) internalPtr); + *((Tk_3DBorder *) internalPtr) = newBorder; + } + break; + } + case TK_OPTION_RELIEF: { + int newRelief; - if (Tk_GetAnchorFromObj(interp, valuePtr, &new) != TCL_OK) { + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + newRelief = TK_RELIEF_NULL; + } else { + if (Tk_GetReliefFromObj(interp, valuePtr, &newRelief) != TCL_OK) { return TCL_ERROR; } - if (internalPtr != NULL) { - *((Tk_Anchor *) oldInternalPtr) - = *((Tk_Anchor *) internalPtr); - *((Tk_Anchor *) internalPtr) = new; - } - break; } - case TK_OPTION_PIXELS: { - int new; + if (internalPtr != NULL) { + *((int *) oldInternalPtr) = *((int *) internalPtr); + *((int *) internalPtr) = newRelief; + } + break; + } + case TK_OPTION_CURSOR: { + Tk_Cursor newCursor; - if (nullOK && ObjectIsEmpty(valuePtr)) { - valuePtr = NULL; - new = 0; - } else { - if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, - &new) != TCL_OK) { - return TCL_ERROR; - } - } - if (internalPtr != NULL) { - *((int *) oldInternalPtr) = *((int *) internalPtr); - *((int *) internalPtr) = new; + if (nullOK && ObjectIsEmpty(valuePtr)) { + newCursor = None; + valuePtr = NULL; + } else { + newCursor = Tk_AllocCursorFromObj(interp, tkwin, valuePtr); + if (newCursor == None) { + return TCL_ERROR; } - break; } - case TK_OPTION_WINDOW: { - Tk_Window new; + if (internalPtr != NULL) { + *((Tk_Cursor *) oldInternalPtr) = *((Tk_Cursor *) internalPtr); + *((Tk_Cursor *) internalPtr) = newCursor; + } + Tk_DefineCursor(tkwin, newCursor); + break; + } + case TK_OPTION_JUSTIFY: { + Tk_Justify newJustify; - if (nullOK && ObjectIsEmpty(valuePtr)) { - valuePtr = NULL; - new = None; - } else { - if (TkGetWindowFromObj(interp, tkwin, valuePtr, &new) - != TCL_OK) { - return TCL_ERROR; - } - } - if (internalPtr != NULL) { - *((Tk_Window *) oldInternalPtr) = *((Tk_Window *) internalPtr); - *((Tk_Window *) internalPtr) = new; + if (Tk_GetJustifyFromObj(interp, valuePtr, &newJustify) != TCL_OK) { + return TCL_ERROR; + } + if (internalPtr != NULL) { + *((Tk_Justify *) oldInternalPtr) = *((Tk_Justify *) internalPtr); + *((Tk_Justify *) internalPtr) = newJustify; + } + break; + } + case TK_OPTION_ANCHOR: { + Tk_Anchor newAnchor; + + if (Tk_GetAnchorFromObj(interp, valuePtr, &newAnchor) != TCL_OK) { + return TCL_ERROR; + } + if (internalPtr != NULL) { + *((Tk_Anchor *) oldInternalPtr) = *((Tk_Anchor *) internalPtr); + *((Tk_Anchor *) internalPtr) = newAnchor; + } + break; + } + case TK_OPTION_PIXELS: { + int newPixels; + + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + newPixels = 0; + } else { + if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr, + &newPixels) != TCL_OK) { + return TCL_ERROR; } - break; } - case TK_OPTION_CUSTOM: { - Tk_ObjCustomOption *custom = optionPtr->extra.custom; - if (custom->setProc(custom->clientData, interp, tkwin, - &valuePtr, recordPtr, optionPtr->specPtr->internalOffset, - (char *)oldInternalPtr, - optionPtr->specPtr->flags) != TCL_OK) { + if (internalPtr != NULL) { + *((int *) oldInternalPtr) = *((int *) internalPtr); + *((int *) internalPtr) = newPixels; + } + break; + } + case TK_OPTION_WINDOW: { + Tk_Window newWin; + + if (nullOK && ObjectIsEmpty(valuePtr)) { + valuePtr = NULL; + newWin = None; + } else { + if (TkGetWindowFromObj(interp, tkwin, valuePtr, + &newWin) != TCL_OK) { return TCL_ERROR; } - break; } - - default: { - char buf[40+TCL_INTEGER_SPACE]; - sprintf(buf, "bad config table: unknown type %d", - optionPtr->specPtr->type); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + if (internalPtr != NULL) { + *((Tk_Window *) oldInternalPtr) = *((Tk_Window *) internalPtr); + *((Tk_Window *) internalPtr) = newWin; + } + break; + } + case TK_OPTION_CUSTOM: { + Tk_ObjCustomOption *custom = optionPtr->extra.custom; + + if (custom->setProc(custom->clientData, interp, tkwin, + &valuePtr, recordPtr, optionPtr->specPtr->internalOffset, + (char *)oldInternalPtr, optionPtr->specPtr->flags) != TCL_OK) { return TCL_ERROR; } + break; + } + + { + char buf[40+TCL_INTEGER_SPACE]; + + default: + sprintf(buf, "bad config table: unknown type %d", + optionPtr->specPtr->type); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + return TCL_ERROR; + } } /* - * Release resources associated with the old value, if we're not - * returning it to the caller, then install the new object value into - * the record. + * Release resources associated with the old value, if we're not returning + * it to the caller, then install the new object value into the record. */ if (savedOptionPtr == NULL) { @@ -992,12 +982,11 @@ DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, savedOptionPtr) * * ObjectIsEmpty -- * - * This procedure tests whether the string value of an object is - * empty. + * This function tests whether the string value of an object is empty. * * Results: - * The return value is 1 if the string value of objPtr has length - * zero, and 0 otherwise. + * The return value is 1 if the string value of objPtr has length zero, + * and 0 otherwise. * * Side effects: * None. @@ -1007,7 +996,7 @@ DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin, savedOptionPtr) static int ObjectIsEmpty(objPtr) - Tcl_Obj *objPtr; /* Object to test. May be NULL. */ + Tcl_Obj *objPtr; /* Object to test. May be NULL. */ { int length; @@ -1026,15 +1015,14 @@ ObjectIsEmpty(objPtr) * * GetOption -- * - * This procedure searches through a chained option table to find - * the entry for a particular option name. + * This function searches through a chained option table to find the + * entry for a particular option name. * * Results: - * The return value is a pointer to the matching entry, or NULL - * if no matching entry could be found. - * Note: if the matching entry is a synonym then this procedure - * returns a pointer to the synonym entry, *not* the "real" entry - * that the synonym refers to. + * The return value is a pointer to the matching entry, or NULL if no + * matching entry could be found. Note: if the matching entry is a + * synonym then this function returns a pointer to the synonym entry, + * *not* the "real" entry that the synonym refers to. * * Side effects: * None. @@ -1044,8 +1032,8 @@ ObjectIsEmpty(objPtr) static Option * GetOption(name, tablePtr) - CONST char *name; /* String balue to be looked up in the - * option table. */ + CONST char *name; /* String balue to be looked up in the option + * table. */ OptionTable *tablePtr; /* Table in which to look up name. */ { Option *bestPtr, *optionPtr; @@ -1054,14 +1042,13 @@ GetOption(name, tablePtr) int count; /* - * Search through all of the option tables in the chain to find the - * best match. Some tricky aspects: + * Search through all of the option tables in the chain to find the best + * match. Some tricky aspects: * * 1. We have to accept unique abbreviations. - * 2. The same name could appear in different tables in the chain. - * If this happens, we use the entry from the first table. We - * have to be careful to distinguish this case from an ambiguous - * abbreviation. + * 2. The same name could appear in different tables in the chain. If this + * happens, we use the entry from the first table. We have to be + * careful to distinguish this case from an ambiguous abbreviation. */ bestPtr = NULL; @@ -1073,40 +1060,38 @@ GetOption(name, tablePtr) *p1 == *p2; p1++, p2++) { if (*p1 == 0) { /* - * This is an exact match. We're done. + * This is an exact match. We're done. */ - bestPtr = optionPtr; - goto done; + return optionPtr; } } if (*p1 == 0) { /* - * The name is an abbreviation for this option. Keep - * to make sure that the abbreviation only matches one - * option name. If we've already found a match in the - * past, then it is an error unless the full names for - * the two options are identical; in this case, the first - * option overrides the second. + * The name is an abbreviation for this option. Keep to make + * sure that the abbreviation only matches one option name. + * If we've already found a match in the past, then it is an + * error unless the full names for the two options are + * identical; in this case, the first option overrides the + * second. */ if (bestPtr == NULL) { bestPtr = optionPtr; - } else { - if (strcmp(bestPtr->specPtr->optionName, - optionPtr->specPtr->optionName) != 0) { - goto error; - } + } else if (strcmp(bestPtr->specPtr->optionName, + optionPtr->specPtr->optionName) != 0) { + return NULL; } } } } - done: - return bestPtr; + /* + * Return whatever we have found, which could be NULL if nothing + * matched. The multiple-matching case is handled above. + */ - error: - return NULL; + return bestPtr; } /* @@ -1114,32 +1099,30 @@ GetOption(name, tablePtr) * * GetOptionFromObj -- * - * This procedure searches through a chained option table to find - * the entry for a particular option name. + * This function searches through a chained option table to find the + * entry for a particular option name. * * Results: - * The return value is a pointer to the matching entry, or NULL - * if no matching entry could be found. If NULL is returned and - * interp is not NULL than an error message is left in its result. - * Note: if the matching entry is a synonym then this procedure - * returns a pointer to the synonym entry, *not* the "real" entry - * that the synonym refers to. + * The return value is a pointer to the matching entry, or NULL if no + * matching entry could be found. If NULL is returned and interp is not + * NULL than an error message is left in its result. Note: if the + * matching entry is a synonym then this function returns a pointer to + * the synonym entry, *not* the "real" entry that the synonym refers to. * * Side effects: - * Information about the matching entry is cached in the object - * containing the name, so that future lookups can proceed more - * quickly. + * Information about the matching entry is cached in the object + * containing the name, so that future lookups can proceed more quickly. * *---------------------------------------------------------------------- */ static Option * GetOptionFromObj(interp, objPtr, tablePtr) - Tcl_Interp *interp; /* Used only for error reporting; if NULL - * no message is left after an error. */ - Tcl_Obj *objPtr; /* Object whose string value is to be - * looked up in the option table. */ - OptionTable *tablePtr; /* Table in which to look up objPtr. */ + Tcl_Interp *interp; /* Used only for error reporting; if NULL no + * message is left after an error. */ + Tcl_Obj *objPtr; /* Object whose string value is to be looked + * up in the option table. */ + OptionTable *tablePtr; /* Table in which to look up objPtr. */ { Option *bestPtr; char *name; @@ -1149,16 +1132,16 @@ GetOptionFromObj(interp, objPtr, tablePtr) */ if (objPtr->typePtr == &tkOptionObjType) { - if (objPtr->internalRep.twoPtrValue.ptr1 == (VOID *) tablePtr) { - return (Option *) objPtr->internalRep.twoPtrValue.ptr2; - } + if (objPtr->internalRep.twoPtrValue.ptr1 == (VOID *) tablePtr) { + return (Option *) objPtr->internalRep.twoPtrValue.ptr2; + } } /* * The answer isn't cached. */ - name = Tcl_GetStringFromObj(objPtr, (int *) NULL); + name = Tcl_GetString(objPtr); bestPtr = GetOption(name, tablePtr); if (bestPtr == NULL) { goto error; @@ -1173,10 +1156,9 @@ GetOptionFromObj(interp, objPtr, tablePtr) objPtr->typePtr = &tkOptionObjType; return bestPtr; - error: + error: if (interp != NULL) { - Tcl_AppendResult(interp, "unknown option \"", name, - "\"", (char *) NULL); + Tcl_AppendResult(interp, "unknown option \"",name,"\"", (char *) NULL); } return NULL; } @@ -1186,29 +1168,28 @@ GetOptionFromObj(interp, objPtr, tablePtr) * * TkGetOptionSpec -- * - * This procedure searches through a chained option table to find - * the option spec for a particular option name. + * This function searches through a chained option table to find the + * option spec for a particular option name. * * Results: - * The return value is a pointer to the option spec of the matching - * entry, or NULL if no matching entry could be found. - * Note: if the matching entry is a synonym then this procedure - * returns a pointer to the option spec of the synonym entry, *not* - * the "real" entry that the synonym refers to. - * Note: this call is primarily used by the style management code - * (tkStyle.c) to look up an element's option spec into a widget's - * option table. + * The return value is a pointer to the option spec of the matching + * entry, or NULL if no matching entry could be found. Note: if the + * matching entry is a synonym then this function returns a pointer to + * the option spec of the synonym entry, *not* the "real" entry that the + * synonym refers to. Note: this call is primarily used by the style + * management code (tkStyle.c) to look up an element's option spec into a + * widget's option table. * * Side effects: - * None. + * None. * *---------------------------------------------------------------------- */ CONST Tk_OptionSpec * TkGetOptionSpec(name, optionTable) - CONST char *name; /* String value to be looked up. */ - Tk_OptionTable optionTable; /* Table in which to look up name. */ + CONST char *name; /* String value to be looked up. */ + Tk_OptionTable optionTable; /* Table in which to look up name. */ { Option *optionPtr; @@ -1224,14 +1205,14 @@ TkGetOptionSpec(name, optionTable) * * SetOptionFromAny -- * - * This procedure is called to convert a Tcl object to option - * internal form. However, this doesn't make sense (need to have a - * table of options in order to do the conversion) so the - * procedure always generates an error. + * This function is called to convert a Tcl object to option internal + * form. However, this doesn't make sense (need to have a table of + * options in order to do the conversion) so the function always + * generates an error. * * Results: - * The return value is always TCL_ERROR, and an error message is - * left in interp's result if interp isn't NULL. + * The return value is always TCL_ERROR, and an error message is left in + * interp's result if interp isn't NULL. * * Side effects: * None. @@ -1255,24 +1236,23 @@ SetOptionFromAny(interp, objPtr) * * Tk_SetOptions -- * - * Process one or more name-value pairs for configuration options - * and fill in fields of a record with new values. + * Process one or more name-value pairs for configuration options and + * fill in fields of a record with new values. * * Results: - * If all goes well then TCL_OK is returned and the old values of - * any modified objects are saved in *savePtr, if it isn't NULL (the - * caller must eventually call Tk_RestoreSavedOptions or - * Tk_FreeSavedOptions to free the contents of *savePtr). In - * addition, if maskPtr isn't NULL then *maskPtr is filled in with - * the OR of the typeMask bits from all modified options. If an - * error occurs then TCL_ERROR is returned and a message - * is left in interp's result unless interp is NULL; nothing is + * If all goes well then TCL_OK is returned and the old values of any + * modified objects are saved in *savePtr, if it isn't NULL (the caller + * must eventually call Tk_RestoreSavedOptions or Tk_FreeSavedOptions to + * free the contents of *savePtr). In addition, if maskPtr isn't NULL + * then *maskPtr is filled in with the OR of the typeMask bits from all + * modified options. If an error occurs then TCL_ERROR is returned and a + * message is left in interp's result unless interp is NULL; nothing is * saved in *savePtr or *maskPtr in this case. * * Side effects: - * The fields of recordPtr get filled in with object pointers - * from objc/objv. Old information in widgRec's fields gets - * recycled. Information may be left at *savePtr. + * The fields of recordPtr get filled in with object pointers from + * objc/objv. Old information in widgRec's fields gets recycled. + * Information may be left at *savePtr. * *-------------------------------------------------------------- */ @@ -1280,28 +1260,24 @@ SetOptionFromAny(interp, objPtr) int Tk_SetOptions(interp, recordPtr, optionTable, objc, objv, tkwin, savePtr, maskPtr) - Tcl_Interp *interp; /* Interpreter for error reporting. - * If NULL, then no error message is - * returned.*/ - char *recordPtr; /* The record to configure. */ - Tk_OptionTable optionTable; /* Describes valid options. */ - int objc; /* The number of elements in objv. */ - Tcl_Obj *CONST objv[]; /* Contains one or more name-value - * pairs. */ - Tk_Window tkwin; /* Window associated with the thing - * being configured; needed for some - * options (such as colors). */ - Tk_SavedOptions *savePtr; /* If non-NULL, the old values of - * modified options are saved here - * so that they can be restored - * after an error. */ - int *maskPtr; /* It non-NULL, this word is modified - * on a successful return to hold the - * bit-wise OR of the typeMask fields - * of all options that were modified - * by this call. Used by the caller - * to figure out which options - * actually changed. */ + Tcl_Interp *interp; /* Interpreter for error reporting. If NULL, + * then no error message is returned.*/ + char *recordPtr; /* The record to configure. */ + Tk_OptionTable optionTable; /* Describes valid options. */ + int objc; /* The number of elements in objv. */ + Tcl_Obj *CONST objv[]; /* Contains one or more name-value pairs. */ + Tk_Window tkwin; /* Window associated with the thing being + * configured; needed for some options (such + * as colors). */ + Tk_SavedOptions *savePtr; /* If non-NULL, the old values of modified + * options are saved here so that they can be + * restored after an error. */ + int *maskPtr; /* It non-NULL, this word is modified on a + * successful return to hold the bit-wise OR + * of the typeMask fields of all options that + * were modified by this call. Used by the + * caller to figure out which options actually + * changed. */ { OptionTable *tablePtr = (OptionTable *) optionTable; Option *optionPtr; @@ -1317,8 +1293,8 @@ Tk_SetOptions(interp, recordPtr, optionTable, objc, objv, tkwin, savePtr, lastSavePtr = savePtr; /* - * Scan through all of the arguments, processing those - * that match entries in the option table. + * Scan through all of the arguments, processing those that match entries + * in the option table. */ mask = 0; @@ -1342,12 +1318,11 @@ Tk_SetOptions(interp, recordPtr, optionTable, objc, objv, tkwin, savePtr, if ((savePtr != NULL) && (lastSavePtr->numItems >= TK_NUM_SAVED_OPTIONS)) { /* - * We've run out of space for saving old option values. Allocate + * We've run out of space for saving old option values. Allocate * more space. */ - newSavePtr = (Tk_SavedOptions *) ckalloc(sizeof( - Tk_SavedOptions)); + newSavePtr = (Tk_SavedOptions *) ckalloc(sizeof(Tk_SavedOptions)); newSavePtr->recordPtr = recordPtr; newSavePtr->tkwin = tkwin; newSavePtr->numItems = 0; @@ -1375,7 +1350,7 @@ Tk_SetOptions(interp, recordPtr, optionTable, objc, objv, tkwin, savePtr, } return TCL_OK; - error: + error: if (savePtr != NULL) { Tk_RestoreSavedOptions(savePtr); } @@ -1387,38 +1362,38 @@ Tk_SetOptions(interp, recordPtr, optionTable, objc, objv, tkwin, savePtr, * * Tk_RestoreSavedOptions -- * - * This procedure undoes the effect of a previous call to - * Tk_SetOptions by restoring all of the options to their value - * before the call to Tk_SetOptions. + * This function undoes the effect of a previous call to Tk_SetOptions by + * restoring all of the options to their value before the call to + * Tk_SetOptions. * * Results: * None. * * Side effects: - * The configutation record is restored and all the information - * stored in savePtr is freed. + * The configutation record is restored and all the information stored in + * savePtr is freed. * *---------------------------------------------------------------------- */ void Tk_RestoreSavedOptions(savePtr) - Tk_SavedOptions *savePtr; /* Holds saved option information; must - * have been passed to Tk_SetOptions. */ + Tk_SavedOptions *savePtr; /* Holds saved option information; must have + * been passed to Tk_SetOptions. */ { int i; Option *optionPtr; Tcl_Obj *newPtr; /* New object value of option, which we - * replace with old value and free. Taken - * from record. */ + * replace with old value and free. Taken from + * record. */ char *internalPtr; /* Points to internal value of option in * record. */ CONST Tk_OptionSpec *specPtr; /* - * Be sure to restore the options in the opposite order they were - * set. This is important because it's possible that the same - * option name was used twice in a single call to Tk_SetOptions. + * Be sure to restore the options in the opposite order they were set. + * This is important because it's possible that the same option name was + * used twice in a single call to Tk_SetOptions. */ if (savePtr->nextPtr != NULL) { @@ -1431,8 +1406,8 @@ Tk_RestoreSavedOptions(savePtr) specPtr = optionPtr->specPtr; /* - * First free the new value of the option, which is currently - * in the record. + * First free the new value of the option, which is currently in the + * record. */ if (specPtr->objOffset >= 0) { @@ -1462,100 +1437,83 @@ Tk_RestoreSavedOptions(savePtr) } if (specPtr->internalOffset >= 0) { switch (specPtr->type) { - case TK_OPTION_BOOLEAN: { - *((int *) internalPtr) - = *((int *) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_INT: { - *((int *) internalPtr) - = *((int *) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_DOUBLE: { - *((double *) internalPtr) - = *((double *) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_STRING: { - *((char **) internalPtr) - = *((char **) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_STRING_TABLE: { - *((int *) internalPtr) - = *((int *) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_COLOR: { - *((XColor **) internalPtr) - = *((XColor **) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_FONT: { - *((Tk_Font *) internalPtr) - = *((Tk_Font *) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_STYLE: { - *((Tk_Style *) internalPtr) - = *((Tk_Style *) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_BITMAP: { - *((Pixmap *) internalPtr) - = *((Pixmap *) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_BORDER: { - *((Tk_3DBorder *) internalPtr) - = *((Tk_3DBorder *) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_RELIEF: { - *((int *) internalPtr) - = *((int *) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_CURSOR: { - *((Tk_Cursor *) internalPtr) - = *((Tk_Cursor *) &savePtr->items[i].internalForm); - Tk_DefineCursor(savePtr->tkwin, - *((Tk_Cursor *) internalPtr)); - break; - } - case TK_OPTION_JUSTIFY: { - *((Tk_Justify *) internalPtr) - = *((Tk_Justify *) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_ANCHOR: { - *((Tk_Anchor *) internalPtr) - = *((Tk_Anchor *) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_PIXELS: { - *((int *) internalPtr) - = *((int *) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_WINDOW: { - *((Tk_Window *) internalPtr) - = *((Tk_Window *) &savePtr->items[i].internalForm); - break; - } - case TK_OPTION_CUSTOM: { - Tk_ObjCustomOption *custom = optionPtr->extra.custom; - if (custom->restoreProc != NULL) { - custom->restoreProc(custom->clientData, savePtr->tkwin, - internalPtr, - (char *)&savePtr->items[i].internalForm); - } - break; - } - default: { - Tcl_Panic("bad option type in Tk_RestoreSavedOptions"); + case TK_OPTION_BOOLEAN: + *((int *) internalPtr) = + *((int *) &savePtr->items[i].internalForm); + break; + case TK_OPTION_INT: + *((int *) internalPtr) = + *((int *) &savePtr->items[i].internalForm); + break; + case TK_OPTION_DOUBLE: + *((double *) internalPtr) = + *((double *) &savePtr->items[i].internalForm); + break; + case TK_OPTION_STRING: + *((char **) internalPtr) = + *((char **) &savePtr->items[i].internalForm); + break; + case TK_OPTION_STRING_TABLE: + *((int *) internalPtr) = + *((int *) &savePtr->items[i].internalForm); + break; + case TK_OPTION_COLOR: + *((XColor **) internalPtr) = + *((XColor **) &savePtr->items[i].internalForm); + break; + case TK_OPTION_FONT: + *((Tk_Font *) internalPtr) = + *((Tk_Font *) &savePtr->items[i].internalForm); + break; + case TK_OPTION_STYLE: + *((Tk_Style *) internalPtr) = + *((Tk_Style *) &savePtr->items[i].internalForm); + break; + case TK_OPTION_BITMAP: + *((Pixmap *) internalPtr) = + *((Pixmap *) &savePtr->items[i].internalForm); + break; + case TK_OPTION_BORDER: + *((Tk_3DBorder *) internalPtr) = + *((Tk_3DBorder *) &savePtr->items[i].internalForm); + break; + case TK_OPTION_RELIEF: + *((int *) internalPtr) = + *((int *) &savePtr->items[i].internalForm); + break; + case TK_OPTION_CURSOR: + *((Tk_Cursor *) internalPtr) = + *((Tk_Cursor *) &savePtr->items[i].internalForm); + Tk_DefineCursor(savePtr->tkwin, *((Tk_Cursor *) internalPtr)); + break; + case TK_OPTION_JUSTIFY: + *((Tk_Justify *) internalPtr) = + *((Tk_Justify *) &savePtr->items[i].internalForm); + break; + case TK_OPTION_ANCHOR: + *((Tk_Anchor *) internalPtr) = + *((Tk_Anchor *) &savePtr->items[i].internalForm); + break; + case TK_OPTION_PIXELS: + *((int *) internalPtr) = + *((int *) &savePtr->items[i].internalForm); + break; + case TK_OPTION_WINDOW: + *((Tk_Window *) internalPtr) = + *((Tk_Window *) &savePtr->items[i].internalForm); + break; + case TK_OPTION_CUSTOM: { + Tk_ObjCustomOption *custom = optionPtr->extra.custom; + + if (custom->restoreProc != NULL) { + custom->restoreProc(custom->clientData, + savePtr->tkwin, internalPtr, + (char *)&savePtr->items[i].internalForm); } + break; + } + default: + Tcl_Panic("bad option type in Tk_RestoreSavedOptions"); } } } @@ -1567,8 +1525,8 @@ Tk_RestoreSavedOptions(savePtr) * * Tk_FreeSavedOptions -- * - * Free all of the saved configuration option values from a - * previous call to Tk_SetOptions. + * Free all of the saved configuration option values from a previous call + * to Tk_SetOptions. * * Results: * None. @@ -1581,8 +1539,8 @@ Tk_RestoreSavedOptions(savePtr) void Tk_FreeSavedOptions(savePtr) - Tk_SavedOptions *savePtr; /* Contains options saved in a previous - * call to Tk_SetOptions. */ + Tk_SavedOptions *savePtr; /* Contains options saved in a previous call + * to Tk_SetOptions. */ { int count; Tk_SavedOption *savedOptionPtr; @@ -1615,8 +1573,8 @@ Tk_FreeSavedOptions(savePtr) * None. * * Side effects: - * All of the Tcl_Obj's in recordPtr that are controlled by - * configuration options in optionTable are freed. + * All of the Tcl_Obj's in recordPtr that are controlled by configuration + * options in optionTable are freed. * *---------------------------------------------------------------------- */ @@ -1624,8 +1582,8 @@ Tk_FreeSavedOptions(savePtr) /* ARGSUSED */ void Tk_FreeConfigOptions(recordPtr, optionTable, tkwin) - char *recordPtr; /* Record whose fields contain current - * values for options. */ + char *recordPtr; /* Record whose fields contain current values + * for options. */ Tk_OptionTable optionTable; /* Describes legal options. */ Tk_Window tkwin; /* Window associated with recordPtr; needed * for freeing some options. */ @@ -1633,7 +1591,7 @@ Tk_FreeConfigOptions(recordPtr, optionTable, tkwin) OptionTable *tablePtr; Option *optionPtr; int count; - Tcl_Obj **oldPtrPtr, *oldPtr; + Tcl_Obj **oldPtrPtr, *oldPtr; char *oldInternalPtr; CONST Tk_OptionSpec *specPtr; @@ -1672,14 +1630,14 @@ Tk_FreeConfigOptions(recordPtr, optionTable, tkwin) * * FreeResources -- * - * Free system resources associated with a configuration option, - * such as colors or fonts. + * Free system resources associated with a configuration option, such as + * colors or fonts. * * Results: * None. * * Side effects: - * Any system resources associated with objPtr are released. However, + * Any system resources associated with objPtr are released. However, * objPtr itself is not freed. * *---------------------------------------------------------------------- @@ -1692,7 +1650,7 @@ FreeResources(optionPtr, objPtr, internalPtr, tkwin) * as an object. */ char *internalPtr; /* A pointer to an internal representation for * the option's value, such as an int or - * (XColor *). Only valid if + * (XColor *). Only valid if * optionPtr->specPtr->internalOffset >= 0. */ Tk_Window tkwin; /* The window in which this option is used. */ { @@ -1700,86 +1658,85 @@ FreeResources(optionPtr, objPtr, internalPtr, tkwin) /* * If there exists an internal form for the value, use it to free - * resources (also zero out the internal form). If there is no - * internal form, then use the object form. + * resources (also zero out the internal form). If there is no internal + * form, then use the object form. */ internalFormExists = optionPtr->specPtr->internalOffset >= 0; switch (optionPtr->specPtr->type) { - case TK_OPTION_STRING: - if (internalFormExists) { - if (*((char **) internalPtr) != NULL) { - ckfree(*((char **) internalPtr)); - *((char **) internalPtr) = NULL; - } - } - break; - case TK_OPTION_COLOR: - if (internalFormExists) { - if (*((XColor **) internalPtr) != NULL) { - Tk_FreeColor(*((XColor **) internalPtr)); - *((XColor **) internalPtr) = NULL; - } - } else if (objPtr != NULL) { - Tk_FreeColorFromObj(tkwin, objPtr); - } - break; - case TK_OPTION_FONT: - if (internalFormExists) { - Tk_FreeFont(*((Tk_Font *) internalPtr)); - *((Tk_Font *) internalPtr) = NULL; - } else if (objPtr != NULL) { - Tk_FreeFontFromObj(tkwin, objPtr); - } - break; - case TK_OPTION_STYLE: - if (internalFormExists) { - Tk_FreeStyle(*((Tk_Style *) internalPtr)); - *((Tk_Style *) internalPtr) = NULL; - } else if (objPtr != NULL) { - Tk_FreeStyleFromObj(objPtr); - } - break; - case TK_OPTION_BITMAP: - if (internalFormExists) { - if (*((Pixmap *) internalPtr) != None) { - Tk_FreeBitmap(Tk_Display(tkwin), *((Pixmap *) internalPtr)); - *((Pixmap *) internalPtr) = None; - } - } else if (objPtr != NULL) { - Tk_FreeBitmapFromObj(tkwin, objPtr); - } - break; - case TK_OPTION_BORDER: - if (internalFormExists) { - if (*((Tk_3DBorder *) internalPtr) != NULL) { - Tk_Free3DBorder(*((Tk_3DBorder *) internalPtr)); - *((Tk_3DBorder *) internalPtr) = NULL; - } - } else if (objPtr != NULL) { - Tk_Free3DBorderFromObj(tkwin, objPtr); - } - break; - case TK_OPTION_CURSOR: - if (internalFormExists) { - if (*((Tk_Cursor *) internalPtr) != None) { - Tk_FreeCursor(Tk_Display(tkwin), - *((Tk_Cursor *) internalPtr)); - *((Tk_Cursor *) internalPtr) = None; - } - } else if (objPtr != NULL) { - Tk_FreeCursorFromObj(tkwin, objPtr); - } - break; - case TK_OPTION_CUSTOM: { - Tk_ObjCustomOption *custom = optionPtr->extra.custom; - if (internalFormExists && custom->freeProc != NULL) { - custom->freeProc(custom->clientData, tkwin, internalPtr); - } - break; - } - default: - break; + case TK_OPTION_STRING: + if (internalFormExists) { + if (*((char **) internalPtr) != NULL) { + ckfree(*((char **) internalPtr)); + *((char **) internalPtr) = NULL; + } + } + break; + case TK_OPTION_COLOR: + if (internalFormExists) { + if (*((XColor **) internalPtr) != NULL) { + Tk_FreeColor(*((XColor **) internalPtr)); + *((XColor **) internalPtr) = NULL; + } + } else if (objPtr != NULL) { + Tk_FreeColorFromObj(tkwin, objPtr); + } + break; + case TK_OPTION_FONT: + if (internalFormExists) { + Tk_FreeFont(*((Tk_Font *) internalPtr)); + *((Tk_Font *) internalPtr) = NULL; + } else if (objPtr != NULL) { + Tk_FreeFontFromObj(tkwin, objPtr); + } + break; + case TK_OPTION_STYLE: + if (internalFormExists) { + Tk_FreeStyle(*((Tk_Style *) internalPtr)); + *((Tk_Style *) internalPtr) = NULL; + } else if (objPtr != NULL) { + Tk_FreeStyleFromObj(objPtr); + } + break; + case TK_OPTION_BITMAP: + if (internalFormExists) { + if (*((Pixmap *) internalPtr) != None) { + Tk_FreeBitmap(Tk_Display(tkwin), *((Pixmap *) internalPtr)); + *((Pixmap *) internalPtr) = None; + } + } else if (objPtr != NULL) { + Tk_FreeBitmapFromObj(tkwin, objPtr); + } + break; + case TK_OPTION_BORDER: + if (internalFormExists) { + if (*((Tk_3DBorder *) internalPtr) != NULL) { + Tk_Free3DBorder(*((Tk_3DBorder *) internalPtr)); + *((Tk_3DBorder *) internalPtr) = NULL; + } + } else if (objPtr != NULL) { + Tk_Free3DBorderFromObj(tkwin, objPtr); + } + break; + case TK_OPTION_CURSOR: + if (internalFormExists) { + if (*((Tk_Cursor *) internalPtr) != None) { + Tk_FreeCursor(Tk_Display(tkwin), *((Tk_Cursor *) internalPtr)); + *((Tk_Cursor *) internalPtr) = None; + } + } else if (objPtr != NULL) { + Tk_FreeCursorFromObj(tkwin, objPtr); + } + break; + case TK_OPTION_CUSTOM: { + Tk_ObjCustomOption *custom = optionPtr->extra.custom; + if (internalFormExists && custom->freeProc != NULL) { + custom->freeProc(custom->clientData, tkwin, internalPtr); + } + break; + } + default: + break; } } @@ -1788,23 +1745,21 @@ FreeResources(optionPtr, objPtr, internalPtr, tkwin) * * Tk_GetOptionInfo -- * - * Returns a list object containing complete information about - * either a single option or all the configuration options in a - * table. + * Returns a list object containing complete information about either a + * single option or all the configuration options in a table. * * Results: - * This procedure normally returns a pointer to an object. - * If namePtr isn't NULL, then the result object is a list with - * five elements: the option's name, its database name, database - * class, default value, and current value. If the option is a - * synonym then the list will contain only two values: the option - * name and the name of the option it refers to. If namePtr is - * NULL, then information is returned for every option in the - * option table: the result will have one sub-list (in the form - * described above) for each option in the table. If an error - * occurs (e.g. because namePtr isn't valid) then NULL is returned - * and an error message will be left in interp's result unless - * interp is NULL. + + * This function normally returns a pointer to an object. If namePtr + * isn't NULL, then the result object is a list with five elements: the + * option's name, its database name, database class, default value, and + * current value. If the option is a synonym then the list will contain + * only two values: the option name and the name of the option it refers + * to. If namePtr is NULL, then information is returned for every option + * in the option table: the result will have one sub-list (in the form + * described above) for each option in the table. If an error occurs + * (e.g. because namePtr isn't valid) then NULL is returned and an error + * message will be left in interp's result unless interp is NULL. * * Side effects: * None. @@ -1814,17 +1769,17 @@ FreeResources(optionPtr, objPtr, internalPtr, tkwin) Tcl_Obj * Tk_GetOptionInfo(interp, recordPtr, optionTable, namePtr, tkwin) - Tcl_Interp *interp; /* Interpreter for error reporting. If - * NULL, then no error message is created. */ - char *recordPtr; /* Record whose fields contain current - * values for options. */ + Tcl_Interp *interp; /* Interpreter for error reporting. If NULL, + * then no error message is created. */ + char *recordPtr; /* Record whose fields contain current values + * for options. */ Tk_OptionTable optionTable; /* Describes all the legal options. */ - Tcl_Obj *namePtr; /* If non-NULL, the string value selects - * a single option whose info is to be - * returned. Otherwise info is returned for - * all options in optionTable. */ - Tk_Window tkwin; /* Window associated with recordPtr; needed - * to compute correct default value for some + Tcl_Obj *namePtr; /* If non-NULL, the string value selects a + * single option whose info is to be returned. + * Otherwise info is returned for all options + * in optionTable. */ + Tk_Window tkwin; /* Window associated with recordPtr; needed to + * compute correct default value for some * options. */ { Tcl_Obj *resultPtr; @@ -1833,8 +1788,8 @@ Tk_GetOptionInfo(interp, recordPtr, optionTable, namePtr, tkwin) int count; /* - * If information is only wanted for a single configuration - * spec, then handle that one spec specially. + * If information is only wanted for a single configuration spec, then + * handle that one spec specially. */ if (namePtr != NULL) { @@ -1849,8 +1804,8 @@ Tk_GetOptionInfo(interp, recordPtr, optionTable, namePtr, tkwin) } /* - * Loop through all the specs, creating a big list with all - * their information. + * Loop through all the specs, creating a big list with all their + * information. */ resultPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); @@ -1869,12 +1824,12 @@ Tk_GetOptionInfo(interp, recordPtr, optionTable, namePtr, tkwin) * * GetConfigList -- * - * Create a valid Tcl list holding the configuration information - * for a single configuration option. + * Create a valid Tcl list holding the configuration information for a + * single configuration option. * * Results: - * A Tcl list, dynamically allocated. The caller is expected to - * arrange for this list to be freed eventually. + * A Tcl list, dynamically allocated. The caller is expected to arrange + * for this list to be freed eventually. * * Side effects: * Memory is allocated. @@ -1884,8 +1839,8 @@ Tk_GetOptionInfo(interp, recordPtr, optionTable, namePtr, tkwin) static Tcl_Obj * GetConfigList(recordPtr, optionPtr, tkwin) - char *recordPtr; /* Pointer to record holding current - * values of configuration options. */ + char *recordPtr; /* Pointer to record holding current values of + * configuration options. */ Option *optionPtr; /* Pointer to information describing a * particular option. */ Tk_Window tkwin; /* Window corresponding to recordPtr. */ @@ -1893,7 +1848,7 @@ GetConfigList(recordPtr, optionPtr, tkwin) Tcl_Obj *listPtr, *elementPtr; listPtr = Tcl_NewListObj(0, (Tcl_Obj **) NULL); - Tcl_ListObjAppendElement((Tcl_Interp *) NULL, listPtr, + Tcl_ListObjAppendElement((Tcl_Interp *) NULL, listPtr, Tcl_NewStringObj(optionPtr->specPtr->optionName, -1)); if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) { @@ -1946,14 +1901,13 @@ GetConfigList(recordPtr, optionPtr, tkwin) * * GetObjectForOption -- * - * This procedure is called to create an object that contains the - * value for an option. It is invoked by GetConfigList and - * Tk_GetOptionValue when only the internal form of an option is - * stored in the record. + * This function is called to create an object that contains the value + * for an option. It is invoked by GetConfigList and Tk_GetOptionValue + * when only the internal form of an option is stored in the record. * * Results: - * The return value is a pointer to a Tcl object. The caller - * must call Tcl_IncrRefCount on this object to preserve it. + * The return value is a pointer to a Tcl object. The caller must call + * Tcl_IncrRefCount on this object to preserve it. * * Side effects: * None. @@ -1963,11 +1917,11 @@ GetConfigList(recordPtr, optionPtr, tkwin) static Tcl_Obj * GetObjectForOption(recordPtr, optionPtr, tkwin) - char *recordPtr; /* Pointer to record holding current - * values of configuration options. */ - Option *optionPtr; /* Pointer to information describing an - * option whose internal value is stored - * in *recordPtr. */ + char *recordPtr; /* Pointer to record holding current values of + * configuration options. */ + Option *optionPtr; /* Pointer to information describing an option + * whose internal value is stored in + * *recordPtr. */ Tk_Window tkwin; /* Window corresponding to recordPtr. */ { Tcl_Obj *objPtr; @@ -1977,107 +1931,103 @@ GetObjectForOption(recordPtr, optionPtr, tkwin) internalPtr = recordPtr + optionPtr->specPtr->internalOffset; objPtr = NULL; switch (optionPtr->specPtr->type) { - case TK_OPTION_BOOLEAN: { - objPtr = Tcl_NewIntObj(*((int *) internalPtr)); - break; - } - case TK_OPTION_INT: { - objPtr = Tcl_NewIntObj(*((int *) internalPtr)); - break; - } - case TK_OPTION_DOUBLE: { - objPtr = Tcl_NewDoubleObj(*((double *) internalPtr)); - break; + case TK_OPTION_BOOLEAN: + objPtr = Tcl_NewIntObj(*((int *) internalPtr)); + break; + case TK_OPTION_INT: + objPtr = Tcl_NewIntObj(*((int *) internalPtr)); + break; + case TK_OPTION_DOUBLE: + objPtr = Tcl_NewDoubleObj(*((double *) internalPtr)); + break; + case TK_OPTION_STRING: + objPtr = Tcl_NewStringObj(*((char **) internalPtr), -1); + break; + case TK_OPTION_STRING_TABLE: + objPtr = Tcl_NewStringObj(((char **) optionPtr->specPtr->clientData)[ + *((int *) internalPtr)], -1); + break; + case TK_OPTION_COLOR: { + XColor *colorPtr = *((XColor **) internalPtr); + + if (colorPtr != NULL) { + objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), -1); + } + break; + } + case TK_OPTION_FONT: { + Tk_Font tkfont = *((Tk_Font *) internalPtr); + + if (tkfont != NULL) { + objPtr = Tcl_NewStringObj(Tk_NameOfFont(tkfont), -1); } - case TK_OPTION_STRING: { - objPtr = Tcl_NewStringObj(*((char **) internalPtr), -1); - break; + break; + } + case TK_OPTION_STYLE: { + Tk_Style style = *((Tk_Style *) internalPtr); + + if (style != NULL) { + objPtr = Tcl_NewStringObj(Tk_NameOfStyle(style), -1); } - case TK_OPTION_STRING_TABLE: { + break; + } + case TK_OPTION_BITMAP: { + Pixmap pixmap = *((Pixmap *) internalPtr); + + if (pixmap != None) { objPtr = Tcl_NewStringObj( - ((char **) optionPtr->specPtr->clientData)[ - *((int *) internalPtr)], -1); - break; - } - case TK_OPTION_COLOR: { - XColor *colorPtr = *((XColor **) internalPtr); - if (colorPtr != NULL) { - objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), -1); - } - break; - } - case TK_OPTION_FONT: { - Tk_Font tkfont = *((Tk_Font *) internalPtr); - if (tkfont != NULL) { - objPtr = Tcl_NewStringObj(Tk_NameOfFont(tkfont), -1); - } - break; - } - case TK_OPTION_STYLE: { - Tk_Style style = *((Tk_Style *) internalPtr); - if (style != NULL) { - objPtr = Tcl_NewStringObj(Tk_NameOfStyle(style), -1); - } - break; - } - case TK_OPTION_BITMAP: { - Pixmap pixmap = *((Pixmap *) internalPtr); - if (pixmap != None) { - objPtr = Tcl_NewStringObj(Tk_NameOfBitmap(Tk_Display(tkwin), - pixmap), -1); - } - break; - } - case TK_OPTION_BORDER: { - Tk_3DBorder border = *((Tk_3DBorder *) internalPtr); - if (border != NULL) { - objPtr = Tcl_NewStringObj(Tk_NameOf3DBorder(border), -1); - } - break; - } - case TK_OPTION_RELIEF: { - objPtr = Tcl_NewStringObj(Tk_NameOfRelief( - *((int *) internalPtr)), -1); - break; - } - case TK_OPTION_CURSOR: { - Tk_Cursor cursor = *((Tk_Cursor *) internalPtr); - if (cursor != None) { - objPtr = Tcl_NewStringObj( - Tk_NameOfCursor(Tk_Display(tkwin), cursor), -1); - } - break; + Tk_NameOfBitmap(Tk_Display(tkwin), pixmap), -1); } - case TK_OPTION_JUSTIFY: { - objPtr = Tcl_NewStringObj(Tk_NameOfJustify( - *((Tk_Justify *) internalPtr)), -1); - break; - } - case TK_OPTION_ANCHOR: { - objPtr = Tcl_NewStringObj(Tk_NameOfAnchor( - *((Tk_Anchor *) internalPtr)), -1); - break; - } - case TK_OPTION_PIXELS: { - objPtr = Tcl_NewIntObj(*((int *) internalPtr)); - break; - } - case TK_OPTION_WINDOW: { - Tk_Window tkwin = *((Tk_Window *) internalPtr); - if (tkwin != NULL) { - objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1); - } - break; - } - case TK_OPTION_CUSTOM: { - Tk_ObjCustomOption *custom = optionPtr->extra.custom; - objPtr = custom->getProc(custom->clientData, tkwin, recordPtr, - optionPtr->specPtr->internalOffset); - break; + break; + } + case TK_OPTION_BORDER: { + Tk_3DBorder border = *((Tk_3DBorder *) internalPtr); + + if (border != NULL) { + objPtr = Tcl_NewStringObj(Tk_NameOf3DBorder(border), -1); } - default: { - Tcl_Panic("bad option type in GetObjectForOption"); + break; + } + case TK_OPTION_RELIEF: + objPtr = Tcl_NewStringObj(Tk_NameOfRelief(*((int *) internalPtr)), -1); + break; + case TK_OPTION_CURSOR: { + Tk_Cursor cursor = *((Tk_Cursor *) internalPtr); + + if (cursor != None) { + objPtr = Tcl_NewStringObj( + Tk_NameOfCursor(Tk_Display(tkwin), cursor), -1); } + break; + } + case TK_OPTION_JUSTIFY: + objPtr = Tcl_NewStringObj(Tk_NameOfJustify( + *((Tk_Justify *) internalPtr)), -1); + break; + case TK_OPTION_ANCHOR: + objPtr = Tcl_NewStringObj(Tk_NameOfAnchor( + *((Tk_Anchor *) internalPtr)), -1); + break; + case TK_OPTION_PIXELS: + objPtr = Tcl_NewIntObj(*((int *) internalPtr)); + break; + case TK_OPTION_WINDOW: { + Tk_Window tkwin = *((Tk_Window *) internalPtr); + + if (tkwin != NULL) { + objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1); + } + break; + } + case TK_OPTION_CUSTOM: { + Tk_ObjCustomOption *custom = optionPtr->extra.custom; + + objPtr = custom->getProc(custom->clientData, tkwin, recordPtr, + optionPtr->specPtr->internalOffset); + break; + } + default: + Tcl_Panic("bad option type in GetObjectForOption"); } if (objPtr == NULL) { objPtr = Tcl_NewObj(); @@ -2090,14 +2040,13 @@ GetObjectForOption(recordPtr, optionPtr, tkwin) * * Tk_GetOptionValue -- * - * This procedure returns the current value of a configuration - * option. + * This function returns the current value of a configuration option. * * Results: - * The return value is the object holding the current value of - * the option given by namePtr. If no such option exists, then - * the return value is NULL and an error message is left in - * interp's result (if interp isn't NULL). + * The return value is the object holding the current value of the option + * given by namePtr. If no such option exists, then the return value is + * NULL and an error message is left in interp's result (if interp isn't + * NULL). * * Side effects: * None. @@ -2107,14 +2056,14 @@ GetObjectForOption(recordPtr, optionPtr, tkwin) Tcl_Obj * Tk_GetOptionValue(interp, recordPtr, optionTable, namePtr, tkwin) - Tcl_Interp *interp; /* Interpreter for error reporting. If - * NULL then no messages are provided for + Tcl_Interp *interp; /* Interpreter for error reporting. If NULL + * then no messages are provided for * errors. */ - char *recordPtr; /* Record whose fields contain current - * values for options. */ + char *recordPtr; /* Record whose fields contain current values + * for options. */ Tk_OptionTable optionTable; /* Describes legal options. */ - Tcl_Obj *namePtr; /* Gives the command-line name for the - * option whose value is to be returned. */ + Tcl_Obj *namePtr; /* Gives the command-line name for the option + * whose value is to be returned. */ Tk_Window tkwin; /* Window corresponding to recordPtr. */ { OptionTable *tablePtr = (OptionTable *) optionTable; @@ -2129,16 +2078,16 @@ Tk_GetOptionValue(interp, recordPtr, optionTable, namePtr, tkwin) optionPtr = optionPtr->extra.synonymPtr; } if (optionPtr->specPtr->objOffset >= 0) { - resultPtr = *((Tcl_Obj **) (recordPtr + optionPtr->specPtr->objOffset)); + resultPtr = *((Tcl_Obj **) (recordPtr+optionPtr->specPtr->objOffset)); if (resultPtr == NULL) { /* * This option has a null value and is represented by a null - * object pointer. We can't return the null pointer, since that - * would indicate an error. Instead, return a new empty object. + * object pointer. We can't return the null pointer, since that + * would indicate an error. Instead, return a new empty object. */ - + resultPtr = Tcl_NewObj(); - } + } } else { resultPtr = GetObjectForOption(recordPtr, optionPtr, tkwin); } @@ -2150,19 +2099,17 @@ Tk_GetOptionValue(interp, recordPtr, optionTable, namePtr, tkwin) * * TkDebugConfig -- * - * This is a debugging procedure that returns information about - * one of the configuration tables that currently exists for an - * interpreter. + * This is a debugging function that returns information about one of the + * configuration tables that currently exists for an interpreter. * * Results: - * If the specified table exists in the given interpreter, then a - * list is returned describing the table and any other tables that - * it chains to: for each table there will be three list elements - * giving the reference count for the table, the number of elements - * in the table, and the command-line name for the first option - * in the table. If the table doesn't exist in the interpreter - * then an empty object is returned. The reference count for the - * returned object is 0. + * If the specified table exists in the given interpreter, then a list is + * returned describing the table and any other tables that it chains to: + * for each table there will be three list elements giving the reference + * count for the table, the number of elements in the table, and the + * command-line name for the first option in the table. If the table + * doesn't exist in the interpreter then an empty object is returned. + * The reference count for the returned object is 0. * * Side effects: * None. @@ -2172,11 +2119,11 @@ Tk_GetOptionValue(interp, recordPtr, optionTable, namePtr, tkwin) Tcl_Obj * TkDebugConfig(interp, table) - Tcl_Interp *interp; /* Interpreter in which the table is - * defined. */ - Tk_OptionTable table; /* Table about which information is to - * be returned. May not necessarily - * exist in the interpreter anymore. */ + Tcl_Interp *interp; /* Interpreter in which the table is + * defined. */ + Tk_OptionTable table; /* Table about which information is to be + * returned. May not necessarily exist in the + * interpreter anymore. */ { OptionTable *tablePtr = (OptionTable *) table; Tcl_HashTable *hashTablePtr; @@ -2192,8 +2139,8 @@ TkDebugConfig(interp, table) } /* - * Scan all the tables for this interpreter to make sure that the - * one we want still is valid. + * Scan all the tables for this interpreter to make sure that the one we + * want still is valid. */ for (hashEntryPtr = Tcl_FirstHashEntry(hashTablePtr, &search); @@ -2207,11 +2154,18 @@ TkDebugConfig(interp, table) Tcl_NewIntObj(tablePtr->numOptions)); Tcl_ListObjAppendElement((Tcl_Interp *) NULL, objPtr, Tcl_NewStringObj( - tablePtr->options[0].specPtr->optionName, - -1)); + tablePtr->options[0].specPtr->optionName, -1)); } break; } } return objPtr; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkEntry.c b/generic/tkEntry.c index f1c2885..ab628e9 100644 --- a/generic/tkEntry.c +++ b/generic/tkEntry.c @@ -1,9 +1,9 @@ -/* - * Entry.c -- +/* + * tkEntry.c -- * * This module implements entry and spinbox widgets for the Tk toolkit. - * An entry displays a string and allows the string to be edited. - * A spinbox expands on the entry by adding up/down buttons that control + * An entry displays a string and allows the string to be edited. A + * spinbox expands on the entry by adding up/down buttons that control * the value of the entry widget. * * Copyright (c) 1990-1994 The Regents of the University of California. @@ -11,28 +11,28 @@ * Copyright (c) 2000 Ajuba Solutions. * Copyright (c) 2002 ActiveState Corporation. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkEntry.c,v 1.37 2005/03/24 15:25:52 dgp Exp $ + * RCS: @(#) $Id: tkEntry.c,v 1.38 2005/08/10 22:02:22 dkf Exp $ */ #include "tkInt.h" #include "default.h" #include "tkEntry.h" - /* - * The following macro defines how many extra pixels to leave on each - * side of the text in the entry. + * The following macro defines how many extra pixels to leave on each side of + * the text in the entry. */ #define XPAD 1 #define YPAD 1 /* - * A comparison function for double values. For Spinboxes. + * A comparison function for double values. For Spinboxes. */ + #define MIN_DBL_VAL 1E-9 #define DOUBLES_EQ(d1, d2) (fabs((d1) - (d2)) < MIN_DBL_VAL) @@ -72,55 +72,55 @@ static Tk_OptionSpec entryOptSpec[] = { {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, (char *) NULL, 0, -1, 0, (ClientData) "-background", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth), - 0, 0, 0}, + DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth), + 0, 0, 0}, {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", DEF_ENTRY_CURSOR, -1, Tk_Offset(Entry, cursor), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_BORDER, "-disabledbackground", "disabledBackground", - "DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1, - Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK, - (ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0}, + "DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1, + Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK, + (ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0}, {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground", - "DisabledForeground", DEF_ENTRY_DISABLED_FG, -1, - Tk_Offset(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0}, + "DisabledForeground", DEF_ENTRY_DISABLED_FG, -1, + Tk_Offset(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection", - "ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1, - Tk_Offset(Entry, exportSelection), 0, 0, 0}, + "ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1, + Tk_Offset(Entry, exportSelection), 0, 0, 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL, (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", DEF_ENTRY_FONT, -1, Tk_Offset(Entry, tkfont), 0, 0, 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", - DEF_ENTRY_FG, -1, Tk_Offset(Entry, fgColorPtr), 0, - 0, 0}, + DEF_ENTRY_FG, -1, Tk_Offset(Entry, fgColorPtr), 0, + 0, 0}, {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG, - -1, Tk_Offset(Entry, highlightBgColorPtr), - 0, 0, 0}, + -1, Tk_Offset(Entry, highlightBgColorPtr), + 0, 0, 0}, {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_ENTRY_HIGHLIGHT, -1, Tk_Offset(Entry, highlightColorPtr), 0, 0, 0}, {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", - "HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1, + "HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1, Tk_Offset(Entry, highlightWidth), 0, 0, 0}, {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground", DEF_ENTRY_INSERT_BG, - -1, Tk_Offset(Entry, insertBorder), - 0, 0, 0}, - {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth", - "BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, -1, - Tk_Offset(Entry, insertBorderWidth), 0, - (ClientData) DEF_ENTRY_INSERT_BD_MONO, 0}, + -1, Tk_Offset(Entry, insertBorder), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth", + "BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, -1, + Tk_Offset(Entry, insertBorderWidth), 0, + (ClientData) DEF_ENTRY_INSERT_BD_MONO, 0}, {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime", - DEF_ENTRY_INSERT_OFF_TIME, -1, Tk_Offset(Entry, insertOffTime), - 0, 0, 0}, + DEF_ENTRY_INSERT_OFF_TIME, -1, Tk_Offset(Entry, insertOffTime), + 0, 0, 0}, {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime", - DEF_ENTRY_INSERT_ON_TIME, -1, Tk_Offset(Entry, insertOnTime), - 0, 0, 0}, + DEF_ENTRY_INSERT_ON_TIME, -1, Tk_Offset(Entry, insertOnTime), + 0, 0, 0}, {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", - DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth), - 0, 0, 0}, + DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth), + 0, 0, 0}, {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand", DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd), TK_OPTION_NULL_OK, 0, 0}, @@ -129,40 +129,40 @@ static Tk_OptionSpec entryOptSpec[] = { {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0}, {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground", - "ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1, - Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK, - (ClientData) DEF_ENTRY_READONLY_BG_MONO, 0}, + "ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1, + Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK, + (ClientData) DEF_ENTRY_READONLY_BG_MONO, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", - DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief), - 0, 0, 0}, + DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief), + 0, 0, 0}, {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground", - DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(Entry, selBorder), - 0, (ClientData) DEF_ENTRY_SELECT_MONO, 0}, - {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", - "BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1, - Tk_Offset(Entry, selBorderWidth), - 0, (ClientData) DEF_ENTRY_SELECT_BD_MONO, 0}, + DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(Entry, selBorder), + 0, (ClientData) DEF_ENTRY_SELECT_MONO, 0}, + {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", + "BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1, + Tk_Offset(Entry, selBorderWidth), + 0, (ClientData) DEF_ENTRY_SELECT_BD_MONO, 0}, {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background", DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr), 0, (ClientData) DEF_ENTRY_SELECT_FG_MONO, 0}, {TK_OPTION_STRING, "-show", "show", "Show", - DEF_ENTRY_SHOW, -1, Tk_Offset(Entry, showChar), - TK_OPTION_NULL_OK, 0, 0}, + DEF_ENTRY_SHOW, -1, Tk_Offset(Entry, showChar), + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-state", "state", "State", - DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state), - 0, (ClientData) stateStrings, 0}, + DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state), + 0, (ClientData) stateStrings, 0}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus), - TK_OPTION_NULL_OK, 0, 0}, + DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus), + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", DEF_ENTRY_TEXT_VARIABLE, -1, Tk_Offset(Entry, textVarName), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate", - DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate), - 0, (ClientData) validateStrings, 0}, + DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate), + 0, (ClientData) validateStrings, 0}, {TK_OPTION_STRING, "-validatecommand", "validateCommand", "ValidateCommand", - (char *) NULL, -1, Tk_Offset(Entry, validateCmd), - TK_OPTION_NULL_OK, 0, 0}, + (char *) NULL, -1, Tk_Offset(Entry, validateCmd), + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_SYNONYM, "-vcmd", (char *) NULL, (char *) NULL, (char *) NULL, 0, -1, 0, (ClientData) "-validatecommand", 0}, {TK_OPTION_INT, "-width", "width", "Width", @@ -203,8 +203,8 @@ static Tk_OptionSpec sbOptSpec[] = { {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, (char *) NULL, 0, -1, 0, (ClientData) "-background", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth), - 0, 0, 0}, + DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth), + 0, 0, 0}, {TK_OPTION_BORDER, "-buttonbackground", "Button.background", "Background", DEF_BUTTON_BG_COLOR, -1, Tk_Offset(Spinbox, buttonBorder), 0, (ClientData) DEF_BUTTON_BG_MONO, 0}, @@ -213,10 +213,10 @@ static Tk_OptionSpec sbOptSpec[] = { TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_RELIEF, "-buttondownrelief", "Button.relief", "Relief", DEF_BUTTON_RELIEF, -1, Tk_Offset(Spinbox, bdRelief), - 0, 0, 0}, + 0, 0, 0}, {TK_OPTION_RELIEF, "-buttonuprelief", "Button.relief", "Relief", DEF_BUTTON_RELIEF, -1, Tk_Offset(Spinbox, buRelief), - 0, 0, 0}, + 0, 0, 0}, {TK_OPTION_STRING, "-command", "command", "Command", DEF_SPINBOX_CMD, -1, Tk_Offset(Spinbox, command), TK_OPTION_NULL_OK, 0, 0}, @@ -224,22 +224,22 @@ static Tk_OptionSpec sbOptSpec[] = { DEF_ENTRY_CURSOR, -1, Tk_Offset(Entry, cursor), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_BORDER, "-disabledbackground", "disabledBackground", - "DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1, - Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK, - (ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0}, + "DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1, + Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK, + (ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0}, {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground", - "DisabledForeground", DEF_ENTRY_DISABLED_FG, -1, - Tk_Offset(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0}, + "DisabledForeground", DEF_ENTRY_DISABLED_FG, -1, + Tk_Offset(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection", - "ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1, - Tk_Offset(Entry, exportSelection), 0, 0, 0}, + "ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1, + Tk_Offset(Entry, exportSelection), 0, 0, 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL, (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", DEF_ENTRY_FONT, -1, Tk_Offset(Entry, tkfont), 0, 0, 0}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", - DEF_ENTRY_FG, -1, Tk_Offset(Entry, fgColorPtr), 0, - 0, 0}, + DEF_ENTRY_FG, -1, Tk_Offset(Entry, fgColorPtr), 0, + 0, 0}, {TK_OPTION_STRING, "-format", "format", "Format", DEF_SPINBOX_FORMAT, -1, Tk_Offset(Spinbox, reqFormat), TK_OPTION_NULL_OK, 0, 0}, @@ -247,32 +247,32 @@ static Tk_OptionSpec sbOptSpec[] = { DEF_SPINBOX_FROM, -1, Tk_Offset(Spinbox, fromValue), 0, 0, 0}, {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG, - -1, Tk_Offset(Entry, highlightBgColorPtr), - 0, 0, 0}, + -1, Tk_Offset(Entry, highlightBgColorPtr), + 0, 0, 0}, {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_ENTRY_HIGHLIGHT, -1, Tk_Offset(Entry, highlightColorPtr), 0, 0, 0}, {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", - "HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1, + "HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1, Tk_Offset(Entry, highlightWidth), 0, 0, 0}, {TK_OPTION_DOUBLE, "-increment", "increment", "Increment", DEF_SPINBOX_INCREMENT, -1, Tk_Offset(Spinbox, increment), 0, 0, 0}, {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground", - DEF_ENTRY_INSERT_BG, -1, Tk_Offset(Entry, insertBorder), - 0, 0, 0}, - {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth", - "BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, -1, - Tk_Offset(Entry, insertBorderWidth), 0, - (ClientData) DEF_ENTRY_INSERT_BD_MONO, 0}, + DEF_ENTRY_INSERT_BG, -1, Tk_Offset(Entry, insertBorder), + 0, 0, 0}, + {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth", + "BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, -1, + Tk_Offset(Entry, insertBorderWidth), 0, + (ClientData) DEF_ENTRY_INSERT_BD_MONO, 0}, {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime", - DEF_ENTRY_INSERT_OFF_TIME, -1, Tk_Offset(Entry, insertOffTime), - 0, 0, 0}, + DEF_ENTRY_INSERT_OFF_TIME, -1, Tk_Offset(Entry, insertOffTime), + 0, 0, 0}, {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime", - DEF_ENTRY_INSERT_ON_TIME, -1, Tk_Offset(Entry, insertOnTime), - 0, 0, 0}, + DEF_ENTRY_INSERT_ON_TIME, -1, Tk_Offset(Entry, insertOnTime), + 0, 0, 0}, {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", - DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth), - 0, 0, 0}, + DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth), + 0, 0, 0}, {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand", DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd), TK_OPTION_NULL_OK, 0, 0}, @@ -281,48 +281,48 @@ static Tk_OptionSpec sbOptSpec[] = { {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", - DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief), - 0, 0, 0}, + DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief), + 0, 0, 0}, {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground", - "ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1, - Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK, - (ClientData) DEF_ENTRY_READONLY_BG_MONO, 0}, + "ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1, + Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK, + (ClientData) DEF_ENTRY_READONLY_BG_MONO, 0}, {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay", - DEF_SPINBOX_REPEAT_DELAY, -1, Tk_Offset(Spinbox, repeatDelay), - 0, 0, 0}, + DEF_SPINBOX_REPEAT_DELAY, -1, Tk_Offset(Spinbox, repeatDelay), + 0, 0, 0}, {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval", - DEF_SPINBOX_REPEAT_INTERVAL, -1, Tk_Offset(Spinbox, repeatInterval), - 0, 0, 0}, + DEF_SPINBOX_REPEAT_INTERVAL, -1, Tk_Offset(Spinbox, repeatInterval), + 0, 0, 0}, {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground", - DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(Entry, selBorder), - 0, (ClientData) DEF_ENTRY_SELECT_MONO, 0}, - {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", - "BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1, - Tk_Offset(Entry, selBorderWidth), - 0, (ClientData) DEF_ENTRY_SELECT_BD_MONO, 0}, + DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(Entry, selBorder), + 0, (ClientData) DEF_ENTRY_SELECT_MONO, 0}, + {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", + "BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1, + Tk_Offset(Entry, selBorderWidth), + 0, (ClientData) DEF_ENTRY_SELECT_BD_MONO, 0}, {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background", DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr), 0, (ClientData) DEF_ENTRY_SELECT_FG_MONO, 0}, {TK_OPTION_STRING_TABLE, "-state", "state", "State", - DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state), - 0, (ClientData) stateStrings, 0}, + DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state), + 0, (ClientData) stateStrings, 0}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus), - TK_CONFIG_NULL_OK, 0, 0}, + DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus), + TK_CONFIG_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", DEF_ENTRY_TEXT_VARIABLE, -1, Tk_Offset(Entry, textVarName), TK_CONFIG_NULL_OK, 0, 0}, {TK_OPTION_DOUBLE, "-to", "to", "To", DEF_SPINBOX_TO, -1, Tk_Offset(Spinbox, toValue), 0, 0, 0}, {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate", - DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate), - 0, (ClientData) validateStrings, 0}, + DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate), + 0, (ClientData) validateStrings, 0}, {TK_OPTION_STRING, "-validatecommand", "validateCommand", "ValidateCommand", - (char *) NULL, -1, Tk_Offset(Entry, validateCmd), - TK_CONFIG_NULL_OK, 0, 0}, + (char *) NULL, -1, Tk_Offset(Entry, validateCmd), + TK_CONFIG_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-values", "values", "Values", - DEF_SPINBOX_VALUES, -1, Tk_Offset(Spinbox, valueStr), - TK_OPTION_NULL_OK, 0, 0}, + DEF_SPINBOX_VALUES, -1, Tk_Offset(Spinbox, valueStr), + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_SYNONYM, "-vcmd", (char *) NULL, (char *) NULL, (char *) NULL, 0, -1, 0, (ClientData) "-validatecommand", 0}, {TK_OPTION_INT, "-width", "width", "Width", @@ -337,19 +337,19 @@ static Tk_OptionSpec sbOptSpec[] = { }; /* - * The following tables define the entry widget commands (and sub- - * commands) and map the indexes into the string tables into - * enumerated types used to dispatch the entry widget command. + * The following tables define the entry widget commands (and sub-commands) + * and map the indexes into the string tables into enumerated types used to + * dispatch the entry widget command. */ static CONST char *entryCmdNames[] = { - "bbox", "cget", "configure", "delete", "get", "icursor", "index", + "bbox", "cget", "configure", "delete", "get", "icursor", "index", "insert", "scan", "selection", "validate", "xview", (char *) NULL }; enum entryCmd { - COMMAND_BBOX, COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DELETE, - COMMAND_GET, COMMAND_ICURSOR, COMMAND_INDEX, COMMAND_INSERT, + COMMAND_BBOX, COMMAND_CGET, COMMAND_CONFIGURE, COMMAND_DELETE, + COMMAND_GET, COMMAND_ICURSOR, COMMAND_INDEX, COMMAND_INSERT, COMMAND_SCAN, COMMAND_SELECTION, COMMAND_VALIDATE, COMMAND_XVIEW }; @@ -363,9 +363,9 @@ enum selCmd { }; /* - * The following tables define the spinbox widget commands (and sub- - * commands) and map the indexes into the string tables into - * enumerated types used to dispatch the spinbox widget command. + * The following tables define the spinbox widget commands (and sub-commands) + * and map the indexes into the string tables into enumerated types used to + * dispatch the spinbox widget command. */ static CONST char *sbCmdNames[] = { @@ -375,7 +375,7 @@ static CONST char *sbCmdNames[] = { }; enum sbCmd { - SB_CMD_BBOX, SB_CMD_CGET, SB_CMD_CONFIGURE, SB_CMD_DELETE, + SB_CMD_BBOX, SB_CMD_CGET, SB_CMD_CONFIGURE, SB_CMD_DELETE, SB_CMD_GET, SB_CMD_ICURSOR, SB_CMD_IDENTIFY, SB_CMD_INDEX, SB_CMD_INSERT, SB_CMD_INVOKE, SB_CMD_SCAN, SB_CMD_SELECTION, SB_CMD_SET, SB_CMD_VALIDATE, SB_CMD_XVIEW @@ -387,7 +387,7 @@ static CONST char *sbSelCmdNames[] = { }; enum sbselCmd { - SB_SEL_ADJUST, SB_SEL_CLEAR, SB_SEL_ELEMENT, SB_SEL_FROM, + SB_SEL_ADJUST, SB_SEL_CLEAR, SB_SEL_ELEMENT, SB_SEL_FROM, SB_SEL_PRESENT, SB_SEL_RANGE, SB_SEL_TO }; @@ -395,91 +395,80 @@ enum sbselCmd { * Extra for selection of elements */ -/* - * This is the string array corresponding to the enum in selelement. - * If you modify them, you must modify the strings here. +/* + * This is the string array corresponding to the enum in selelement. If you + * modify them, you must modify the strings here. */ - + static CONST char *selElementNames[] = { "none", "buttondown", "buttonup", (char *) NULL, "entry" }; + /* - * Flags for GetEntryIndex procedure: + * Flags for GetEntryIndex function: */ #define ZERO_OK 1 #define LAST_PLUS_ONE_OK 2 /* - * Forward declarations for procedures defined later in this file: + * Forward declarations for functions defined later in this file: */ -static int ConfigureEntry _ANSI_ARGS_((Tcl_Interp *interp, - Entry *entryPtr, int objc, - Tcl_Obj *CONST objv[], int flags)); -static void DeleteChars _ANSI_ARGS_((Entry *entryPtr, int index, - int count)); -static void DestroyEntry _ANSI_ARGS_((char *memPtr)); -static void DisplayEntry _ANSI_ARGS_((ClientData clientData)); -static void EntryBlinkProc _ANSI_ARGS_((ClientData clientData)); -static void EntryCmdDeletedProc _ANSI_ARGS_(( - ClientData clientData)); -static void EntryComputeGeometry _ANSI_ARGS_((Entry *entryPtr)); -static void EntryEventProc _ANSI_ARGS_((ClientData clientData, - XEvent *eventPtr)); -static void EntryFocusProc _ANSI_ARGS_ ((Entry *entryPtr, - int gotFocus)); -static int EntryFetchSelection _ANSI_ARGS_((ClientData clientData, - int offset, char *buffer, int maxBytes)); -static void EntryLostSelection _ANSI_ARGS_(( - ClientData clientData)); -static void EventuallyRedraw _ANSI_ARGS_((Entry *entryPtr)); -static void EntryScanTo _ANSI_ARGS_((Entry *entryPtr, int y)); -static void EntrySetValue _ANSI_ARGS_((Entry *entryPtr, - CONST char *value)); -static void EntrySelectTo _ANSI_ARGS_(( - Entry *entryPtr, int index)); -static char * EntryTextVarProc _ANSI_ARGS_((ClientData clientData, +static int ConfigureEntry(Tcl_Interp *interp, Entry *entryPtr, + int objc, Tcl_Obj *CONST objv[], int flags); +static void DeleteChars(Entry *entryPtr, int index, int count); +static void DestroyEntry(char *memPtr); +static void DisplayEntry(ClientData clientData); +static void EntryBlinkProc(ClientData clientData); +static void EntryCmdDeletedProc(ClientData clientData); +static void EntryComputeGeometry(Entry *entryPtr); +static void EntryEventProc(ClientData clientData, + XEvent *eventPtr); +static void EntryFocusProc(Entry *entryPtr, int gotFocus); +static int EntryFetchSelection(ClientData clientData, int offset, + char *buffer, int maxBytes); +static void EntryLostSelection(ClientData clientData); +static void EventuallyRedraw(Entry *entryPtr); +static void EntryScanTo(Entry *entryPtr, int y); +static void EntrySetValue(Entry *entryPtr, CONST char *value); +static void EntrySelectTo(Entry *entryPtr, int index); +static char * EntryTextVarProc(ClientData clientData, Tcl_Interp *interp, CONST char *name1, - CONST char *name2, int flags)); -static void EntryUpdateScrollbar _ANSI_ARGS_((Entry *entryPtr)); -static int EntryValidate _ANSI_ARGS_((Entry *entryPtr, - char *cmd)); -static int EntryValidateChange _ANSI_ARGS_((Entry *entryPtr, + CONST char *name2, int flags); +static void EntryUpdateScrollbar(Entry *entryPtr); +static int EntryValidate(Entry *entryPtr, char *cmd); +static int EntryValidateChange(Entry *entryPtr, char *change, + CONST char *new, int index, int type); +static void ExpandPercents(Entry *entryPtr, CONST char *before, char *change, CONST char *new, int index, - int type)); -static void ExpandPercents _ANSI_ARGS_((Entry *entryPtr, - CONST char *before, char *change, CONST char *new, - int index, int type, Tcl_DString *dsPtr)); -static void EntryValueChanged _ANSI_ARGS_((Entry *entryPtr, - CONST char *newValue)); -static void EntryVisibleRange _ANSI_ARGS_((Entry *entryPtr, - double *firstPtr, double *lastPtr)); -static int EntryWidgetObjCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static void EntryWorldChanged _ANSI_ARGS_(( - ClientData instanceData)); -static int GetEntryIndex _ANSI_ARGS_((Tcl_Interp *interp, - Entry *entryPtr, char *string, int *indexPtr)); -static void InsertChars _ANSI_ARGS_((Entry *entryPtr, int index, - char *string)); + int type, Tcl_DString *dsPtr); +static void EntryValueChanged(Entry *entryPtr, + CONST char *newValue); +static void EntryVisibleRange(Entry *entryPtr, + double *firstPtr, double *lastPtr); +static int EntryWidgetObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]); +static void EntryWorldChanged(ClientData instanceData); +static int GetEntryIndex(Tcl_Interp *interp, Entry *entryPtr, + char *string, int *indexPtr); +static void InsertChars(Entry *entryPtr, int index, char *string); /* * These forward declarations are the spinbox specific ones: */ -static int SpinboxWidgetObjCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static int GetSpinboxElement _ANSI_ARGS_((Spinbox *sbPtr, - int x, int y)); -static int SpinboxInvoke _ANSI_ARGS_((Tcl_Interp *interp, - Spinbox *sbPtr, int element)); -static int ComputeFormat _ANSI_ARGS_((Spinbox *sbPtr)); +static int SpinboxWidgetObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]); +static int GetSpinboxElement(Spinbox *sbPtr, int x, int y); +static int SpinboxInvoke(Tcl_Interp *interp, Spinbox *sbPtr, + int element); +static int ComputeFormat(Spinbox *sbPtr); /* - * The structure below defines widget class behavior by means of procedures + * The structure below defines widget class behavior by means of functions * that can be invoked from generic window code. */ @@ -494,9 +483,8 @@ static Tk_ClassProcs entryClass = { * * Tk_EntryObjCmd -- * - * This procedure is invoked to process the "entry" Tcl - * command. See the user documentation for details on what - * it does. + * This function is invoked to process the "entry" Tcl command. See the + * user documentation for details on what it does. * * Results: * A standard Tcl result. @@ -512,7 +500,7 @@ Tk_EntryObjCmd(clientData, interp, objc, objv) ClientData clientData; /* NULL. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ - Tcl_Obj *CONST objv[]; /* Argument objects. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ { register Entry *entryPtr; Tk_OptionTable optionTable; @@ -525,23 +513,23 @@ Tk_EntryObjCmd(clientData, interp, objc, objv) } tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), - Tcl_GetString(objv[1]), (char *) NULL); + Tcl_GetString(objv[1]), (char *) NULL); if (tkwin == NULL) { return TCL_ERROR; } /* - * Create the option table for this widget class. If it has already - * been created, Tk will return the cached value. + * Create the option table for this widget class. If it has already been + * created, Tk will return the cached value. */ optionTable = Tk_CreateOptionTable(interp, entryOptSpec); /* - * Initialize the fields of the structure that won't be initialized - * by ConfigureEntry, or that ConfigureEntry requires to be - * initialized already (e.g. resource pointers). Only the non-NULL/0 - * data must be initialized as memset covers the rest. + * Initialize the fields of the structure that won't be initialized by + * ConfigureEntry, or that ConfigureEntry requires to be initialized + * already (e.g. resource pointers). Only the non-NULL/0 data must be + * initialized as memset covers the rest. */ entryPtr = (Entry *) ckalloc(sizeof(Entry)); @@ -605,9 +593,9 @@ Tk_EntryObjCmd(clientData, interp, objc, objv) * * EntryWidgetObjCmd -- * - * 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. + * This function 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. @@ -634,9 +622,9 @@ EntryWidgetObjCmd(clientData, interp, objc, objv) return TCL_ERROR; } - /* - * Parse the widget command by looking up the second token in - * the list of valid command names. + /* + * Parse the widget command by looking up the second token in the list of + * valid command names. */ result = Tcl_GetIndexFromObj(interp, objv[1], entryCmdNames, @@ -647,398 +635,379 @@ EntryWidgetObjCmd(clientData, interp, objc, objv) Tcl_Preserve((ClientData) entryPtr); switch ((enum entryCmd) cmdIndex) { - case COMMAND_BBOX: { - int index, x, y, width, height; - char buf[TCL_INTEGER_SPACE * 4]; + case COMMAND_BBOX: { + int index, x, y, width, height; + char buf[TCL_INTEGER_SPACE * 4]; - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "index"); - goto error; - } - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), - &index) != TCL_OK) { - goto error; - } - if ((index == entryPtr->numChars) && (index > 0)) { - index--; - } - Tk_CharBbox(entryPtr->textLayout, index, &x, &y, - &width, &height); - sprintf(buf, "%d %d %d %d", x + entryPtr->layoutX, - y + entryPtr->layoutY, width, height); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - break; - } - - case COMMAND_CGET: { - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "option"); - goto error; - } - - objPtr = Tk_GetOptionValue(interp, (char *) entryPtr, - entryPtr->optionTable, objv[2], entryPtr->tkwin); + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "index"); + goto error; + } + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &index) != TCL_OK) { + goto error; + } + if ((index == entryPtr->numChars) && (index > 0)) { + index--; + } + Tk_CharBbox(entryPtr->textLayout, index, &x, &y, &width, &height); + sprintf(buf, "%d %d %d %d", x + entryPtr->layoutX, + y + entryPtr->layoutY, width, height); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + break; + } + + case COMMAND_CGET: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "option"); + goto error; + } + + objPtr = Tk_GetOptionValue(interp, (char *) entryPtr, + entryPtr->optionTable, objv[2], entryPtr->tkwin); + if (objPtr == NULL) { + goto error; + } else { + Tcl_SetObjResult(interp, objPtr); + } + break; + + case COMMAND_CONFIGURE: + if (objc <= 3) { + objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr, + entryPtr->optionTable, + (objc == 3) ? objv[2] : (Tcl_Obj *) NULL, + entryPtr->tkwin); if (objPtr == NULL) { - goto error; + goto error; } else { Tcl_SetObjResult(interp, objPtr); } - break; + } else { + result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0); } + break; - case COMMAND_CONFIGURE: { - if (objc <= 3) { - objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr, - entryPtr->optionTable, - (objc == 3) ? objv[2] : (Tcl_Obj *) NULL, - entryPtr->tkwin); - if (objPtr == NULL) { - goto error; - } else { - Tcl_SetObjResult(interp, objPtr); - } - } else { - result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0); - } - break; + case COMMAND_DELETE: { + int first, last; + + if ((objc < 3) || (objc > 4)) { + Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?"); + goto error; + } + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &first) != TCL_OK) { + goto error; + } + if (objc == 3) { + last = first + 1; + } else if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[3]), + &last) != TCL_OK) { + goto error; } + if ((last >= first) && (entryPtr->state == STATE_NORMAL)) { + DeleteChars(entryPtr, first, last - first); + } + break; + } - case COMMAND_DELETE: { - int first, last; + case COMMAND_GET: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL); + goto error; + } + Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1); + break; - if ((objc < 3) || (objc > 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?"); - goto error; - } - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), - &first) != TCL_OK) { - goto error; - } - if (objc == 3) { - last = first + 1; - } else { - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[3]), - &last) != TCL_OK) { - goto error; - } - } - if ((last >= first) && (entryPtr->state == STATE_NORMAL)) { - DeleteChars(entryPtr, first, last - first); - } - break; + case COMMAND_ICURSOR: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "pos"); + goto error; + } + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &entryPtr->insertPos) != TCL_OK) { + goto error; } + EventuallyRedraw(entryPtr); + break; - case COMMAND_GET: { - if (objc != 2) { - Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL); - goto error; - } - Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1); - break; + case COMMAND_INDEX: { + int index; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "string"); + goto error; + } + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &index) != TCL_OK) { + goto error; } + Tcl_SetObjResult(interp, Tcl_NewIntObj(index)); + break; + } - case COMMAND_ICURSOR: { - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "pos"); + case COMMAND_INSERT: { + int index; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "index text"); + goto error; + } + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &index) != TCL_OK) { + goto error; + } + if (entryPtr->state == STATE_NORMAL) { + InsertChars(entryPtr, index, Tcl_GetString(objv[3])); + } + break; + } + + case COMMAND_SCAN: { + int x; + char *minorCmd; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x"); + goto error; + } + if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) { + goto error; + } + + minorCmd = Tcl_GetString(objv[2]); + if (minorCmd[0] == 'm' + && (strncmp(minorCmd, "mark", strlen(minorCmd)) == 0)) { + entryPtr->scanMarkX = x; + entryPtr->scanMarkIndex = entryPtr->leftIndex; + } else if ((minorCmd[0] == 'd') + && (strncmp(minorCmd, "dragto", strlen(minorCmd)) == 0)) { + EntryScanTo(entryPtr, x); + } else { + Tcl_AppendResult(interp, "bad scan option \"", + Tcl_GetString(objv[2]), "\": must be mark or dragto", + (char *) NULL); + goto error; + } + break; + } + + case COMMAND_SELECTION: { + int index, index2; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "option ?index?"); + goto error; + } + + /* + * Parse the selection sub-command, using the command table + * "selCmdNames" defined above. + */ + + result = Tcl_GetIndexFromObj(interp, objv[2], selCmdNames, + "selection option", 0, &selIndex); + if (result != TCL_OK) { + goto error; + } + + /* + * Disabled entries don't allow the selection to be modified, but + * 'selection present' must return a boolean. + */ + + if ((entryPtr->state == STATE_DISABLED) + && (selIndex != SELECTION_PRESENT)) { + goto done; + } + + switch (selIndex) { + case SELECTION_ADJUST: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 3, objv, "index"); goto error; } - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), - &entryPtr->insertPos) != TCL_OK) { - goto error; + if (GetEntryIndex(interp, entryPtr, + Tcl_GetString(objv[3]), &index) != TCL_OK) { + goto error; } - EventuallyRedraw(entryPtr); + if (entryPtr->selectFirst >= 0) { + int half1, half2; + + half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2; + half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2; + if (index < half1) { + entryPtr->selectAnchor = entryPtr->selectLast; + } else if (index > half2) { + entryPtr->selectAnchor = entryPtr->selectFirst; + } else { + /* + * We're at about the halfway point in the selection; just + * keep the existing anchor. + */ + } + } + EntrySelectTo(entryPtr, index); break; - } - - case COMMAND_INDEX: { - int index; + case SELECTION_CLEAR: if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "string"); + Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL); goto error; } - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), - &index) != TCL_OK) { - goto error; + if (entryPtr->selectFirst >= 0) { + entryPtr->selectFirst = -1; + entryPtr->selectLast = -1; + EventuallyRedraw(entryPtr); } - Tcl_SetObjResult(interp, Tcl_NewIntObj(index)); - break; - } - - case COMMAND_INSERT: { - int index; + goto done; + case SELECTION_FROM: if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "index text"); + Tcl_WrongNumArgs(interp, 3, objv, "index"); goto error; } - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), - &index) != TCL_OK) { - goto error; - } - if (entryPtr->state == STATE_NORMAL) { - InsertChars(entryPtr, index, Tcl_GetString(objv[3])); + if (GetEntryIndex(interp, entryPtr, + Tcl_GetString(objv[3]), &index) != TCL_OK) { + goto error; } + entryPtr->selectAnchor = index; break; - } - case COMMAND_SCAN: { - int x; - char *minorCmd; + case SELECTION_PRESENT: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL); + goto error; + } + Tcl_SetObjResult(interp, + Tcl_NewBooleanObj((entryPtr->selectFirst >= 0))); + goto done; - if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x"); + case SELECTION_RANGE: + if (objc != 5) { + Tcl_WrongNumArgs(interp, 3, objv, "start end"); goto error; } - if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) { - goto error; + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[3]), + &index) != TCL_OK) { + goto error; } - - minorCmd = Tcl_GetString(objv[2]); - if (minorCmd[0] == 'm' - && (strncmp(minorCmd, "mark", strlen(minorCmd)) == 0)) { - entryPtr->scanMarkX = x; - entryPtr->scanMarkIndex = entryPtr->leftIndex; - } else if ((minorCmd[0] == 'd') - && (strncmp(minorCmd, "dragto", strlen(minorCmd)) == 0)) { - EntryScanTo(entryPtr, x); - } else { - Tcl_AppendResult(interp, "bad scan option \"", - Tcl_GetString(objv[2]), "\": must be mark or dragto", - (char *) NULL); + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[4]), + &index2) != TCL_OK) { goto error; } + if (index >= index2) { + entryPtr->selectFirst = -1; + entryPtr->selectLast = -1; + } else { + entryPtr->selectFirst = index; + entryPtr->selectLast = index2; + } + if (!(entryPtr->flags & GOT_SELECTION) + && (entryPtr->exportSelection)) { + Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, + EntryLostSelection, (ClientData) entryPtr); + entryPtr->flags |= GOT_SELECTION; + } + EventuallyRedraw(entryPtr); break; - } - - case COMMAND_SELECTION: { - int index, index2; - if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "option ?index?"); + case SELECTION_TO: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 3, objv, "index"); goto error; } - - /* - * Parse the selection sub-command, using the command - * table "selCmdNames" defined above. - */ - - result = Tcl_GetIndexFromObj(interp, objv[2], selCmdNames, - "selection option", 0, &selIndex); - if (result != TCL_OK) { + if (GetEntryIndex(interp, entryPtr, + Tcl_GetString(objv[3]), &index) != TCL_OK) { goto error; } + EntrySelectTo(entryPtr, index); + break; + } + break; + } - /* - * Disabled entries don't allow the selection to be modified, - * but 'selection present' must return a boolean. - */ - - if ((entryPtr->state == STATE_DISABLED) - && (selIndex != SELECTION_PRESENT)) { - goto done; - } - - switch (selIndex) { - case SELECTION_ADJUST: { - if (objc != 4) { - Tcl_WrongNumArgs(interp, 3, objv, "index"); - goto error; - } - if (GetEntryIndex(interp, entryPtr, - Tcl_GetString(objv[3]), &index) != TCL_OK) { - goto error; - } - if (entryPtr->selectFirst >= 0) { - int half1, half2; - - half1 = (entryPtr->selectFirst - + entryPtr->selectLast)/2; - half2 = (entryPtr->selectFirst - + entryPtr->selectLast + 1)/2; - if (index < half1) { - entryPtr->selectAnchor = entryPtr->selectLast; - } else if (index > half2) { - entryPtr->selectAnchor = entryPtr->selectFirst; - } else { - /* - * We're at about the halfway point in the - * selection; just keep the existing anchor. - */ - } - } - EntrySelectTo(entryPtr, index); - break; - } - - case SELECTION_CLEAR: { - if (objc != 3) { - Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL); - goto error; - } - if (entryPtr->selectFirst >= 0) { - entryPtr->selectFirst = -1; - entryPtr->selectLast = -1; - EventuallyRedraw(entryPtr); - } - goto done; - } - - case SELECTION_FROM: { - if (objc != 4) { - Tcl_WrongNumArgs(interp, 3, objv, "index"); - goto error; - } - if (GetEntryIndex(interp, entryPtr, - Tcl_GetString(objv[3]), &index) != TCL_OK) { - goto error; - } - entryPtr->selectAnchor = index; - break; - } + case COMMAND_VALIDATE: { + int code; - case SELECTION_PRESENT: { - if (objc != 3) { - Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL); - goto error; - } - Tcl_SetObjResult(interp, - Tcl_NewBooleanObj((entryPtr->selectFirst >= 0))); - goto done; - } - - case SELECTION_RANGE: { - if (objc != 5) { - Tcl_WrongNumArgs(interp, 3, objv, "start end"); - goto error; - } - if (GetEntryIndex(interp, entryPtr, - Tcl_GetString(objv[3]), &index) != TCL_OK) { - goto error; - } - if (GetEntryIndex(interp, entryPtr, - Tcl_GetString(objv[4]),& index2) != TCL_OK) { - goto error; - } - if (index >= index2) { - entryPtr->selectFirst = -1; - entryPtr->selectLast = -1; - } else { - entryPtr->selectFirst = index; - entryPtr->selectLast = index2; - } - if (!(entryPtr->flags & GOT_SELECTION) - && (entryPtr->exportSelection)) { - Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, - EntryLostSelection, (ClientData) entryPtr); - entryPtr->flags |= GOT_SELECTION; - } - EventuallyRedraw(entryPtr); - break; - } - - case SELECTION_TO: { - if (objc != 4) { - Tcl_WrongNumArgs(interp, 3, objv, "index"); - goto error; - } - if (GetEntryIndex(interp, entryPtr, - Tcl_GetString(objv[3]), &index) != TCL_OK) { - goto error; - } - EntrySelectTo(entryPtr, index); - break; - } - } - break; + if (objc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL); + goto error; + } + selIndex = entryPtr->validate; + entryPtr->validate = VALIDATE_ALL; + code = EntryValidateChange(entryPtr, (char *) NULL, entryPtr->string, + -1, VALIDATE_FORCED); + if (entryPtr->validate != VALIDATE_NONE) { + entryPtr->validate = selIndex; } + Tcl_SetObjResult(interp, Tcl_NewBooleanObj((code == TCL_OK))); + break; + } - case COMMAND_VALIDATE: { - int code; + case COMMAND_XVIEW: { + int index; + + if (objc == 2) { + double first, last; + char buf[TCL_DOUBLE_SPACE * 2]; - if (objc != 2) { - Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL); + EntryVisibleRange(entryPtr, &first, &last); + sprintf(buf, "%g %g", first, last); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + goto done; + } else if (objc == 3) { + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &index) != TCL_OK) { goto error; } - selIndex = entryPtr->validate; - entryPtr->validate = VALIDATE_ALL; - code = EntryValidateChange(entryPtr, (char *) NULL, - entryPtr->string, -1, VALIDATE_FORCED); - if (entryPtr->validate != VALIDATE_NONE) { - entryPtr->validate = selIndex; - } - Tcl_SetObjResult(interp, Tcl_NewBooleanObj((code == TCL_OK))); - break; - } + } else { + double fraction; + int count; - case COMMAND_XVIEW: { - int index; - - if (objc == 2) { - double first, last; - char buf[TCL_DOUBLE_SPACE * 2]; - - EntryVisibleRange(entryPtr, &first, &last); - sprintf(buf, "%g %g", first, last); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - goto done; - } else if (objc == 3) { - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), - &index) != TCL_OK) { - goto error; - } - } else { - double fraction; - int count; - - index = entryPtr->leftIndex; - switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, - &count)) { - case TK_SCROLL_ERROR: { - goto error; - } - case TK_SCROLL_MOVETO: { - index = (int) ((fraction * entryPtr->numChars) + 0.5); - break; - } - case TK_SCROLL_PAGES: { - int charsPerPage; - - charsPerPage = ((Tk_Width(entryPtr->tkwin) - - 2 * entryPtr->inset) - / entryPtr->avgWidth) - 2; - if (charsPerPage < 1) { - charsPerPage = 1; - } - index += count * charsPerPage; - break; - } - case TK_SCROLL_UNITS: { - index += count; - break; - } + index = entryPtr->leftIndex; + switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, + &count)) { + case TK_SCROLL_ERROR: + goto error; + case TK_SCROLL_MOVETO: + index = (int) ((fraction * entryPtr->numChars) + 0.5); + break; + case TK_SCROLL_PAGES: { + int charsPerPage; + + charsPerPage = ((Tk_Width(entryPtr->tkwin) + - 2 * entryPtr->inset) / entryPtr->avgWidth) - 2; + if (charsPerPage < 1) { + charsPerPage = 1; } + index += count * charsPerPage; + break; } - if (index >= entryPtr->numChars) { - index = entryPtr->numChars - 1; + case TK_SCROLL_UNITS: + index += count; + break; } - if (index < 0) { - index = 0; - } - entryPtr->leftIndex = index; - entryPtr->flags |= UPDATE_SCROLLBAR; - EntryComputeGeometry(entryPtr); - EventuallyRedraw(entryPtr); - break; } + if (index >= entryPtr->numChars) { + index = entryPtr->numChars - 1; + } + if (index < 0) { + index = 0; + } + entryPtr->leftIndex = index; + entryPtr->flags |= UPDATE_SCROLLBAR; + EntryComputeGeometry(entryPtr); + EventuallyRedraw(entryPtr); + break; + } } - done: + done: Tcl_Release((ClientData) entryPtr); return result; - error: + error: Tcl_Release((ClientData) entryPtr); return TCL_ERROR; } @@ -1048,9 +1017,9 @@ EntryWidgetObjCmd(clientData, interp, objc, objv) * * DestroyEntry -- * - * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release - * to clean up the internal structure of an entry at a safe time - * (when no-one is using it anymore). + * This function is invoked by Tcl_EventuallyFree or Tcl_Release to clean + * up the internal structure of an entry at a safe time (when no-one is + * using it anymore). * * Results: * None. @@ -1068,9 +1037,8 @@ DestroyEntry(memPtr) Entry *entryPtr = (Entry *) memPtr; /* - * Free up all the stuff that requires special handling, then - * let Tk_FreeOptions handle all the standard option-related - * stuff. + * Free up all the stuff that requires special handling, then let + * Tk_FreeOptions handle all the standard option-related stuff. */ ckfree((char *)entryPtr->string); @@ -1115,18 +1083,17 @@ DestroyEntry(memPtr) * * ConfigureEntry -- * - * This procedure is called to process an argv/argc list, plus - * the Tk option database, in order to configure (or reconfigure) - * an entry widget. + * This function is called to process an argv/argc list, plus the Tk + * option database, in order to configure (or reconfigure) an entry + * widget. * * Results: - * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then the interp's result contains an error message. + * The return value is a standard Tcl result. If TCL_ERROR is returned, + * then the interp's result contains an error message. * * Side effects: - * Configuration information, such as colors, border width, - * etc. get set for entryPtr; old resources get freed, - * if there were any. + * Configuration information, such as colors, border width, etc. get set + * for entryPtr; old resources get freed, if there were any. * *---------------------------------------------------------------------- */ @@ -1143,15 +1110,16 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags) Tk_SavedOptions savedOptions; Tk_3DBorder border; Tcl_Obj *errorResult = NULL; - Spinbox *sbPtr = (Spinbox *) entryPtr; /* Only used when this widget - * is of type TK_SPINBOX */ - char *oldValues = NULL; /* lint initialization */ - char *oldFormat = NULL; /* lint initialization */ + Spinbox *sbPtr = (Spinbox *) entryPtr; + /* Only used when this widget is of type + * TK_SPINBOX */ + char *oldValues = NULL; /* lint initialization */ + char *oldFormat = NULL; /* lint initialization */ int error; - int oldExport = 0; /* lint initialization */ - int valuesChanged = 0; /* lint initialization */ - double oldFrom = 0.0; /* lint initialization */ - double oldTo = 0.0; /* lint initialization */ + int oldExport = 0; /* lint initialization */ + int valuesChanged = 0; /* lint initialization */ + double oldFrom = 0.0; /* lint initialization */ + double oldTo = 0.0; /* lint initialization */ /* * Eliminate any existing trace on a variable monitored by the entry. @@ -1159,16 +1127,17 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags) if ((entryPtr->textVarName != NULL) && (entryPtr->flags & ENTRY_VAR_TRACED)) { - Tcl_UntraceVar(interp, entryPtr->textVarName, + Tcl_UntraceVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, EntryTextVarProc, (ClientData) entryPtr); entryPtr->flags &= ~ENTRY_VAR_TRACED; } /* - * Store old values that we need to effect certain behavior if - * they change value + * Store old values that we need to effect certain behavior if they change + * value. */ + oldExport = entryPtr->exportSelection; if (entryPtr->type == TK_SPINBOX) { oldValues = sbPtr->valueStr; @@ -1235,6 +1204,7 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags) * calculate the minimum space we'll need for the values as * strings. */ + int min, max; size_t formatLen, formatSpace = TCL_DOUBLE_SPACE; char fbuf[4], *fmt = sbPtr->reqFormat; @@ -1261,16 +1231,19 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags) formatSpace = TCL_DOUBLE_SPACE; } sbPtr->formatBuf = ckrealloc(sbPtr->formatBuf, formatSpace); + /* - * We perturb the value of oldFrom to allow us to go into - * the branch below that will reformat the displayed value. + * We perturb the value of oldFrom to allow us to go into the + * branch below that will reformat the displayed value. */ + oldFrom = sbPtr->fromValue - 1; } /* - * See if we have to rearrange our listObj data + * See if we have to rearrange our listObj data. */ + if (oldValues != sbPtr->valueStr) { if (sbPtr->listObj != NULL) { Tcl_DecrRefCount(sbPtr->listObj); @@ -1296,13 +1269,14 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags) } /* - * Restart the cursor timing sequence in case the on-time or - * off-time just changed. Set validate temporarily to none, - * so the configure doesn't cause it to be triggered. + * Restart the cursor timing sequence in case the on-time or off-time + * just changed. Set validate temporarily to none, so the configure + * doesn't cause it to be triggered. */ if (entryPtr->flags & GOT_FOCUS) { int validate = entryPtr->validate; + entryPtr->validate = VALIDATE_NONE; EntryFocusProc(entryPtr, 1); entryPtr->validate = validate; @@ -1313,8 +1287,8 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags) */ if (entryPtr->exportSelection && (!oldExport) - && (entryPtr->selectFirst != -1) - && !(entryPtr->flags & GOT_SELECTION)) { + && (entryPtr->selectFirst != -1) + && !(entryPtr->flags & GOT_SELECTION)) { Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection, (ClientData) entryPtr); entryPtr->flags |= GOT_SELECTION; @@ -1326,12 +1300,12 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags) */ Tk_SetInternalBorder(entryPtr->tkwin, - entryPtr->borderWidth + entryPtr->highlightWidth); + entryPtr->borderWidth + entryPtr->highlightWidth); if (entryPtr->highlightWidth <= 0) { entryPtr->highlightWidth = 0; } - entryPtr->inset = entryPtr->highlightWidth - + entryPtr->borderWidth + XPAD; + entryPtr->inset = entryPtr->highlightWidth + + entryPtr->borderWidth + XPAD; break; } if (!error) { @@ -1361,9 +1335,10 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags) Tcl_Obj *objPtr; /* - * No check for error return, because there shouldn't be one - * given the check for valid list above + * No check for error return, because there shouldn't be one given + * the check for valid list above. */ + Tcl_ListObjIndex(interp, sbPtr->listObj, 0, &objPtr); EntryValueChanged(entryPtr, Tcl_GetString(objPtr)); } else if ((sbPtr->valueStr == NULL) @@ -1372,10 +1347,11 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags) || !DOUBLES_EQ(sbPtr->toValue, oldTo))) { /* * If the valueStr is empty and -from && -to are specified, check - * to see if the current string is within the range. If not, - * it will be constrained to the nearest edge. If the current - * string isn't a double value, we set it to -from. + * to see if the current string is within the range. If not, it + * will be constrained to the nearest edge. If the current string + * isn't a double value, we set it to -from. */ + int code; double dvalue; @@ -1395,8 +1371,8 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags) } /* - * Set up a trace on the variable's value after we've possibly - * constrained the value according to new -from/-to values. + * Set up a trace on the variable's value after we've possibly constrained + * the value according to new -from/-to values. */ if ((entryPtr->textVarName != NULL) @@ -1409,11 +1385,11 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags) EntryWorldChanged((ClientData) entryPtr); if (error) { - Tcl_SetObjResult(interp, errorResult); + Tcl_SetObjResult(interp, errorResult); Tcl_DecrRefCount(errorResult); return TCL_ERROR; } else { - return TCL_OK; + return TCL_OK; } } @@ -1422,19 +1398,19 @@ ConfigureEntry(interp, entryPtr, objc, objv, flags) * * EntryWorldChanged -- * - * This procedure is called when the world has changed in some - * way and the widget needs to recompute all its graphics contexts - * and determine its new geometry. + * This function is called when the world has changed in some way and the + * widget needs to recompute all its graphics contexts and determine its + * new geometry. * * Results: - * None. + * None. * * Side effects: - * Entry will be relayed out and redisplayed. + * Entry will be relayed out and redisplayed. * *--------------------------------------------------------------------------- */ - + static void EntryWorldChanged(instanceData) ClientData instanceData; /* Information about widget. */ @@ -1463,27 +1439,27 @@ EntryWorldChanged(instanceData) } /* - * Default background and foreground are from the normal state. - * In a disabled state, both of those may be overridden; in the readonly - * state, the background may be overridden. + * Default background and foreground are from the normal state. In a + * disabled state, both of those may be overridden; in the readonly state, + * the background may be overridden. */ border = entryPtr->normalBorder; colorPtr = entryPtr->fgColorPtr; switch (entryPtr->state) { - case STATE_DISABLED: - if (entryPtr->disabledBorder != NULL) { - border = entryPtr->disabledBorder; - } - if (entryPtr->dfgColorPtr != NULL) { - colorPtr = entryPtr->dfgColorPtr; - } - break; - case STATE_READONLY: - if (entryPtr->readonlyBorder != NULL) { - border = entryPtr->readonlyBorder; - } - break; + case STATE_DISABLED: + if (entryPtr->disabledBorder != NULL) { + border = entryPtr->disabledBorder; + } + if (entryPtr->dfgColorPtr != NULL) { + colorPtr = entryPtr->dfgColorPtr; + } + break; + case STATE_READONLY: + if (entryPtr->readonlyBorder != NULL) { + border = entryPtr->readonlyBorder; + } + break; } Tk_SetBackgroundFromBorder(entryPtr->tkwin, border); @@ -1507,8 +1483,7 @@ EntryWorldChanged(instanceData) entryPtr->selTextGC = gc; /* - * Recompute the window's geometry and arrange for it to be - * redisplayed. + * Recompute the window's geometry and arrange for it to be redisplayed. */ EntryComputeGeometry(entryPtr); @@ -1516,18 +1491,17 @@ EntryWorldChanged(instanceData) EventuallyRedraw(entryPtr); } -#ifndef MAC_OSX_TK +#ifndef MAC_OSX_TK /* *-------------------------------------------------------------- * * TkpDrawEntryBorderAndFocus -- * - * This procedure redraws the border of an entry widget. - * It overrides the generic border drawing code if the - * entry widget parameters are such that the native widget - * drawing is a good fit. - * This version just returns o, so platforms that don't - * do special native drawing don't have to implement it. + * This function redraws the border of an entry widget. It overrides the + * generic border drawing code if the entry widget parameters are such + * that the native widget drawing is a good fit. This version just + * returns 0, so platforms that don't do special native drawing don't + * have to implement it. * * Results: * 1 if it has drawn the border, 0 if not. @@ -1546,19 +1520,17 @@ TkpDrawEntryBorderAndFocus(entryPtr, pixmap, isSpinbox) { return 0; } - - + /* *-------------------------------------------------------------- * * TkpDrawSpinboxButtons -- * - * This procedure redraws the buttons of an spinbox widget. - * It overrides the generic button drawing code if the - * spinbox widget parameters are such that the native widget - * drawing is a good fit. - * This version just returns 0, so platforms that don't - * do special native drawing don't have to implement it. + * This function redraws the buttons of an spinbox widget. It overrides + * the generic button drawing code if the spinbox widget parameters are + * such that the native widget drawing is a good fit. This version just + * returns 0, so platforms that don't do special native drawing don't + * have to implement it. * * Results: * 1 if it has drawn the border, 0 if not. @@ -1571,19 +1543,19 @@ TkpDrawEntryBorderAndFocus(entryPtr, pixmap, isSpinbox) int TkpDrawSpinboxButtons(sbPtr, pixmap) - Spinbox *sbPtr; + Spinbox *sbPtr; Pixmap pixmap; { return 0; } #endif /* Not MAC_OSX_TK */ - + /* *-------------------------------------------------------------- * * DisplayEntry -- * - * This procedure redraws the contents of an entry window. + * This function redraws the contents of an entry window. * * Results: * None. @@ -1620,9 +1592,9 @@ DisplayEntry(clientData) if (entryPtr->flags & UPDATE_SCROLLBAR) { entryPtr->flags &= ~UPDATE_SCROLLBAR; - /* - * Preserve/Release because updating the scrollbar can have - * the side-effect of destroying or unmapping the entry widget. + /* + * Preserve/Release because updating the scrollbar can have the + * side-effect of destroying or unmapping the entry widget. */ Tcl_Preserve((ClientData) entryPtr); @@ -1636,26 +1608,26 @@ DisplayEntry(clientData) } /* - * In order to avoid screen flashes, this procedure redraws the - * textual area of the entry into off-screen memory, then copies - * it back on-screen in a single operation. This means there's - * no point in time where the on-screen image has been cleared. + * In order to avoid screen flashes, this function redraws the textual + * area of the entry into off-screen memory, then copies it back on-screen + * in a single operation. This means there's no point in time where the + * on-screen image has been cleared. */ pixmap = Tk_GetPixmap(entryPtr->display, Tk_WindowId(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin)); /* - * Compute x-coordinate of the pixel just after last visible - * one, plus vertical position of baseline of text. + * Compute x-coordinate of the pixel just after last visible one, plus + * vertical position of baseline of text. */ xBound = Tk_Width(tkwin) - entryPtr->inset - entryPtr->xWidth; baseY = (Tk_Height(tkwin) + fm.ascent - fm.descent) / 2; /* - * On Windows and Mac, we need to hide the selection whenever we - * don't have the focus. + * On Windows and Mac, we need to hide the selection whenever we don't + * have the focus. */ #ifdef ALWAYS_SHOW_SELECTION @@ -1665,9 +1637,9 @@ DisplayEntry(clientData) #endif /* - * Draw the background in three layers. From bottom to top the - * layers are: normal background, selection background, and - * insertion cursor background. + * Draw the background in three layers. From bottom to top the layers are: + * normal background, selection background, and insertion cursor + * background. */ if ((entryPtr->state == STATE_DISABLED) && @@ -1701,16 +1673,16 @@ DisplayEntry(clientData) (selEndX - selStartX) + 2*entryPtr->selBorderWidth, (fm.ascent + fm.descent) + 2*entryPtr->selBorderWidth, entryPtr->selBorderWidth, TK_RELIEF_RAISED); - } + } } /* - * Draw a special background for the insertion cursor, overriding - * even the selection background. As a special hack to keep the - * cursor visible when the insertion cursor color is the same as - * the color for selected text (e.g., on mono displays), write - * background in the cursor area (instead of nothing) when the - * cursor isn't on. Otherwise the selection would hide the cursor. + * Draw a special background for the insertion cursor, overriding even the + * selection background. As a special hack to keep the cursor visible when + * the insertion cursor color is the same as the color for selected text + * (e.g., on mono displays), write background in the cursor area (instead + * of nothing) when the cursor isn't on. Otherwise the selection would + * hide the cursor. */ if ((entryPtr->state == STATE_NORMAL) && (entryPtr->flags & GOT_FOCUS)) { @@ -1720,25 +1692,22 @@ DisplayEntry(clientData) cursorX -= (entryPtr->insertWidth)/2; Tk_SetCaretPos(entryPtr->tkwin, cursorX, baseY - fm.ascent, fm.ascent + fm.descent); - if (entryPtr->insertPos >= entryPtr->leftIndex) { - if (cursorX < xBound) { - if (entryPtr->flags & CURSOR_ON) { - Tk_Fill3DRectangle(tkwin, pixmap, entryPtr->insertBorder, - cursorX, baseY - fm.ascent, entryPtr->insertWidth, - fm.ascent + fm.descent, - entryPtr->insertBorderWidth, - TK_RELIEF_RAISED); - } else if (entryPtr->insertBorder == entryPtr->selBorder) { - Tk_Fill3DRectangle(tkwin, pixmap, border, - cursorX, baseY - fm.ascent, entryPtr->insertWidth, - fm.ascent + fm.descent, 0, TK_RELIEF_FLAT); - } + if (entryPtr->insertPos >= entryPtr->leftIndex && cursorX < xBound) { + if (entryPtr->flags & CURSOR_ON) { + Tk_Fill3DRectangle(tkwin, pixmap, entryPtr->insertBorder, + cursorX, baseY - fm.ascent, entryPtr->insertWidth, + fm.ascent + fm.descent, entryPtr->insertBorderWidth, + TK_RELIEF_RAISED); + } else if (entryPtr->insertBorder == entryPtr->selBorder) { + Tk_Fill3DRectangle(tkwin, pixmap, border, cursorX, + baseY - fm.ascent, entryPtr->insertWidth, + fm.ascent + fm.descent, 0, TK_RELIEF_FLAT); } } } /* - * Draw the text in two pieces: first the unselected portion, then the + * Draw the text in two pieces: first the unselected portion, then the * selected portion on top of it. */ @@ -1768,17 +1737,18 @@ DisplayEntry(clientData) /* * Draw the spin button controls. */ - if (TkpDrawSpinboxButtons(sbPtr, pixmap) == 0) { - xWidth = entryPtr->xWidth; - pad = XPAD + 1; - inset = entryPtr->inset - XPAD; - startx = Tk_Width(tkwin) - (xWidth + inset); - height = (Tk_Height(tkwin) - 2*inset)/2; + + if (TkpDrawSpinboxButtons(sbPtr, pixmap) == 0) { + xWidth = entryPtr->xWidth; + pad = XPAD + 1; + inset = entryPtr->inset - XPAD; + startx = Tk_Width(tkwin) - (xWidth + inset); + height = (Tk_Height(tkwin) - 2*inset)/2; #if 0 - Tk_Fill3DRectangle(tkwin, pixmap, sbPtr->buttonBorder, - startx, inset, xWidth, height, 1, sbPtr->buRelief); - Tk_Fill3DRectangle(tkwin, pixmap, sbPtr->buttonBorder, - startx, inset+height, xWidth, height, 1, sbPtr->bdRelief); + Tk_Fill3DRectangle(tkwin, pixmap, sbPtr->buttonBorder, + startx, inset, xWidth, height, 1, sbPtr->buRelief); + Tk_Fill3DRectangle(tkwin, pixmap, sbPtr->buttonBorder, + startx, inset+height, xWidth, height, 1, sbPtr->bdRelief); #else Tk_Fill3DRectangle(tkwin, pixmap, sbPtr->buttonBorder, startx, inset, xWidth, height, 1, @@ -1789,89 +1759,96 @@ DisplayEntry(clientData) (sbPtr->selElement == SEL_BUTTONDOWN) ? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED); #endif - - xWidth -= 2*pad; - /* - * Only draw the triangles if we have enough display space - */ - if ((xWidth > 1)) { - XPoint points[3]; - int starty, space, offset; - - space = height - 2*pad; - /* - * Ensure width of triangle is odd to guarantee a sharp tip - */ - if (!(xWidth % 2)) { - xWidth++; - } - tHeight = (xWidth + 1) / 2; - if (tHeight > space) { - tHeight = space; - } - space = (space - tHeight) / 2; - startx += pad; - starty = inset + height - pad - space; - offset = (sbPtr->selElement == SEL_BUTTONUP); - /* - * The points are slightly different for the up and down arrows - * because (for *.x), we need to account for a bug in the way - * XFillPolygon draws triangles, and we want to shift - * the arrows differently when allowing for depressed behavior. - */ - points[0].x = startx + offset; - points[0].y = starty + (offset ? 0 : -1); - points[1].x = startx + xWidth/2 + offset; - points[1].y = starty - tHeight + (offset ? 0 : -1); - points[2].x = startx + xWidth + offset; - points[2].y = points[0].y; - XFillPolygon(entryPtr->display, pixmap, entryPtr->textGC, - points, 3, Convex, CoordModeOrigin); - - starty = inset + height + pad + space; - offset = (sbPtr->selElement == SEL_BUTTONDOWN); - points[0].x = startx + 1 + offset; - points[0].y = starty + (offset ? 1 : 0); - points[1].x = startx + xWidth/2 + offset; - points[1].y = starty + tHeight + (offset ? 0 : -1); - points[2].x = startx - 1 + xWidth + offset; - points[2].y = points[0].y; - XFillPolygon(entryPtr->display, pixmap, entryPtr->textGC, - points, 3, Convex, CoordModeOrigin); - } - } + + xWidth -= 2*pad; + + /* + * Only draw the triangles if we have enough display space + */ + + if ((xWidth > 1)) { + XPoint points[3]; + int starty, space, offset; + + space = height - 2*pad; + + /* + * Ensure width of triangle is odd to guarantee a sharp tip + */ + + if (!(xWidth % 2)) { + xWidth++; + } + tHeight = (xWidth + 1) / 2; + if (tHeight > space) { + tHeight = space; + } + space = (space - tHeight) / 2; + startx += pad; + starty = inset + height - pad - space; + offset = (sbPtr->selElement == SEL_BUTTONUP); + + /* + * The points are slightly different for the up and down + * arrows because (for *.x), we need to account for a bug in + * the way XFillPolygon draws triangles, and we want to shift + * the arrows differently when allowing for depressed + * behavior. + */ + + points[0].x = startx + offset; + points[0].y = starty + (offset ? 0 : -1); + points[1].x = startx + xWidth/2 + offset; + points[1].y = starty - tHeight + (offset ? 0 : -1); + points[2].x = startx + xWidth + offset; + points[2].y = points[0].y; + XFillPolygon(entryPtr->display, pixmap, entryPtr->textGC, + points, 3, Convex, CoordModeOrigin); + + starty = inset + height + pad + space; + offset = (sbPtr->selElement == SEL_BUTTONDOWN); + points[0].x = startx + 1 + offset; + points[0].y = starty + (offset ? 1 : 0); + points[1].x = startx + xWidth/2 + offset; + points[1].y = starty + tHeight + (offset ? 0 : -1); + points[2].x = startx - 1 + xWidth + offset; + points[2].y = points[0].y; + XFillPolygon(entryPtr->display, pixmap, entryPtr->textGC, + points, 3, Convex, CoordModeOrigin); + } + } } /* - * Draw the border and focus highlight last, so they will overwrite - * any text that extends past the viewable part of the window. + * Draw the border and focus highlight last, so they will overwrite any + * text that extends past the viewable part of the window. */ - if (!TkpDrawEntryBorderAndFocus(entryPtr, pixmap, - (entryPtr->type == TK_SPINBOX))) { - xBound = entryPtr->highlightWidth; - if (entryPtr->relief != TK_RELIEF_FLAT) { + if (!TkpDrawEntryBorderAndFocus(entryPtr, pixmap, + (entryPtr->type == TK_SPINBOX))) { + xBound = entryPtr->highlightWidth; + if (entryPtr->relief != TK_RELIEF_FLAT) { Tk_Draw3DRectangle(tkwin, pixmap, border, xBound, xBound, - Tk_Width(tkwin) - 2 * xBound, + Tk_Width(tkwin) - 2 * xBound, Tk_Height(tkwin) - 2 * xBound, entryPtr->borderWidth, entryPtr->relief); - } - if (xBound > 0) { + } + if (xBound > 0) { GC fgGC, bgGC; bgGC = Tk_GCForColor(entryPtr->highlightBgColorPtr, pixmap); if (entryPtr->flags & GOT_FOCUS) { - fgGC = Tk_GCForColor(entryPtr->highlightColorPtr, pixmap); - TkpDrawHighlightBorder(tkwin, fgGC, bgGC, xBound, pixmap); + fgGC = Tk_GCForColor(entryPtr->highlightColorPtr, pixmap); + TkpDrawHighlightBorder(tkwin, fgGC, bgGC, xBound, pixmap); } else { - TkpDrawHighlightBorder(tkwin, bgGC, bgGC, xBound, pixmap); + TkpDrawHighlightBorder(tkwin, bgGC, bgGC, xBound, pixmap); } - } + } } /* - * Everything's been redisplayed; now copy the pixmap onto the screen - * and free up the pixmap. + * Everything's been redisplayed; now copy the pixmap onto the screen and + * free up the pixmap. */ XCopyArea(entryPtr->display, pixmap, Tk_WindowId(tkwin), entryPtr->textGC, @@ -1886,17 +1863,17 @@ DisplayEntry(clientData) * * EntryComputeGeometry -- * - * This procedure is invoked to recompute information about where - * in its window an entry's string will be displayed. It also - * computes the requested size for the window. + * This function is invoked to recompute information about where in its + * window an entry's string will be displayed. It also computes the + * requested size for the window. * * Results: * None. * * Side effects: - * The leftX and tabOrigin fields are recomputed for entryPtr, - * and leftIndex may be adjusted. Tk_GeometryRequest is called - * to register the desired dimensions for the window. + * The leftX and tabOrigin fields are recomputed for entryPtr, and + * leftIndex may be adjusted. Tk_GeometryRequest is called to register + * the desired dimensions for the window. * *---------------------------------------------------------------------- */ @@ -1917,8 +1894,8 @@ EntryComputeGeometry(entryPtr) } /* - * If we're displaying a special character instead of the value of - * the entry, recompute the displayString. + * If we're displaying a special character instead of the value of the + * entry, recompute the displayString. */ if (entryPtr->showChar != NULL) { @@ -1927,10 +1904,10 @@ EntryComputeGeometry(entryPtr) int size; /* - * Normalize the special character so we can safely duplicate it - * in the display string. If we didn't do this, then two malformed - * characters might end up looking like one valid UTF character in - * the resulting string. + * Normalize the special character so we can safely duplicate it in + * the display string. If we didn't do this, then two malformed + * characters might end up looking like one valid UTF character in the + * resulting string. */ Tcl_UtfToUniChar(entryPtr->showChar, &ch); @@ -1954,21 +1931,21 @@ EntryComputeGeometry(entryPtr) entryPtr->layoutY = (Tk_Height(entryPtr->tkwin) - height) / 2; /* - * Recompute where the leftmost character on the display will - * be drawn (entryPtr->leftX) and adjust leftIndex if necessary - * so that we don't let characters hang off the edge of the - * window unless the entire window is full. + * Recompute where the leftmost character on the display will be drawn + * (entryPtr->leftX) and adjust leftIndex if necessary so that we don't + * let characters hang off the edge of the window unless the entire window + * is full. */ overflow = totalLength - - (Tk_Width(entryPtr->tkwin) - 2*entryPtr->inset - entryPtr->xWidth); + (Tk_Width(entryPtr->tkwin) - 2*entryPtr->inset - entryPtr->xWidth); if (overflow <= 0) { entryPtr->leftIndex = 0; if (entryPtr->justify == TK_JUSTIFY_LEFT) { entryPtr->leftX = entryPtr->inset; } else if (entryPtr->justify == TK_JUSTIFY_RIGHT) { entryPtr->leftX = Tk_Width(entryPtr->tkwin) - entryPtr->inset - - entryPtr->xWidth - totalLength; + - entryPtr->xWidth - totalLength; } else { entryPtr->leftX = (Tk_Width(entryPtr->tkwin) - entryPtr->xWidth - totalLength)/2; @@ -1976,10 +1953,10 @@ EntryComputeGeometry(entryPtr) entryPtr->layoutX = entryPtr->leftX; } else { /* - * The whole string can't fit in the window. Compute the - * maximum number of characters that may be off-screen to - * the left without leaving empty space on the right of the - * window, then don't let leftIndex be any greater than that. + * The whole string can't fit in the window. Compute the maximum + * number of characters that may be off-screen to the left without + * leaving empty space on the right of the window, then don't let + * leftIndex be any greater than that. */ maxOffScreen = Tk_PointToChar(entryPtr->textLayout, overflow, 0); @@ -2028,8 +2005,8 @@ EntryComputeGeometry(entryPtr) * None. * * Side effects: - * New information gets added to entryPtr; it will be redisplayed - * soon, but not necessarily immediately. + * New information gets added to entryPtr; it will be redisplayed soon, + * but not necessarily immediately. * *---------------------------------------------------------------------- */ @@ -2037,8 +2014,8 @@ EntryComputeGeometry(entryPtr) static void InsertChars(entryPtr, index, value) Entry *entryPtr; /* Entry that is to get the new elements. */ - int index; /* Add the new elements before this - * character index. */ + int index; /* Add the new elements before this character + * index. */ char *value; /* New characters to add (NULL-terminated * string). */ { @@ -2060,9 +2037,9 @@ InsertChars(entryPtr, index, value) strcpy(new + byteIndex + byteCount, string + byteIndex); if ((entryPtr->validate == VALIDATE_KEY || - entryPtr->validate == VALIDATE_ALL) && - EntryValidateChange(entryPtr, value, new, index, - VALIDATE_INSERT) != TCL_OK) { + entryPtr->validate == VALIDATE_ALL) && + EntryValidateChange(entryPtr, value, new, index, + VALIDATE_INSERT) != TCL_OK) { ckfree(new); return; } @@ -2071,13 +2048,12 @@ InsertChars(entryPtr, index, value) entryPtr->string = new; /* - * The following construction is used because inserting improperly - * formed UTF-8 sequences between other improperly formed UTF-8 - * sequences could result in actually forming valid UTF-8 sequences; - * the number of characters added may not be Tcl_NumUtfChars(string, -1), - * because of context. The actual number of characters added is how - * many characters are in the string now minus the number that - * used to be there. + * The following construction is used because inserting improperly formed + * UTF-8 sequences between other improperly formed UTF-8 sequences could + * result in actually forming valid UTF-8 sequences; the number of + * characters added may not be Tcl_NumUtfChars(string, -1), because of + * context. The actual number of characters added is how many characters + * are in the string now minus the number that used to be there. */ oldChars = entryPtr->numChars; @@ -2091,11 +2067,11 @@ InsertChars(entryPtr, index, value) } /* - * Inserting characters invalidates all indexes into the string. - * Touch up the indexes so that they still refer to the same - * characters (at new positions). When updating the selection - * end-points, don't include the new text in the selection unless - * it was completely surrounded by the selection. + * Inserting characters invalidates all indexes into the string. Touch up + * the indexes so that they still refer to the same characters (at new + * positions). When updating the selection end-points, don't include the + * new text in the selection unless it was completely surrounded by the + * selection. */ if (entryPtr->selectFirst >= index) { @@ -2104,8 +2080,7 @@ InsertChars(entryPtr, index, value) if (entryPtr->selectLast > index) { entryPtr->selectLast += charsAdded; } - if ((entryPtr->selectAnchor > index) - || (entryPtr->selectFirst >= index)) { + if ((entryPtr->selectAnchor > index) || (entryPtr->selectFirst >= index)) { entryPtr->selectAnchor += charsAdded; } if (entryPtr->leftIndex > index) { @@ -2153,7 +2128,7 @@ DeleteChars(entryPtr, index, count) string = entryPtr->string; byteIndex = Tcl_UtfAtIndex(string, index) - string; - byteCount = Tcl_UtfAtIndex(string + byteIndex, count) - (string + byteIndex); + byteCount = Tcl_UtfAtIndex(string + byteIndex, count) - (string+byteIndex); newByteCount = entryPtr->numBytes + 1 - byteCount; new = (char *) ckalloc((unsigned) newByteCount); @@ -2165,9 +2140,9 @@ DeleteChars(entryPtr, index, count) todelete[byteCount] = '\0'; if ((entryPtr->validate == VALIDATE_KEY || - entryPtr->validate == VALIDATE_ALL) && - EntryValidateChange(entryPtr, todelete, new, index, - VALIDATE_DELETE) != TCL_OK) { + entryPtr->validate == VALIDATE_ALL) && + EntryValidateChange(entryPtr, todelete, new, index, + VALIDATE_DELETE) != TCL_OK) { ckfree(new); ckfree(todelete); return; @@ -2186,8 +2161,8 @@ DeleteChars(entryPtr, index, count) /* * Deleting characters results in the remaining characters being - * renumbered. Update the various indexes into the string to reflect - * this change. + * renumbered. Update the various indexes into the string to reflect this + * change. */ if (entryPtr->selectFirst >= index) { @@ -2237,10 +2212,9 @@ DeleteChars(entryPtr, index, count) * * EntryValueChanged -- * - * This procedure is invoked when characters are inserted into - * an entry or deleted from it. It updates the entry's associated - * variable, if there is one, and does other bookkeeping such - * as arranging for redisplay. + * This function is invoked when characters are inserted into an entry or + * deleted from it. It updates the entry's associated variable, if there + * is one, and does other bookkeeping such as arranging for redisplay. * * Results: * None. @@ -2254,8 +2228,8 @@ DeleteChars(entryPtr, index, count) static void EntryValueChanged(entryPtr, newValue) Entry *entryPtr; /* Entry whose value just changed. */ - CONST char *newValue; /* If this value is not NULL, we first - * force the value of the entry to this */ + CONST char *newValue; /* If this value is not NULL, we first force + * the value of the entry to this. */ { if (newValue != NULL) { EntrySetValue(entryPtr, newValue); @@ -2271,10 +2245,10 @@ EntryValueChanged(entryPtr, newValue) if ((newValue != NULL) && (strcmp(newValue, entryPtr->string) != 0)) { /* * The value of the variable is different than what we asked for. - * This means that a trace on the variable modified it. In this - * case our trace procedure wasn't invoked since the modification - * came while a trace was already active on the variable. So, - * update our value to reflect the variable's latest value. + * This means that a trace on the variable modified it. In this case + * our trace function wasn't invoked since the modification came while + * a trace was already active on the variable. So, update our value to + * reflect the variable's latest value. */ EntrySetValue(entryPtr, newValue); @@ -2294,19 +2268,19 @@ EntryValueChanged(entryPtr, newValue) * * EntrySetValue -- * - * Replace the contents of a text entry with a given value. This - * procedure is invoked when updating the entry from the entry's - * associated variable. + * Replace the contents of a text entry with a given value. This function + * is invoked when updating the entry from the entry's associated + * variable. * * Results: * None. * * Side effects: - * The string displayed in the entry will change. The selection, - * insertion point, and view may have to be adjusted to keep them - * within the bounds of the new string. Note: this procedure does - * *not* update the entry's associated variable, since that could - * result in an infinite loop. + * The string displayed in the entry will change. The selection, + * insertion point, and view may have to be adjusted to keep them within + * the bounds of the new string. Note: this function does *not* update + * the entry's associated variable, since that could result in an + * infinite loop. * *---------------------------------------------------------------------- */ @@ -2328,11 +2302,13 @@ EntrySetValue(entryPtr, value) entryPtr->flags |= VALIDATE_ABORT; } else { /* - * If we validate, we create a copy of the value, as it may - * point to volatile memory, like the value of the -textvar - * which may get freed during validation + * If we validate, we create a copy of the value, as it may point to + * volatile memory, like the value of the -textvar which may get freed + * during validation */ + char *tmp = (char *) ckalloc((unsigned) (valueLen + 1)); + strcpy(tmp, value); value = tmp; malloced = 1; @@ -2341,10 +2317,12 @@ EntrySetValue(entryPtr, value) (void) EntryValidateChange(entryPtr, (char *) NULL, value, -1, VALIDATE_FORCED); entryPtr->flags &= ~VALIDATE_VAR; + /* * If VALIDATE_ABORT has been set, then this operation should be * aborted because the validatecommand did something else instead */ + if (entryPtr->flags & VALIDATE_ABORT) { entryPtr->flags &= ~VALIDATE_ABORT; ckfree((char *)value); @@ -2359,6 +2337,7 @@ EntrySetValue(entryPtr, value) entryPtr->string = value; } else { char *tmp = (char *) ckalloc((unsigned) (valueLen + 1)); + strcpy(tmp, value); entryPtr->string = tmp; } @@ -2399,15 +2378,15 @@ EntrySetValue(entryPtr, value) * * EntryEventProc -- * - * This procedure is invoked by the Tk dispatcher for various - * events on entries. + * This function is invoked by the Tk dispatcher for various events on + * entries. * * Results: * None. * * Side effects: - * When the window gets deleted, internal structures get - * cleaned up. When it gets exposed, it is redisplayed. + * When the window gets deleted, internal structures get cleaned up. + * When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */ @@ -2446,34 +2425,33 @@ EntryEventProc(clientData, eventPtr) } switch (eventPtr->type) { - case Expose: - EventuallyRedraw(entryPtr); - entryPtr->flags |= BORDER_NEEDED; - break; - case DestroyNotify: - if (!(entryPtr->flags & ENTRY_DELETED)) { - entryPtr->flags |= (ENTRY_DELETED | VALIDATE_ABORT); - Tcl_DeleteCommandFromToken(entryPtr->interp, - entryPtr->widgetCmd); - if (entryPtr->flags & REDRAW_PENDING) { - Tcl_CancelIdleCall(DisplayEntry, clientData); - } - Tcl_EventuallyFree(clientData, DestroyEntry); - } - break; - case ConfigureNotify: - Tcl_Preserve((ClientData) entryPtr); - entryPtr->flags |= UPDATE_SCROLLBAR; - EntryComputeGeometry(entryPtr); - EventuallyRedraw(entryPtr); - Tcl_Release((ClientData) entryPtr); - break; - case FocusIn: - case FocusOut: - if (eventPtr->xfocus.detail != NotifyInferior) { - EntryFocusProc(entryPtr, (eventPtr->type == FocusIn)); + case Expose: + EventuallyRedraw(entryPtr); + entryPtr->flags |= BORDER_NEEDED; + break; + case DestroyNotify: + if (!(entryPtr->flags & ENTRY_DELETED)) { + entryPtr->flags |= (ENTRY_DELETED | VALIDATE_ABORT); + Tcl_DeleteCommandFromToken(entryPtr->interp, entryPtr->widgetCmd); + if (entryPtr->flags & REDRAW_PENDING) { + Tcl_CancelIdleCall(DisplayEntry, clientData); } - break; + Tcl_EventuallyFree(clientData, DestroyEntry); + } + break; + case ConfigureNotify: + Tcl_Preserve((ClientData) entryPtr); + entryPtr->flags |= UPDATE_SCROLLBAR; + EntryComputeGeometry(entryPtr); + EventuallyRedraw(entryPtr); + Tcl_Release((ClientData) entryPtr); + break; + case FocusIn: + case FocusOut: + if (eventPtr->xfocus.detail != NotifyInferior) { + EntryFocusProc(entryPtr, (eventPtr->type == FocusIn)); + } + break; } } @@ -2482,9 +2460,9 @@ EntryEventProc(clientData, eventPtr) * * EntryCmdDeletedProc -- * - * 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. + * This function 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. @@ -2502,14 +2480,14 @@ EntryCmdDeletedProc(clientData) Entry *entryPtr = (Entry *) 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. + * This function 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 function destroys the + * widget. */ if (!(entryPtr->flags & ENTRY_DELETED)) { - Tk_DestroyWindow(entryPtr->tkwin); + Tk_DestroyWindow(entryPtr->tkwin); } } @@ -2518,15 +2496,14 @@ EntryCmdDeletedProc(clientData) * * GetEntryIndex -- * - * Parse an index into an entry and return either its value - * or an error. + * Parse an index into an entry and return either its value or an error. * * Results: - * A standard Tcl result. If all went well, then *indexPtr is - * filled in with the character index (into entryPtr) corresponding to - * string. The index value is guaranteed to lie between 0 and - * the number of characters in the string, inclusive. If an - * error occurs then an error message is left in the interp's result. + * A standard Tcl result. If all went well, then *indexPtr is filled in + * with the character index (into entryPtr) corresponding to string. The + * index value is guaranteed to lie between 0 and the number of + * characters in the string, inclusive. If an error occurs then an error + * message is left in the interp's result. * * Side effects: * None. @@ -2551,7 +2528,7 @@ GetEntryIndex(interp, entryPtr, string, indexPtr) if (strncmp(string, "anchor", length) == 0) { *indexPtr = entryPtr->selectAnchor; } else { - badIndex: + badIndex: /* * Some of the paths here leave messages in the interp's result, @@ -2613,10 +2590,10 @@ GetEntryIndex(interp, entryPtr, string, indexPtr) x - entryPtr->layoutX, 0); /* - * Special trick: if the x-position was off-screen to the right, - * round the index up to refer to the character just after the - * last visible one on the screen. This is needed to enable the - * last character to be selected, for example. + * Special trick: if the x-position was off-screen to the right, round + * the index up to refer to the character just after the last visible + * one on the screen. This is needed to enable the last character to + * be selected, for example. */ if (roundUp && (*indexPtr < entryPtr->numChars)) { @@ -2630,7 +2607,7 @@ GetEntryIndex(interp, entryPtr, string, indexPtr) *indexPtr = 0; } else if (*indexPtr > entryPtr->numChars) { *indexPtr = entryPtr->numChars; - } + } } return TCL_OK; } @@ -2640,8 +2617,8 @@ GetEntryIndex(interp, entryPtr, string, indexPtr) * * EntryScanTo -- * - * Given a y-coordinate (presumably of the curent mouse location) - * drag the view in the window to implement the scan operation. + * Given a y-coordinate (presumably of the curent mouse location) drag + * the view in the window to implement the scan operation. * * Results: * None. @@ -2660,14 +2637,14 @@ EntryScanTo(entryPtr, x) int newLeftIndex; /* - * Compute new leftIndex for entry by amplifying the difference - * between the current position and the place where the scan - * started (the "mark" position). If we run off the left or right - * side of the entry, then reset the mark point so that the current - * position continues to correspond to the edge of the window. - * This means that the picture will start dragging as soon as the - * mouse reverses direction (without this reset, might have to slide - * mouse a long ways back before the picture starts moving again). + * Compute new leftIndex for entry by amplifying the difference between + * the current position and the place where the scan started (the "mark" + * position). If we run off the left or right side of the entry, then + * reset the mark point so that the current position continues to + * correspond to the edge of the window. This means that the picture will + * start dragging as soon as the mouse reverses direction (without this + * reset, might have to slide mouse a long ways back before the picture + * starts moving again). */ newLeftIndex = entryPtr->scanMarkIndex @@ -2679,7 +2656,7 @@ EntryScanTo(entryPtr, x) if (newLeftIndex < 0) { newLeftIndex = entryPtr->scanMarkIndex = 0; entryPtr->scanMarkX = x; - } + } if (newLeftIndex != entryPtr->leftIndex) { entryPtr->leftIndex = newLeftIndex; @@ -2698,8 +2675,8 @@ EntryScanTo(entryPtr, x) * * EntrySelectTo -- * - * Modify the selection by moving its un-anchored end. This could - * make the selection either larger or smaller. + * Modify the selection by moving its un-anchored end. This could make + * the selection either larger or smaller. * * Results: * None. @@ -2759,15 +2736,15 @@ EntrySelectTo(entryPtr, index) * * EntryFetchSelection -- * - * This procedure is called back by Tk when the selection is - * requested by someone. It returns part or all of the selection - * in a buffer provided by the caller. + * This function is called back by Tk when the selection is requested by + * someone. It returns part or all of the selection in a buffer provided + * by the caller. * * Results: - * The return value is the number of non-NULL bytes stored - * at buffer. Buffer is filled (or partially filled) with a - * NULL-terminated string containing part or all of the selection, - * as given by offset and maxBytes. + * The return value is the number of non-NULL bytes stored at buffer. + * Buffer is filled (or partially filled) with a NULL-terminated string + * containing part or all of the selection, as given by offset and + * maxBytes. * * Side effects: * None. @@ -2781,8 +2758,8 @@ EntryFetchSelection(clientData, offset, buffer, maxBytes) int offset; /* Byte offset within selection of first * character to be returned. */ char *buffer; /* Location in which to place selection. */ - int maxBytes; /* Maximum number of bytes to place at - * buffer, not including terminating NULL + int maxBytes; /* Maximum number of bytes to place at buffer, + * not including terminating NULL * character. */ { Entry *entryPtr = (Entry *) clientData; @@ -2814,15 +2791,15 @@ EntryFetchSelection(clientData, offset, buffer, maxBytes) * * EntryLostSelection -- * - * This procedure is called back by Tk when the selection is - * grabbed away from an entry widget. + * This function is called back by Tk when the selection is grabbed away + * from an entry widget. * * Results: * None. * * Side effects: - * The existing selection is unhighlighted, and the window is - * marked as not containing a selection. + * The existing selection is unhighlighted, and the window is marked as + * not containing a selection. * *---------------------------------------------------------------------- */ @@ -2836,9 +2813,9 @@ EntryLostSelection(clientData) entryPtr->flags &= ~GOT_SELECTION; /* - * On Windows and Mac systems, we want to remember the selection - * for the next time the focus enters the window. On Unix, we need - * to clear the selection since it is always visible. + * On Windows and Mac systems, we want to remember the selection for the + * next time the focus enters the window. On Unix, we need to clear the + * selection since it is always visible. */ #ifdef ALWAYS_SHOW_SELECTION @@ -2861,10 +2838,10 @@ EntryLostSelection(clientData) * None. * * Side effects: - * Information gets redisplayed. Right now we don't do selective - * redisplays: the whole window will be redrawn. This doesn't - * seem to hurt performance noticeably, but if it does then this - * could be changed. + * Information gets redisplayed. Right now we don't do selective + * redisplays: the whole window will be redrawn. This doesn't seem to + * hurt performance noticeably, but if it does then this could be + * changed. * *---------------------------------------------------------------------- */ @@ -2878,9 +2855,9 @@ EventuallyRedraw(entryPtr) } /* - * Right now we don't do selective redisplays: the whole window - * will be redrawn. This doesn't seem to hurt performance noticeably, - * but if it does then this could be changed. + * Right now we don't do selective redisplays: the whole window will be + * redrawn. This doesn't seem to hurt performance noticeably, but if it + * does then this could be changed. */ if (!(entryPtr->flags & REDRAW_PENDING)) { @@ -2894,13 +2871,12 @@ EventuallyRedraw(entryPtr) * * EntryVisibleRange -- * - * Return information about the range of the entry that is - * currently visible. + * Return information about the range of the entry that is currently + * visible. * * Results: - * *firstPtr and *lastPtr are modified to hold fractions between - * 0 and 1 identifying the range of characters visible in the - * entry. + * *firstPtr and *lastPtr are modified to hold fractions between 0 and 1 + * identifying the range of characters visible in the entry. * * Side effects: * None. @@ -2911,8 +2887,8 @@ EventuallyRedraw(entryPtr) static void EntryVisibleRange(entryPtr, firstPtr, lastPtr) Entry *entryPtr; /* Information about widget. */ - double *firstPtr; /* Return position of first visible - * character in widget. */ + double *firstPtr; /* Return position of first visible character + * in widget. */ double *lastPtr; /* Return position of char just after last * visible one. */ { @@ -2944,10 +2920,10 @@ EntryVisibleRange(entryPtr, firstPtr, lastPtr) * * EntryUpdateScrollbar -- * - * This procedure is invoked whenever information has changed in - * an entry in a way that would invalidate a scrollbar display. - * If there is an associated scrollbar, then this procedure updates - * it by invoking a Tcl command. + * This function is invoked whenever information has changed in an entry + * in a way that would invalidate a scrollbar display. If there is an + * associated scrollbar, then this function updates it by invoking a Tcl + * command. * * Results: * None. @@ -2993,15 +2969,15 @@ EntryUpdateScrollbar(entryPtr) * * EntryBlinkProc -- * - * This procedure is called as a timer handler to blink the - * insertion cursor off and on. + * This function is called as a timer handler to blink the insertion + * cursor off and on. * * Results: * None. * * Side effects: - * The cursor gets turned on or off, redisplay gets invoked, - * and this procedure reschedules itself. + * The cursor gets turned on or off, redisplay gets invoked, and this + * function reschedules itself. * *---------------------------------------------------------------------- */ @@ -3034,9 +3010,9 @@ EntryBlinkProc(clientData) * * EntryFocusProc -- * - * This procedure is called whenever the entry gets or loses the - * input focus. It's also called whenever the window is reconfigured - * while it has the focus. + * This function is called whenever the entry gets or loses the input + * focus. It's also called whenever the window is reconfigured while it + * has the focus. * * Results: * None. @@ -3085,15 +3061,14 @@ EntryFocusProc(entryPtr, gotFocus) * * EntryTextVarProc -- * - * This procedure is invoked when someone changes the variable - * whose contents are to be displayed in an entry. + * This function is invoked when someone changes the variable whose + * contents are to be displayed in an entry. * * Results: * NULL is always returned. * * Side effects: - * The text displayed in the entry will change to match the - * variable. + * The text displayed in the entry will change to match the variable. * *-------------------------------------------------------------- */ @@ -3118,8 +3093,8 @@ EntryTextVarProc(clientData, interp, name1, name2, flags) } /* - * If the variable is unset, then immediately recreate it unless - * the whole interpreter is going away. + * If the variable is unset, then immediately recreate it unless the whole + * interpreter is going away. */ if (flags & TCL_TRACE_UNSETS) { @@ -3135,10 +3110,9 @@ EntryTextVarProc(clientData, interp, name1, name2, flags) } /* - * Update the entry's text with the value of the variable, unless - * the entry already has that value (this happens when the variable - * changes value because we changed it because someone typed in - * the entry). + * Update the entry's text with the value of the variable, unless the + * entry already has that value (this happens when the variable changes + * value because we changed it because someone typed in the entry). */ value = Tcl_GetVar(interp, entryPtr->textVarName, TCL_GLOBAL_ONLY); @@ -3154,17 +3128,17 @@ EntryTextVarProc(clientData, interp, name1, name2, flags) * * EntryValidate -- * - * This procedure is invoked when any character is added or - * removed from the entry widget, or a focus has trigerred validation. + * This function is invoked when any character is added or removed from + * the entry widget, or a focus has trigerred validation. * * Results: - * TCL_OK if the validatecommand passes the new string. - * TCL_BREAK if the vcmd executed OK, but rejects the string. - * TCL_ERROR if an error occurred while executing the vcmd - * or a valid Tcl_Bool is not returned. + + * TCL_OK if the validatecommand passes the new string. TCL_BREAK if the + * vcmd executed OK, but rejects the string. TCL_ERROR if an error + * occurred while executing the vcmd or a valid Tcl_Bool is not returned. * * Side effects: - * An error condition may arise + * An error condition may arise * *-------------------------------------------------------------- */ @@ -3181,9 +3155,10 @@ EntryValidate(entryPtr, cmd) code = Tcl_EvalEx(interp, cmd, -1, TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT); /* - * We accept TCL_OK and TCL_RETURN as valid return codes from the - * command callback. + * We accept TCL_OK and TCL_RETURN as valid return codes from the command + * callback. */ + if (code != TCL_OK && code != TCL_RETURN) { Tcl_AddErrorInfo(interp, "\n\t(in validation command executed by "); Tcl_AddErrorInfo(interp, Tk_PathName(entryPtr->tkwin)); @@ -3195,8 +3170,9 @@ EntryValidate(entryPtr, cmd) /* * The command callback should return an acceptable Tcl boolean. */ + if (Tcl_GetBooleanFromObj(interp, Tcl_GetObjResult(interp), - &bool) != TCL_OK) { + &bool) != TCL_OK) { Tcl_AddErrorInfo(interp, "\nvalid boolean not returned by validation command"); Tcl_BackgroundError(interp); @@ -3213,17 +3189,16 @@ EntryValidate(entryPtr, cmd) * * EntryValidateChange -- * - * This procedure is invoked when any character is added or - * removed from the entry widget, or a focus has trigerred validation. + * This function is invoked when any character is added or removed from + * the entry widget, or a focus has trigerred validation. * * Results: - * TCL_OK if the validatecommand accepts the new string, - * TCL_ERROR if any problems occured with validatecommand. + * TCL_OK if the validatecommand accepts the new string, TCL_ERROR if any + * problems occured with validatecommand. * * Side effects: - * The insertion/deletion may be aborted, and the - * validatecommand might turn itself off (if an error - * or loop condition arises). + * The insertion/deletion may be aborted, and the validatecommand might + * turn itself off (if an error or loop condition arises). * *-------------------------------------------------------------- */ @@ -3233,25 +3208,26 @@ EntryValidateChange(entryPtr, change, new, index, type) register Entry *entryPtr; /* Entry that needs validation. */ char *change; /* Characters to be added/deleted * (NULL-terminated string). */ - CONST char *new; /* Potential new value of entry string */ - int index; /* index of insert/delete, -1 otherwise */ - int type; /* forced, delete, insert, - * focusin or focusout */ + CONST char *new; /* Potential new value of entry string */ + int index; /* index of insert/delete, -1 otherwise */ + int type; /* forced, delete, insert, focusin or + * focusout */ { int code, varValidate = (entryPtr->flags & VALIDATE_VAR); char *p; Tcl_DString script; - + if (entryPtr->validateCmd == NULL || entryPtr->validate == VALIDATE_NONE) { return (varValidate ? TCL_ERROR : TCL_OK); } /* - * If we're already validating, then we're hitting a loop condition - * Return and set validate to 0 to disallow further validations - * and prevent current validation from finishing + * If we're already validating, then we're hitting a loop condition Return + * and set validate to 0 to disallow further validations and prevent + * current validation from finishing */ + if (entryPtr->flags & VALIDATING) { entryPtr->validate = VALIDATE_NONE; return (varValidate ? TCL_ERROR : TCL_OK); @@ -3273,10 +3249,10 @@ EntryValidateChange(entryPtr, change, new, index, type) Tcl_DStringFree(&script); /* - * If e->validate has become VALIDATE_NONE during the validation, or - * we now have VALIDATE_VAR set (from EntrySetValue) and didn't before, - * it means that a loop condition almost occured. Do not allow - * this validation result to finish. + * If e->validate has become VALIDATE_NONE during the validation, or we + * now have VALIDATE_VAR set (from EntrySetValue) and didn't before, it + * means that a loop condition almost occured. Do not allow this + * validation result to finish. */ if (entryPtr->validate == VALIDATE_NONE @@ -3285,8 +3261,8 @@ EntryValidateChange(entryPtr, change, new, index, type) } /* - * It's possible that the user deleted the entry during validation. - * In that case, abort future validation and return an error. + * It's possible that the user deleted the entry during validation. In + * that case, abort future validation and return an error. */ if (entryPtr->flags & ENTRY_DELETED) { @@ -3295,20 +3271,19 @@ EntryValidateChange(entryPtr, change, new, index, type) /* * If validate will return ERROR, then disallow further validations - * Otherwise, if it didn't accept the new string (returned TCL_BREAK) - * then eval the invalidCmd (if it's set) + * Otherwise, if it didn't accept the new string (returned TCL_BREAK) then + * eval the invalidCmd (if it's set) */ if (code == TCL_ERROR) { entryPtr->validate = VALIDATE_NONE; } else if (code == TCL_BREAK) { /* - * If we were doing forced validation (like via a variable - * trace) and the command returned 0, the we turn off validation - * because we assume that textvariables have precedence in - * managing the value. We also don't call the invcmd, as it - * may want to do entry manipulation which the setting of the - * var will later wipe anyway. + * If we were doing forced validation (like via a variable trace) and + * the command returned 0, the we turn off validation because we + * assume that textvariables have precedence in managing the value. + * We also don't call the invcmd, as it may want to do entry + * manipulation which the setting of the var will later wipe anyway. */ if (varValidate) { @@ -3316,13 +3291,13 @@ EntryValidateChange(entryPtr, change, new, index, type) } else if (entryPtr->invalidCmd != NULL) { Tcl_DStringInit(&script); ExpandPercents(entryPtr, entryPtr->invalidCmd, - change, new, index, type, &script); + change, new, index, type, &script); Tcl_DStringAppend(&script, "", 1); p = Tcl_DStringValue(&script); if (Tcl_EvalEx(entryPtr->interp, p, -1, TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT) != TCL_OK) { Tcl_AddErrorInfo(entryPtr->interp, - "\n\t(in invalidcommand executed by entry)"); + "\n\t(in invalidcommand executed by entry)"); Tcl_BackgroundError(entryPtr->interp); code = TCL_ERROR; entryPtr->validate = VALIDATE_NONE; @@ -3330,8 +3305,9 @@ EntryValidateChange(entryPtr, change, new, index, type) Tcl_DStringFree(&script); /* - * It's possible that the user deleted the entry during validation. - * In that case, abort future validation and return an error. + * It's possible that the user deleted the entry during + * validation. In that case, abort future validation and return an + * error. */ if (entryPtr->flags & ENTRY_DELETED) { @@ -3350,13 +3326,12 @@ EntryValidateChange(entryPtr, change, new, index, type) * * ExpandPercents -- * - * Given a command and an event, produce a new command - * by replacing % constructs in the original command - * with information from the X event. + * Given a command and an event, produce a new command by replacing % + * constructs in the original command with information from the X event. * * Results: - * The new expanded command is appended to the dynamic string - * given by dsPtr. + * The new expanded command is appended to the dynamic string given by + * dsPtr. * * Side effects: * None. @@ -3368,8 +3343,8 @@ static void ExpandPercents(entryPtr, before, change, new, index, type, dsPtr) register Entry *entryPtr; /* Entry that needs validation. */ register CONST char *before; - /* Command containing percent - * expressions to be replaced. */ + /* Command containing percent expressions to + * be replaced. */ char *change; /* Characters to added/deleted * (NULL-terminated string). */ CONST char *new; /* Potential new value of entry string */ @@ -3390,12 +3365,16 @@ ExpandPercents(entryPtr, before, change, new, index, type, dsPtr) break; } /* - * Find everything up to the next % character and append it - * to the result string. + * Find everything up to the next % character and append it to the + * result string. */ string = before; - /* No need to convert '%', as it is in ascii range */ + + /* + * No need to convert '%', as it is in ascii range. + */ + string = Tcl_UtfFindFirst(before, '%'); if (string == (char *) NULL) { Tcl_DStringAppend(dsPtr, before, -1); @@ -3406,7 +3385,7 @@ ExpandPercents(entryPtr, before, change, new, index, type, dsPtr) } /* - * There's a percent sequence here. Process it. + * There's a percent sequence here. Process it. */ before++; /* skip over % */ @@ -3419,80 +3398,82 @@ ExpandPercents(entryPtr, before, change, new, index, type, dsPtr) /* * -command %-substitution */ + switch (ch) { - case 's': /* Current string value of spinbox */ - string = entryPtr->string; - break; - case 'd': /* direction, up or down */ - string = change; - break; - case 'W': /* widget name */ - string = Tk_PathName(entryPtr->tkwin); - break; - default: - length = Tcl_UniCharToUtf(ch, numStorage); - numStorage[length] = '\0'; - string = numStorage; - break; + case 's': /* Current string value of spinbox */ + string = entryPtr->string; + break; + case 'd': /* direction, up or down */ + string = change; + break; + case 'W': /* widget name */ + string = Tk_PathName(entryPtr->tkwin); + break; + default: + length = Tcl_UniCharToUtf(ch, numStorage); + numStorage[length] = '\0'; + string = numStorage; + break; } } else { /* * -validatecommand / -invalidcommand %-substitution */ + switch (ch) { - case 'd': /* Type of call that caused validation */ - switch (type) { - case VALIDATE_INSERT: - number = 1; - break; - case VALIDATE_DELETE: - number = 0; - break; - default: - number = -1; - break; - } - sprintf(numStorage, "%d", number); - string = numStorage; - break; - case 'i': /* index of insert/delete */ - sprintf(numStorage, "%d", index); - string = numStorage; - break; - case 'P': /* 'Peeked' new value of the string */ - string = new; + case 'd': /* Type of call that caused validation */ + switch (type) { + case VALIDATE_INSERT: + number = 1; break; - case 's': /* Current string value of spinbox */ - string = entryPtr->string; + case VALIDATE_DELETE: + number = 0; break; - case 'S': /* string to be inserted/deleted, if any */ - string = change; - break; - case 'v': /* type of validation currently set */ - string = validateStrings[entryPtr->validate]; + default: + number = -1; break; - case 'V': /* type of validation in effect */ - switch (type) { - case VALIDATE_INSERT: - case VALIDATE_DELETE: - string = validateStrings[VALIDATE_KEY]; - break; - case VALIDATE_FORCED: - string = "forced"; - break; - default: - string = validateStrings[type]; - break; - } + } + sprintf(numStorage, "%d", number); + string = numStorage; + break; + case 'i': /* index of insert/delete */ + sprintf(numStorage, "%d", index); + string = numStorage; + break; + case 'P': /* 'Peeked' new value of the string */ + string = new; + break; + case 's': /* Current string value of spinbox */ + string = entryPtr->string; + break; + case 'S': /* string to be inserted/deleted, if any */ + string = change; + break; + case 'v': /* type of validation currently set */ + string = validateStrings[entryPtr->validate]; + break; + case 'V': /* type of validation in effect */ + switch (type) { + case VALIDATE_INSERT: + case VALIDATE_DELETE: + string = validateStrings[VALIDATE_KEY]; break; - case 'W': /* widget name */ - string = Tk_PathName(entryPtr->tkwin); + case VALIDATE_FORCED: + string = "forced"; break; default: - length = Tcl_UniCharToUtf(ch, numStorage); - numStorage[length] = '\0'; - string = numStorage; + string = validateStrings[type]; break; + } + break; + case 'W': /* widget name */ + string = Tk_PathName(entryPtr->tkwin); + break; + default: + length = Tcl_UniCharToUtf(ch, numStorage); + numStorage[length] = '\0'; + string = numStorage; + break; } } @@ -3511,9 +3492,8 @@ ExpandPercents(entryPtr, before, change, new, index, type, dsPtr) * * Tk_SpinboxObjCmd -- * - * This procedure is invoked to process the "spinbox" Tcl - * command. See the user documentation for details on what - * it does. + * This function is invoked to process the "spinbox" Tcl command. See the + * user documentation for details on what it does. * * Results: * A standard Tcl result. @@ -3529,7 +3509,7 @@ Tk_SpinboxObjCmd(clientData, interp, objc, objv) ClientData clientData; /* NULL. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ - Tcl_Obj *CONST objv[]; /* Argument objects. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ { register Entry *entryPtr; register Spinbox *sbPtr; @@ -3543,23 +3523,23 @@ Tk_SpinboxObjCmd(clientData, interp, objc, objv) } tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp), - Tcl_GetString(objv[1]), (char *) NULL); + Tcl_GetString(objv[1]), (char *) NULL); if (tkwin == NULL) { return TCL_ERROR; } /* - * Create the option table for this widget class. If it has already - * been created, Tk will return the cached value. + * Create the option table for this widget class. If it has already been + * created, Tk will return the cached value. */ optionTable = Tk_CreateOptionTable(interp, sbOptSpec); /* - * Initialize the fields of the structure that won't be initialized - * by ConfigureEntry, or that ConfigureEntry requires to be - * initialized already (e.g. resource pointers). Only the non-NULL/0 - * data must be initialized as memset covers the rest. + * Initialize the fields of the structure that won't be initialized by + * ConfigureEntry, or that ConfigureEntry requires to be initialized + * already (e.g. resource pointers). Only the non-NULL/0 data must be + * initialized as memset covers the rest. */ sbPtr = (Spinbox *) ckalloc(sizeof(Spinbox)); @@ -3628,7 +3608,7 @@ Tk_SpinboxObjCmd(clientData, interp, objc, objv) if (ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0) != TCL_OK) { goto error; } - + Tcl_SetResult(interp, Tk_PathName(entryPtr->tkwin), TCL_STATIC); return TCL_OK; @@ -3642,9 +3622,9 @@ Tk_SpinboxObjCmd(clientData, interp, objc, objv) * * SpinboxWidgetObjCmd -- * - * 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. + * This function 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. @@ -3673,8 +3653,8 @@ SpinboxWidgetObjCmd(clientData, interp, objc, objv) } /* - * Parse the widget command by looking up the second token in - * the list of valid command names. + * Parse the widget command by looking up the second token in the list of + * valid command names. */ result = Tcl_GetIndexFromObj(interp, objv[1], sbCmdNames, @@ -3685,471 +3665,452 @@ SpinboxWidgetObjCmd(clientData, interp, objc, objv) Tcl_Preserve((ClientData) entryPtr); switch ((enum sbCmd) cmdIndex) { - case SB_CMD_BBOX: { - int index, x, y, width, height; - char buf[TCL_INTEGER_SPACE * 4]; + case SB_CMD_BBOX: { + int index, x, y, width, height; + char buf[TCL_INTEGER_SPACE * 4]; - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "index"); - goto error; - } - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), - &index) != TCL_OK) { - goto error; - } - if ((index == entryPtr->numChars) && (index > 0)) { - index--; - } - Tk_CharBbox(entryPtr->textLayout, index, &x, &y, - &width, &height); - sprintf(buf, "%d %d %d %d", x + entryPtr->layoutX, - y + entryPtr->layoutY, width, height); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - break; - } - - case SB_CMD_CGET: { - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "option"); - goto error; - } - - objPtr = Tk_GetOptionValue(interp, (char *) entryPtr, - entryPtr->optionTable, objv[2], entryPtr->tkwin); - if (objPtr == NULL) { - goto error; - } else { - Tcl_SetObjResult(interp, objPtr); - } - break; + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "index"); + goto error; + } + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &index) != TCL_OK) { + goto error; } + if ((index == entryPtr->numChars) && (index > 0)) { + index--; + } + Tk_CharBbox(entryPtr->textLayout, index, &x, &y, + &width, &height); + sprintf(buf, "%d %d %d %d", x + entryPtr->layoutX, + y + entryPtr->layoutY, width, height); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + break; + } - case SB_CMD_CONFIGURE: { - if (objc <= 3) { - objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr, - entryPtr->optionTable, - (objc == 3) ? objv[2] : (Tcl_Obj *) NULL, - entryPtr->tkwin); - if (objPtr == NULL) { - goto error; - } else { - Tcl_SetObjResult(interp, objPtr); - } - } else { - result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0); - } - break; + case SB_CMD_CGET: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "option"); + goto error; } - case SB_CMD_DELETE: { - int first, last; + objPtr = Tk_GetOptionValue(interp, (char *) entryPtr, + entryPtr->optionTable, objv[2], entryPtr->tkwin); + if (objPtr == NULL) { + goto error; + } else { + Tcl_SetObjResult(interp, objPtr); + } + break; - if ((objc < 3) || (objc > 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?"); + case SB_CMD_CONFIGURE: + if (objc <= 3) { + objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr, + entryPtr->optionTable, + (objc == 3) ? objv[2] : (Tcl_Obj *) NULL, + entryPtr->tkwin); + if (objPtr == NULL) { goto error; - } - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), - &first) != TCL_OK) { - goto error; - } - if (objc == 3) { - last = first + 1; } else { - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[3]), - &last) != TCL_OK) { - goto error; - } - } - if ((last >= first) && (entryPtr->state == STATE_NORMAL)) { - DeleteChars(entryPtr, first, last - first); + Tcl_SetObjResult(interp, objPtr); } - break; + } else { + result = ConfigureEntry(interp, entryPtr, objc-2, objv+2, 0); } + break; - case SB_CMD_GET: { - if (objc != 2) { - Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL); + case SB_CMD_DELETE: { + int first, last; + + if ((objc < 3) || (objc > 4)) { + Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?"); + goto error; + } + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &first) != TCL_OK) { + goto error; + } + if (objc == 3) { + last = first + 1; + } else { + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[3]), + &last) != TCL_OK) { goto error; } - Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1); - break; } + if ((last >= first) && (entryPtr->state == STATE_NORMAL)) { + DeleteChars(entryPtr, first, last - first); + } + break; + } - case SB_CMD_ICURSOR: { - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "pos"); + case SB_CMD_GET: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL); + goto error; + } + Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1); + break; + + case SB_CMD_ICURSOR: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "pos"); + goto error; + } + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &entryPtr->insertPos) != TCL_OK) { + goto error; + } + EventuallyRedraw(entryPtr); + break; + + case SB_CMD_IDENTIFY: { + int x, y, elem; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "x y"); + goto error; + } + if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || + (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { + goto error; + } + elem = GetSpinboxElement(sbPtr, x, y); + if (elem != SEL_NONE) { + Tcl_SetStringObj(Tcl_GetObjResult(interp), + selElementNames[elem], -1); + } + break; + } + + case SB_CMD_INDEX: { + int index; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "string"); + goto error; + } + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &index) != TCL_OK) { + goto error; + } + Tcl_SetObjResult(interp, Tcl_NewIntObj(index)); + break; + } + + case SB_CMD_INSERT: { + int index; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "index text"); + goto error; + } + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &index) != TCL_OK) { + goto error; + } + if (entryPtr->state == STATE_NORMAL) { + InsertChars(entryPtr, index, Tcl_GetString(objv[3])); + } + break; + } + + case SB_CMD_INVOKE: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "elemName"); + goto error; + } + result = Tcl_GetIndexFromObj(interp, objv[2], + selElementNames, "element", 0, &cmdIndex); + if (result != TCL_OK) { + goto error; + } + if (entryPtr->state != STATE_DISABLED) { + if (SpinboxInvoke(interp, sbPtr, cmdIndex) != TCL_OK) { goto error; } - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), - &entryPtr->insertPos) != TCL_OK) { - goto error; - } - EventuallyRedraw(entryPtr); - break; } - - case SB_CMD_IDENTIFY: { - int x, y, elem; + break; + + case SB_CMD_SCAN: { + int x; + char *minorCmd; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x"); + goto error; + } + if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) { + goto error; + } + minorCmd = Tcl_GetString(objv[2]); + if (minorCmd[0] == 'm' + && (strncmp(minorCmd, "mark", strlen(minorCmd)) == 0)) { + entryPtr->scanMarkX = x; + entryPtr->scanMarkIndex = entryPtr->leftIndex; + } else if ((minorCmd[0] == 'd') + && (strncmp(minorCmd, "dragto", strlen(minorCmd)) == 0)) { + EntryScanTo(entryPtr, x); + } else { + Tcl_AppendResult(interp, "bad scan option \"", + Tcl_GetString(objv[2]), "\": must be mark or dragto", + (char *) NULL); + goto error; + } + break; + } + + case SB_CMD_SELECTION: { + int index, index2; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "option ?index?"); + goto error; + } + + /* + * Parse the selection sub-command, using the command table + * "sbSelCmdNames" defined above. + */ + + result = Tcl_GetIndexFromObj(interp, objv[2], sbSelCmdNames, + "selection option", 0, &selIndex); + if (result != TCL_OK) { + goto error; + } + + /* + * Disabled entries don't allow the selection to be modified, but + * 'selection present' must return a boolean. + */ + + if ((entryPtr->state == STATE_DISABLED) + && (selIndex != SB_SEL_PRESENT)) { + goto done; + } + + switch (selIndex) { + case SB_SEL_ADJUST: if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "x y"); + Tcl_WrongNumArgs(interp, 3, objv, "index"); goto error; } - if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || - (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { + if (GetEntryIndex(interp, entryPtr, + Tcl_GetString(objv[3]), &index) != TCL_OK) { goto error; } - elem = GetSpinboxElement(sbPtr, x, y); - if (elem != SEL_NONE) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), - selElementNames[elem], -1); + if (entryPtr->selectFirst >= 0) { + int half1, half2; + + half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2; + half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2; + if (index < half1) { + entryPtr->selectAnchor = entryPtr->selectLast; + } else if (index > half2) { + entryPtr->selectAnchor = entryPtr->selectFirst; + } else { + /* + * We're at about the halfway point in the selection; just + * keep the existing anchor. + */ + } } + EntrySelectTo(entryPtr, index); break; - } - - case SB_CMD_INDEX: { - int index; + case SB_SEL_CLEAR: if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "string"); + Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL); goto error; } - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), - &index) != TCL_OK) { - goto error; + if (entryPtr->selectFirst >= 0) { + entryPtr->selectFirst = -1; + entryPtr->selectLast = -1; + EventuallyRedraw(entryPtr); } - Tcl_SetObjResult(interp, Tcl_NewIntObj(index)); - break; - } - - case SB_CMD_INSERT: { - int index; + goto done; + case SB_SEL_FROM: if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "index text"); + Tcl_WrongNumArgs(interp, 3, objv, "index"); goto error; } - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), - &index) != TCL_OK) { - goto error; - } - if (entryPtr->state == STATE_NORMAL) { - InsertChars(entryPtr, index, Tcl_GetString(objv[3])); + if (GetEntryIndex(interp, entryPtr, + Tcl_GetString(objv[3]), &index) != TCL_OK) { + goto error; } + entryPtr->selectAnchor = index; break; - } - case SB_CMD_INVOKE: { + case SB_SEL_PRESENT: if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "elemName"); + Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL); goto error; } - result = Tcl_GetIndexFromObj(interp, objv[2], - selElementNames, "element", 0, &cmdIndex); - if (result != TCL_OK) { + Tcl_SetObjResult(interp, + Tcl_NewBooleanObj((entryPtr->selectFirst >= 0))); + goto done; + + case SB_SEL_RANGE: + if (objc != 5) { + Tcl_WrongNumArgs(interp, 3, objv, "start end"); goto error; } - if (entryPtr->state != STATE_DISABLED) { - if (SpinboxInvoke(interp, sbPtr, cmdIndex) != TCL_OK) { - goto error; - } - } - break; - } - - case SB_CMD_SCAN: { - int x; - char *minorCmd; - - if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x"); + if (GetEntryIndex(interp, entryPtr, + Tcl_GetString(objv[3]), &index) != TCL_OK) { goto error; } - if (Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) { - goto error; + if (GetEntryIndex(interp, entryPtr, + Tcl_GetString(objv[4]),& index2) != TCL_OK) { + goto error; } - - minorCmd = Tcl_GetString(objv[2]); - if (minorCmd[0] == 'm' - && (strncmp(minorCmd, "mark", strlen(minorCmd)) == 0)) { - entryPtr->scanMarkX = x; - entryPtr->scanMarkIndex = entryPtr->leftIndex; - } else if ((minorCmd[0] == 'd') - && (strncmp(minorCmd, "dragto", strlen(minorCmd)) == 0)) { - EntryScanTo(entryPtr, x); + if (index >= index2) { + entryPtr->selectFirst = -1; + entryPtr->selectLast = -1; } else { - Tcl_AppendResult(interp, "bad scan option \"", - Tcl_GetString(objv[2]), "\": must be mark or dragto", - (char *) NULL); - goto error; + entryPtr->selectFirst = index; + entryPtr->selectLast = index2; + } + if (!(entryPtr->flags & GOT_SELECTION) + && (entryPtr->exportSelection)) { + Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, + EntryLostSelection, (ClientData) entryPtr); + entryPtr->flags |= GOT_SELECTION; } + EventuallyRedraw(entryPtr); break; - } - - case SB_CMD_SELECTION: { - int index, index2; - if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "option ?index?"); + case SB_SEL_TO: + if (objc != 4) { + Tcl_WrongNumArgs(interp, 3, objv, "index"); goto error; } - - /* - * Parse the selection sub-command, using the command - * table "sbSelCmdNames" defined above. - */ - - result = Tcl_GetIndexFromObj(interp, objv[2], sbSelCmdNames, - "selection option", 0, &selIndex); - if (result != TCL_OK) { - goto error; + if (GetEntryIndex(interp, entryPtr, + Tcl_GetString(objv[3]), &index) != TCL_OK) { + goto error; } + EntrySelectTo(entryPtr, index); + break; - /* - * Disabled entries don't allow the selection to be modified, - * but 'selection present' must return a boolean. - */ - - if ((entryPtr->state == STATE_DISABLED) - && (selIndex != SB_SEL_PRESENT)) { - goto done; + case SB_SEL_ELEMENT: + if ((objc < 3) || (objc > 4)) { + Tcl_WrongNumArgs(interp, 3, objv, "?elemName?"); + goto error; } + if (objc == 3) { + Tcl_SetStringObj(Tcl_GetObjResult(interp), + selElementNames[sbPtr->selElement], -1); + } else { + int lastElement = sbPtr->selElement; - switch (selIndex) { - case SB_SEL_ADJUST: { - if (objc != 4) { - Tcl_WrongNumArgs(interp, 3, objv, "index"); - goto error; - } - if (GetEntryIndex(interp, entryPtr, - Tcl_GetString(objv[3]), &index) != TCL_OK) { - goto error; - } - if (entryPtr->selectFirst >= 0) { - int half1, half2; - - half1 = (entryPtr->selectFirst - + entryPtr->selectLast)/2; - half2 = (entryPtr->selectFirst - + entryPtr->selectLast + 1)/2; - if (index < half1) { - entryPtr->selectAnchor = entryPtr->selectLast; - } else if (index > half2) { - entryPtr->selectAnchor = entryPtr->selectFirst; - } else { - /* - * We're at about the halfway point in the - * selection; just keep the existing anchor. - */ - } - } - EntrySelectTo(entryPtr, index); - break; - } - - case SB_SEL_CLEAR: { - if (objc != 3) { - Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL); - goto error; - } - if (entryPtr->selectFirst >= 0) { - entryPtr->selectFirst = -1; - entryPtr->selectLast = -1; - EventuallyRedraw(entryPtr); - } - goto done; - } - - case SB_SEL_FROM: { - if (objc != 4) { - Tcl_WrongNumArgs(interp, 3, objv, "index"); - goto error; - } - if (GetEntryIndex(interp, entryPtr, - Tcl_GetString(objv[3]), &index) != TCL_OK) { - goto error; - } - entryPtr->selectAnchor = index; - break; - } - - case SB_SEL_PRESENT: { - if (objc != 3) { - Tcl_WrongNumArgs(interp, 3, objv, (char *) NULL); - goto error; - } - Tcl_SetObjResult(interp, - Tcl_NewBooleanObj((entryPtr->selectFirst >= 0))); - goto done; + result = Tcl_GetIndexFromObj(interp, objv[3], selElementNames, + "selection element", 0, &(sbPtr->selElement)); + if (result != TCL_OK) { + goto error; } - - case SB_SEL_RANGE: { - if (objc != 5) { - Tcl_WrongNumArgs(interp, 3, objv, "start end"); - goto error; - } - if (GetEntryIndex(interp, entryPtr, - Tcl_GetString(objv[3]), &index) != TCL_OK) { - goto error; - } - if (GetEntryIndex(interp, entryPtr, - Tcl_GetString(objv[4]),& index2) != TCL_OK) { - goto error; - } - if (index >= index2) { - entryPtr->selectFirst = -1; - entryPtr->selectLast = -1; - } else { - entryPtr->selectFirst = index; - entryPtr->selectLast = index2; - } - if (!(entryPtr->flags & GOT_SELECTION) - && (entryPtr->exportSelection)) { - Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, - EntryLostSelection, (ClientData) entryPtr); - entryPtr->flags |= GOT_SELECTION; - } + if (lastElement != sbPtr->selElement) { EventuallyRedraw(entryPtr); - break; - } - - case SB_SEL_TO: { - if (objc != 4) { - Tcl_WrongNumArgs(interp, 3, objv, "index"); - goto error; - } - if (GetEntryIndex(interp, entryPtr, - Tcl_GetString(objv[3]), &index) != TCL_OK) { - goto error; - } - EntrySelectTo(entryPtr, index); - break; - } - - case SB_SEL_ELEMENT: { - if ((objc < 3) || (objc > 4)) { - Tcl_WrongNumArgs(interp, 3, objv, "?elemName?"); - goto error; - } - if (objc == 3) { - Tcl_SetStringObj(Tcl_GetObjResult(interp), - selElementNames[sbPtr->selElement], -1); - } else { - int lastElement = sbPtr->selElement; - - result = Tcl_GetIndexFromObj(interp, objv[3], - selElementNames, "selection element", 0, - &(sbPtr->selElement)); - if (result != TCL_OK) { - goto error; - } - if (lastElement != sbPtr->selElement) { - EventuallyRedraw(entryPtr); - } - } - break; } } break; } + break; + } - case SB_CMD_SET: { - if (objc > 3) { - Tcl_WrongNumArgs(interp, 2, objv, "?string?"); - goto error; - } - if (objc == 3) { - EntryValueChanged(entryPtr, Tcl_GetString(objv[2])); - } - Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1); - break; + case SB_CMD_SET: + if (objc > 3) { + Tcl_WrongNumArgs(interp, 2, objv, "?string?"); + goto error; + } + if (objc == 3) { + EntryValueChanged(entryPtr, Tcl_GetString(objv[2])); } + Tcl_SetStringObj(Tcl_GetObjResult(interp), entryPtr->string, -1); + break; - case SB_CMD_VALIDATE: { - int code; + case SB_CMD_VALIDATE: { + int code; - if (objc != 2) { - Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL); + if (objc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, (char *) NULL); + goto error; + } + selIndex = entryPtr->validate; + entryPtr->validate = VALIDATE_ALL; + code = EntryValidateChange(entryPtr, (char *) NULL, entryPtr->string, + -1, VALIDATE_FORCED); + if (entryPtr->validate != VALIDATE_NONE) { + entryPtr->validate = selIndex; + } + Tcl_SetObjResult(interp, Tcl_NewBooleanObj((code == TCL_OK))); + break; + } + + case SB_CMD_XVIEW: { + int index; + + if (objc == 2) { + double first, last; + char buf[TCL_DOUBLE_SPACE * 2]; + + EntryVisibleRange(entryPtr, &first, &last); + sprintf(buf, "%g %g", first, last); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + goto done; + } else if (objc == 3) { + if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), + &index) != TCL_OK) { goto error; } - selIndex = entryPtr->validate; - entryPtr->validate = VALIDATE_ALL; - code = EntryValidateChange(entryPtr, (char *) NULL, - entryPtr->string, -1, VALIDATE_FORCED); - if (entryPtr->validate != VALIDATE_NONE) { - entryPtr->validate = selIndex; - } - Tcl_SetObjResult(interp, Tcl_NewBooleanObj((code == TCL_OK))); - break; - } + } else { + double fraction; + int count; - case SB_CMD_XVIEW: { - int index; - - if (objc == 2) { - double first, last; - char buf[TCL_DOUBLE_SPACE * 2]; - - EntryVisibleRange(entryPtr, &first, &last); - sprintf(buf, "%g %g", first, last); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - goto done; - } else if (objc == 3) { - if (GetEntryIndex(interp, entryPtr, Tcl_GetString(objv[2]), - &index) != TCL_OK) { - goto error; - } - } else { - double fraction; - int count; - - index = entryPtr->leftIndex; - switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, - &count)) { - case TK_SCROLL_ERROR: { - goto error; - } - case TK_SCROLL_MOVETO: { - index = (int) ((fraction * entryPtr->numChars) + 0.5); - break; - } - case TK_SCROLL_PAGES: { - int charsPerPage; - - charsPerPage = ((Tk_Width(entryPtr->tkwin) - - 2 * entryPtr->inset - entryPtr->xWidth) - / entryPtr->avgWidth) - 2; - if (charsPerPage < 1) { - charsPerPage = 1; - } - index += count * charsPerPage; - break; - } - case TK_SCROLL_UNITS: { - index += count; - break; - } + index = entryPtr->leftIndex; + switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, + &count)) { + case TK_SCROLL_ERROR: + goto error; + case TK_SCROLL_MOVETO: + index = (int) ((fraction * entryPtr->numChars) + 0.5); + break; + case TK_SCROLL_PAGES: { + int charsPerPage; + + charsPerPage = ((Tk_Width(entryPtr->tkwin) + - 2 * entryPtr->inset - entryPtr->xWidth) + / entryPtr->avgWidth) - 2; + if (charsPerPage < 1) { + charsPerPage = 1; } + index += count * charsPerPage; + break; } - if (index >= entryPtr->numChars) { - index = entryPtr->numChars - 1; - } - if (index < 0) { - index = 0; + case TK_SCROLL_UNITS: + index += count; + break; } - entryPtr->leftIndex = index; - entryPtr->flags |= UPDATE_SCROLLBAR; - EntryComputeGeometry(entryPtr); - EventuallyRedraw(entryPtr); - break; } + if (index >= entryPtr->numChars) { + index = entryPtr->numChars - 1; + } + if (index < 0) { + index = 0; + } + entryPtr->leftIndex = index; + entryPtr->flags |= UPDATE_SCROLLBAR; + EntryComputeGeometry(entryPtr); + EventuallyRedraw(entryPtr); + break; + } } - done: + done: Tcl_Release((ClientData) entryPtr); return result; - error: + error: Tcl_Release((ClientData) entryPtr); return TCL_ERROR; } @@ -4199,25 +4160,25 @@ GetSpinboxElement(sbPtr, x, y) * * SpinboxInvoke -- * - * This procedure is invoked when the invoke method for the - * widget is called. + * This function is invoked when the invoke method for the widget is + * called. * * Results: * TCL_OK. * * Side effects: - * An background error condition may arise when invoking the - * callback. The widget value may change. + * An background error condition may arise when invoking the callback. + * The widget value may change. * *-------------------------------------------------------------- */ static int SpinboxInvoke(interp, sbPtr, element) - register Tcl_Interp *interp; /* Current interpreter. */ - register Spinbox *sbPtr; /* Spinbox to invoke. */ - int element; /* element to invoke, either the "up" - * or "down" button. */ + register Tcl_Interp *interp;/* Current interpreter. */ + register Spinbox *sbPtr; /* Spinbox to invoke. */ + int element; /* Element to invoke, either the "up" or + * "down" button. */ { Entry *entryPtr = (Entry *) sbPtr; char *type; @@ -4225,16 +4186,16 @@ SpinboxInvoke(interp, sbPtr, element) Tcl_DString script; switch (element) { - case SEL_BUTTONUP: - type = "up"; - up = 1; - break; - case SEL_BUTTONDOWN: - type = "down"; - up = 0; - break; - default: - return TCL_OK; + case SEL_BUTTONUP: + type = "up"; + up = 1; + break; + case SEL_BUTTONDOWN: + type = "down"; + up = 0; + break; + default: + return TCL_OK; } if (fabs(sbPtr->increment) > MIN_DBL_VAL) { @@ -4244,11 +4205,11 @@ SpinboxInvoke(interp, sbPtr, element) Tcl_ListObjIndex(interp, sbPtr->listObj, sbPtr->eIndex, &objPtr); if (strcmp(Tcl_GetString(objPtr), entryPtr->string)) { /* - * Somehow the string changed from what we expected, - * so let's do a search on the list to see if the current - * value is there. If not, move to the first element of - * the list. + * Somehow the string changed from what we expected, so let's + * do a search on the list to see if the current value is + * there. If not, move to the first element of the list. */ + int i, listc, elemLen, length = entryPtr->numChars; char *bytes; Tcl_Obj **listv; @@ -4288,43 +4249,44 @@ SpinboxInvoke(interp, sbPtr, element) if (Tcl_GetDouble(NULL, entryPtr->string, &dvalue) != TCL_OK) { /* - * If the string is empty, or isn't a valid double value, - * just use the -from value + * If the string is empty, or isn't a valid double value, just + * use the -from value */ + dvalue = sbPtr->fromValue; - } else { - if (up) { - dvalue += sbPtr->increment; - if (dvalue > sbPtr->toValue) { - if (sbPtr->wrap) { - dvalue = sbPtr->fromValue; - } else { - dvalue = sbPtr->toValue; - } - } else if (dvalue < sbPtr->fromValue) { - /* - * It's possible that when pressing up, we are - * still less than the fromValue, because the - * user may have manipulated the value by hand. - */ + } else if (up) { + dvalue += sbPtr->increment; + if (dvalue > sbPtr->toValue) { + if (sbPtr->wrap) { dvalue = sbPtr->fromValue; + } else { + dvalue = sbPtr->toValue; } - } else { - dvalue -= sbPtr->increment; - if (dvalue < sbPtr->fromValue) { - if (sbPtr->wrap) { - dvalue = sbPtr->toValue; - } else { - dvalue = sbPtr->fromValue; - } - } else if (dvalue > sbPtr->toValue) { - /* - * It's possible that when pressing down, we are - * still greater than the toValue, because the - * user may have manipulated the value by hand. - */ + } else if (dvalue < sbPtr->fromValue) { + /* + * It's possible that when pressing up, we are still less + * than the fromValue, because the user may have + * manipulated the value by hand. + */ + + dvalue = sbPtr->fromValue; + } + } else { + dvalue -= sbPtr->increment; + if (dvalue < sbPtr->fromValue) { + if (sbPtr->wrap) { dvalue = sbPtr->toValue; + } else { + dvalue = sbPtr->fromValue; } + } else if (dvalue > sbPtr->toValue) { + /* + * It's possible that when pressing down, we are still + * greater than the toValue, because the user may have + * manipulated the value by hand. + */ + + dvalue = sbPtr->toValue; } } sprintf(sbPtr->formatBuf, sbPtr->valueFormat, dvalue); @@ -4345,9 +4307,11 @@ SpinboxInvoke(interp, sbPtr, element) if (code != TCL_OK) { Tcl_AddErrorInfo(interp, "\n\t(in command executed by spinbox)"); Tcl_BackgroundError(interp); + /* * Yes, it's an error, but a bg one, so we return OK */ + return TCL_OK; } @@ -4362,9 +4326,9 @@ SpinboxInvoke(interp, sbPtr, element) * * ComputeFormat -- * - * This procedure is invoked to recompute the "format" fields - * of a spinbox's widget record, which determines how the value - * of the dial is converted to a string. + * This function is invoked to recompute the "format" fields of a + * spinbox's widget record, which determines how the value of the dial is + * converted to a string. * * Results: * Tcl result code. @@ -4383,8 +4347,8 @@ ComputeFormat(sbPtr) int eDigits, fDigits; /* - * Compute the displacement from the decimal of the most significant - * digit required for any number in the dial's range. + * Compute the displacement from the decimal of the most significant digit + * required for any number in the dial's range. */ if (sbPtr->reqFormat) { @@ -4406,6 +4370,7 @@ ComputeFormat(sbPtr) /* * A increment was specified, so use it. */ + leastSigDigit = (int) floor(log10(sbPtr->increment)); } else { leastSigDigit = 0; @@ -4416,13 +4381,13 @@ ComputeFormat(sbPtr) } /* - * Compute the number of characters required using "e" format and - * "f" format, and then choose whichever one takes fewer characters. + * Compute the number of characters required using "e" format and "f" + * format, and then choose whichever one takes fewer characters. */ eDigits = numDigits + 4; if (numDigits > 1) { - eDigits++; /* Decimal point. */ + eDigits++; /* Decimal point. */ } afterDecimal = numDigits - mostSigDigit - 1; if (afterDecimal < 0) { @@ -4430,10 +4395,10 @@ ComputeFormat(sbPtr) } fDigits = (mostSigDigit >= 0) ? mostSigDigit + afterDecimal : afterDecimal; if (afterDecimal > 0) { - fDigits++; /* Decimal point. */ + fDigits++; /* Decimal point. */ } if (mostSigDigit < 0) { - fDigits++; /* Zero to left of decimal point. */ + fDigits++; /* Zero to left of decimal point. */ } if (fDigits <= eDigits) { sprintf(sbPtr->digitFormat, "%%.%df", afterDecimal); @@ -4443,3 +4408,11 @@ ComputeFormat(sbPtr) sbPtr->valueFormat = sbPtr->digitFormat; return TCL_OK; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkFocus.c b/generic/tkFocus.c index 967cd1c..982644e 100644 --- a/generic/tkFocus.c +++ b/generic/tkFocus.c @@ -1,25 +1,23 @@ -/* +/* * tkFocus.c -- * - * This file contains procedures that manage the input - * focus for Tk. + * This file contains functions that manage the input focus for Tk. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkFocus.c,v 1.11 2004/01/13 02:06:00 davygrvy Exp $ + * RCS: @(#) $Id: tkFocus.c,v 1.12 2005/08/10 22:02:22 dkf Exp $ */ #include "tkInt.h" #include "tkPort.h" - /* - * For each top-level window that has ever received the focus, there - * is a record of the following type: + * For each top-level window that has ever received the focus, there is a + * record of the following type: */ typedef struct TkToplevelFocusInfo { @@ -33,19 +31,17 @@ typedef struct TkToplevelFocusInfo { } ToplevelFocusInfo; /* - * One of the following structures exists for each display used by - * each application. These are linked together from the TkMainInfo - * structure. These structures are needed because it isn't - * sufficient to store a single piece of focus information in each - * display or in each application: we need the cross-product. - * There needs to be separate information for each display, because - * it's possible to have multiple focus windows active simultaneously - * on different displays. There also needs to be separate information - * for each application, because of embedding: if an embedded - * application has the focus, its container application also has - * the focus. Thus we keep a list of structures for each application: - * the same display can appear in structures for several applications - * at once. + * One of the following structures exists for each display used by each + * application. These are linked together from the TkMainInfo structure. + * These structures are needed because it isn't sufficient to store a single + * piece of focus information in each display or in each application: we need + * the cross-product. There needs to be separate information for each display, + * because it's possible to have multiple focus windows active simultaneously + * on different displays. There also needs to be separate information for each + * application, because of embedding: if an embedded application has the + * focus, its container application also has the focus. Thus we keep a list of + * structures for each application: the same display can appear in structures + * for several applications at once. */ typedef struct TkDisplayFocusInfo { @@ -60,34 +56,40 @@ typedef struct TkDisplayFocusInfo { * supposed to receive the X input focus as * soon as it is mapped (needed to handle the * fact that X won't allow the focus on an - * unmapped window). NULL means no delayed + * unmapped window). NULL means no delayed * focus op in progress for this display. */ - int forceFocus; /* Associated with focusOnMapPtr: non-zero + int forceFocus; /* Associated with focusOnMapPtr: non-zero * means claim the focus even if some other * application currently has it. */ unsigned long focusSerial; /* Serial number of last request this * application made to change the focus on - * this display. Used to identify stale - * focus notifications coming from the - * X server. */ + * this display. Used to identify stale focus + * notifications coming from the X server. */ struct TkDisplayFocusInfo *nextPtr; - /* Next in list of all display focus - * records for a given application. */ + /* Next in list of all display focus records + * for a given application. */ } DisplayFocusInfo; /* - * The following magic value is stored in the "send_event" field of - * FocusIn and FocusOut events that are generated in this file. This - * allows us to separate "real" events coming from the server from - * those that we generated. + * The following magic value is stored in the "send_event" field of FocusIn + * and FocusOut events that are generated in this file. This allows us to + * separate "real" events coming from the server from those that we generated. */ -#define GENERATED_EVENT_MAGIC ((Bool) 0x547321ac) +#define GENERATED_EVENT_MAGIC ((Bool) 0x547321ac) /* - * Forward declarations for procedures defined in this file: + * Debugging support... */ +#define DEBUG(dispPtr, arguments) \ + if ((dispPtr)->focusDebug) { \ + printf arguments; \ + } + +/* + * Forward declarations for functions defined in this file: + */ static DisplayFocusInfo *FindDisplayFocusInfo _ANSI_ARGS_((TkMainInfo *mainPtr, TkDisplay *dispPtr)); @@ -101,8 +103,8 @@ static void GenerateFocusEvents _ANSI_ARGS_((TkWindow *sourcePtr, * * Tk_FocusObjCmd -- * - * This procedure is invoked to process the "focus" Tcl command. - * See the user documentation for details on what it does. + * This function is invoked to process the "focus" Tcl command. See the + * user documentation for details on what it does. * * Results: * A standard Tcl result. @@ -115,8 +117,7 @@ static void GenerateFocusEvents _ANSI_ARGS_((TkWindow *sourcePtr, int Tk_FocusObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Main window associated with - * interpreter. */ + ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ @@ -144,17 +145,17 @@ Tk_FocusObjCmd(clientData, interp, objc, objv) } /* - * If invoked with a single argument beginning with "." then focus - * on that window. + * If invoked with a single argument beginning with "." then focus on that + * window. */ if (objc == 2) { - windowName = Tcl_GetStringFromObj(objv[1], (int *) NULL); + windowName = Tcl_GetString(objv[1]); /* * The empty string case exists for backwards compatibility. */ - + if (windowName[0] == '\0') { return TCL_OK; } @@ -170,6 +171,10 @@ Tk_FocusObjCmd(clientData, interp, objc, objv) } } + /* + * We have a subcommand to parse and act upon. + */ + if (Tcl_GetIndexFromObj(interp, objv[1], focusOptions, "option", 0, &index) != TCL_OK) { return TCL_ERROR; @@ -179,63 +184,58 @@ Tk_FocusObjCmd(clientData, interp, objc, objv) return TCL_ERROR; } switch (index) { - case 0: { /* -displayof */ - windowName = Tcl_GetStringFromObj(objv[2], (int *) NULL); - newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin); - if (newPtr == NULL) { - return TCL_ERROR; - } - newPtr = TkGetFocusWin(newPtr); - if (newPtr != NULL) { - Tcl_SetResult(interp, newPtr->pathName, TCL_STATIC); - } - break; + case 0: /* -displayof */ + windowName = Tcl_GetString(objv[2]); + newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin); + if (newPtr == NULL) { + return TCL_ERROR; } - case 1: { /* -force */ - windowName = Tcl_GetStringFromObj(objv[2], (int *) NULL); + newPtr = TkGetFocusWin(newPtr); + if (newPtr != NULL) { + Tcl_SetResult(interp, newPtr->pathName, TCL_STATIC); + } + break; + case 1: /* -force */ + windowName = Tcl_GetString(objv[2]); - /* - * The empty string case exists for backwards compatibility. - */ - - if (windowName[0] == '\0') { - return TCL_OK; - } - newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin); - if (newPtr == NULL) { - return TCL_ERROR; - } - TkSetFocusWin(newPtr, 1); - break; + /* + * The empty string case exists for backwards compatibility. + */ + + if (windowName[0] == '\0') { + return TCL_OK; } - case 2: { /* -lastfor */ - windowName = Tcl_GetStringFromObj(objv[2], (int *) NULL); - newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin); - if (newPtr == NULL) { - return TCL_ERROR; + newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin); + if (newPtr == NULL) { + return TCL_ERROR; + } + TkSetFocusWin(newPtr, 1); + break; + case 2: /* -lastfor */ + windowName = Tcl_GetString(objv[2]); + newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin); + if (newPtr == NULL) { + return TCL_ERROR; + } + for (topLevelPtr = newPtr; topLevelPtr != NULL; + topLevelPtr = topLevelPtr->parentPtr) { + if (!(topLevelPtr->flags & TK_TOP_HIERARCHY)) { + continue; } - for (topLevelPtr = newPtr; topLevelPtr != NULL; - topLevelPtr = topLevelPtr->parentPtr) { - if (topLevelPtr->flags & TK_TOP_HIERARCHY) { - for (tlFocusPtr = newPtr->mainPtr->tlFocusPtr; - tlFocusPtr != NULL; - tlFocusPtr = tlFocusPtr->nextPtr) { - if (tlFocusPtr->topLevelPtr == topLevelPtr) { - Tcl_SetResult(interp, - tlFocusPtr->focusWinPtr->pathName, - TCL_STATIC); - return TCL_OK; - } - } - Tcl_SetResult(interp, topLevelPtr->pathName, TCL_STATIC); + for (tlFocusPtr = newPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL; + tlFocusPtr = tlFocusPtr->nextPtr) { + if (tlFocusPtr->topLevelPtr == topLevelPtr) { + Tcl_SetResult(interp, + tlFocusPtr->focusWinPtr->pathName, TCL_STATIC); return TCL_OK; } } - break; - } - default: { - Tcl_Panic("bad const entries to focusOptions in focus command"); + Tcl_SetResult(interp, topLevelPtr->pathName, TCL_STATIC); + return TCL_OK; } + break; + default: + Tcl_Panic("bad const entries to focusOptions in focus command"); } return TCL_OK; } @@ -245,13 +245,13 @@ Tk_FocusObjCmd(clientData, interp, objc, objv) * * TkFocusFilterEvent -- * - * This procedure is invoked by Tk_HandleEvent when it encounters - * a FocusIn, FocusOut, Enter, or Leave event. + * This function is invoked by Tk_HandleEvent when it encounters a + * FocusIn, FocusOut, Enter, or Leave event. * * Results: - * A return value of 1 means that Tk_HandleEvent should process - * the event normally (i.e. event handlers should be invoked). - * A return value of 0 means that this event should be ignored. + * A return value of 1 means that Tk_HandleEvent should process the event + * normally (i.e. event handlers should be invoked). A return value of 0 + * means that this event should be ignored. * * Side effects: * Additional events may be generated, and the focus may switch. @@ -266,21 +266,19 @@ TkFocusFilterEvent(winPtr, eventPtr) * event. */ { /* - * Design notes: the window manager and X server work together to - * transfer the focus among top-level windows. This procedure takes - * care of transferring the focus from a top-level or wrapper window - * to the actual window within that top-level that has the focus. - * We do this by synthesizing X events to move the focus around. - * None of the FocusIn and FocusOut events generated by X are ever - * used outside of this procedure; only the synthesized events get - * through to the rest of the application. At one point (e.g. - * Tk4.0b1) Tk used to call X to move the focus from a top-level to - * one of its descendants, then just pass through the events - * generated by X. This approach didn't work very well, for a - * variety of reasons. For example, if X generates the events they - * go at the back of the event queue, which could cause problems if - * other things have already happened, such as moving the focus to - * yet another window. + * Design notes: the window manager and X server work together to transfer + * the focus among top-level windows. This function takes care of + * transferring the focus from a top-level or wrapper window to the actual + * window within that top-level that has the focus. We do this by + * synthesizing X events to move the focus around. None of the FocusIn and + * FocusOut events generated by X are ever used outside of this function; + * only the synthesized events get through to the rest of the application. + * At one point (e.g. Tk4.0b1) Tk used to call X to move the focus from a + * top-level to one of its descendants, then just pass through the events + * generated by X. This approach didn't work very well, for a variety of + * reasons. For example, if X generates the events they go at the back of + * the event queue, which could cause problems if other things have + * already happened, such as moving the focus to yet another window. */ ToplevelFocusInfo *tlFocusPtr; @@ -290,8 +288,8 @@ TkFocusFilterEvent(winPtr, eventPtr) int retValue, delta; /* - * If this was a generated event, just turn off the generated - * flag and pass the event through to Tk bindings. + * If this was a generated event, just turn off the generated flag and + * pass the event through to Tk bindings. */ if (eventPtr->xfocus.send_event == GENERATED_EVENT_MAGIC) { @@ -300,11 +298,11 @@ TkFocusFilterEvent(winPtr, eventPtr) } /* - * Check for special events generated by embedded applications to - * request the input focus. If this is one of those events, make - * the change in focus and return without any additional processing - * of the event (note: the "detail" field of the event indicates - * whether to claim the focus even if we don't already have it). + * Check for special events generated by embedded applications to request + * the input focus. If this is one of those events, make the change in + * focus and return without any additional processing of the event (note: + * the "detail" field of the event indicates whether to claim the focus + * even if we don't already have it). */ if ((eventPtr->xfocus.mode == EMBEDDED_APP_WANTS_FOCUS) @@ -314,10 +312,9 @@ TkFocusFilterEvent(winPtr, eventPtr) } /* - * This was not a generated event. We'll return 1 (so that the - * event will be processed) if it's an Enter or Leave event, and - * 0 (so that the event won't be processed) if it's a FocusIn or - * FocusOut event. + * This was not a generated event. We'll return 1 (so that the event will + * be processed) if it's an Enter or Leave event, and 0 (so that the event + * won't be processed) if it's a FocusIn or FocusOut event. */ retValue = 0; @@ -325,26 +322,26 @@ TkFocusFilterEvent(winPtr, eventPtr) if (eventPtr->type == FocusIn) { /* * Skip FocusIn events that cause confusion - * NotifyVirtual and NotifyNonlinearVirtual - Virtual events occur - * on windows in between the origin and destination of the - * focus change. For FocusIn we may see this when focus - * goes into an embedded child. We don't care about this, - * although we may end up getting a NotifyPointer later. - * NotifyInferior - focus is coming to us from an embedded child. - * When focus is on an embeded focus, we still think we have - * the focus, too, so this message doesn't change our state. - * NotifyPointerRoot - should never happen because this is sent - * to the root window. + * NotifyVirtual and NotifyNonlinearVirtual - Virtual events occur on + * windows in between the origin and destination of the focus + * change. For FocusIn we may see this when focus goes into an + * embedded child. We don't care about this, although we may end + * up getting a NotifyPointer later. + * NotifyInferior - focus is coming to us from an embedded child. When + * focus is on an embeded focus, we still think we have the + * focus, too, so this message doesn't change our state. + * NotifyPointerRoot - should never happen because this is sent to the + * root window. * * Interesting FocusIn events are * NotifyAncestor - focus is coming from our parent, probably the root. * NotifyNonlinear - focus is coming from a different branch, probably * another toplevel. - * NotifyPointer - implicit focus because of the mouse position. - * This is only interesting on toplevels, when it means that the - * focus has been set to the root window but the mouse is over - * this toplevel. We take the focus implicitly (probably no - * window manager) + * NotifyPointer - implicit focus because of the mouse position. This + * is only interesting on toplevels, when it means that the focus + * has been set to the root window but the mouse is over this + * toplevel. We take the focus implicitly (probably no window + * manager) */ if ((eventPtr->xfocus.detail == NotifyVirtual) @@ -357,12 +354,12 @@ TkFocusFilterEvent(winPtr, eventPtr) /* * Skip FocusOut events that cause confusion. * NotifyPointer - the pointer is in us or a child, and we are losing - * focus because of an XSetInputFocus. Other focus events - * will set our state properly. - * NotifyPointerRoot - should never happen because this is sent - * to the root window. - * NotifyInferior - focus leaving us for an embedded child. We - * retain a notion of focus when an embedded child has focus. + * focus because of an XSetInputFocus. Other focus events will + * set our state properly. + * NotifyPointerRoot - should never happen because this is sent to the + * root window. + * NotifyInferior - focus leaving us for an embedded child. We retain + * a notion of focus when an embedded child has focus. * * Interesting events are: * NotifyAncestor - focus is going to root. @@ -394,8 +391,8 @@ TkFocusFilterEvent(winPtr, eventPtr) } /* - * If there is a grab in effect and this window is outside the - * grabbed tree, then ignore the event. + * If there is a grab in effect and this window is outside the grabbed + * tree, then ignore the event. */ if (TkGrabState(winPtr) == TK_GRAB_EXCLUDED) { @@ -403,16 +400,15 @@ TkFocusFilterEvent(winPtr, eventPtr) } /* - * It is possible that there were outstanding FocusIn and FocusOut - * events on their way to us at the time the focus was changed - * internally with the "focus" command. If so, these events could - * potentially cause us to lose the focus (switch it to the window - * of the last FocusIn event) even though the focus change occurred - * after those events. The following code detects this and ignores - * the stale events. + * It is possible that there were outstanding FocusIn and FocusOut events + * on their way to us at the time the focus was changed internally with + * the "focus" command. If so, these events could potentially cause us to + * lose the focus (switch it to the window of the last FocusIn event) even + * though the focus change occurred after those events. The following code + * detects this and ignores the stale events. * - * Note: the focusSerial is only generated by TkpChangeFocus, - * whereas in Tk 4.2 there was always a nop marker generated. + * Note: the focusSerial is only generated by TkpChangeFocus, whereas in + * Tk 4.2 there was always a nop marker generated. */ delta = eventPtr->xfocus.serial - displayFocusPtr->focusSerial; @@ -442,6 +438,7 @@ TkFocusFilterEvent(winPtr, eventPtr) /* * Ignore event if newFocus window is already dead! */ + if (newFocusPtr->flags & TK_ALREADY_DEAD) { return retValue; } @@ -453,7 +450,7 @@ TkFocusFilterEvent(winPtr, eventPtr) /* * NotifyPointer gets set when the focus has been set to the root - * window but we have the pointer. We'll treat this like an implicit + * window but we have the pointer. We'll treat this like an implicit * focus in event so that upon Leave events we release focus. */ @@ -468,9 +465,9 @@ TkFocusFilterEvent(winPtr, eventPtr) GenerateFocusEvents(displayFocusPtr->focusWinPtr, (TkWindow *) NULL); /* - * Reset dispPtr->focusPtr, but only if it currently is the same - * as this application's focusWinPtr: this check is needed to - * handle embedded applications in the same process. + * Reset dispPtr->focusPtr, but only if it currently is the same as + * this application's focusWinPtr: this check is needed to handle + * embedded applications in the same process. */ if (dispPtr->focusPtr == displayFocusPtr->focusWinPtr) { @@ -480,25 +477,22 @@ TkFocusFilterEvent(winPtr, eventPtr) } else if (eventPtr->type == EnterNotify) { /* * If there is no window manager, or if the window manager isn't - * moving the focus around (e.g. the disgusting "NoTitleFocus" - * option has been selected in twm), then we won't get FocusIn - * or FocusOut events. Instead, the "focus" field will be set - * in an Enter event to indicate that we've already got the focus - * when the mouse enters the window (even though we didn't get - * a FocusIn event). Watch for this and grab the focus when it - * happens. Note: if this is an embedded application then don't - * accept the focus implicitly like this; the container - * application will give us the focus explicitly if it wants us - * to have it. + * moving the focus around (e.g. the disgusting "NoTitleFocus" option + * has been selected in twm), then we won't get FocusIn or FocusOut + * events. Instead, the "focus" field will be set in an Enter event to + * indicate that we've already got the focus when the mouse enters the + * window (even though we didn't get a FocusIn event). Watch for this + * and grab the focus when it happens. Note: if this is an embedded + * application then don't accept the focus implicitly like this; the + * container application will give us the focus explicitly if it wants + * us to have it. */ if (eventPtr->xcrossing.focus && - (displayFocusPtr->focusWinPtr == NULL) + (displayFocusPtr->focusWinPtr == NULL) && !(winPtr->flags & TK_EMBEDDED)) { - if (dispPtr->focusDebug) { - printf("Focussed implicitly on %s\n", - newFocusPtr->pathName); - } + DEBUG(dispPtr, + ("Focussed implicitly on %s\n", newFocusPtr->pathName)); GenerateFocusEvents(displayFocusPtr->focusWinPtr, newFocusPtr); displayFocusPtr->focusWinPtr = newFocusPtr; @@ -509,20 +503,18 @@ TkFocusFilterEvent(winPtr, eventPtr) /* * If the pointer just left a window for which we automatically * claimed the focus on enter, move the focus back to the root - * window, where it was before we claimed it above. Note: + * window, where it was before we claimed it above. Note: * dispPtr->implicitWinPtr may not be the same as - * displayFocusPtr->focusWinPtr (e.g. because the "focus" - * command was used to redirect the focus after it arrived at - * dispPtr->implicitWinPtr)!! In addition, we generate events + * displayFocusPtr->focusWinPtr (e.g. because the "focus" command + * was used to redirect the focus after it arrived at + * dispPtr->implicitWinPtr)!! In addition, we generate events * because the window manager won't give us a FocusOut event when - * we focus on the root. + * we focus on the root. */ if ((dispPtr->implicitWinPtr != NULL) && !(winPtr->flags & TK_EMBEDDED)) { - if (dispPtr->focusDebug) { - printf("Defocussed implicit Async\n"); - } + DEBUG(dispPtr, ("Defocussed implicit Async\n")); GenerateFocusEvents(displayFocusPtr->focusWinPtr, (TkWindow *) NULL); XSetInputFocus(dispPtr->display, PointerRoot, RevertToPointerRoot, @@ -539,8 +531,8 @@ TkFocusFilterEvent(winPtr, eventPtr) * * TkSetFocusWin -- * - * This procedure is invoked to change the focus window for a - * given display in a given application. + * This function is invoked to change the focus window for a given + * display in a given application. * * Results: * None. @@ -554,11 +546,11 @@ TkFocusFilterEvent(winPtr, eventPtr) void TkSetFocusWin(winPtr, force) - TkWindow *winPtr; /* Window that is to be the new focus for - * its display and application. */ - int force; /* If non-zero, set the X focus to this - * window even if the application doesn't - * currently have the X focus. */ + TkWindow *winPtr; /* Window that is to be the new focus for its + * display and application. */ + int force; /* If non-zero, set the X focus to this window + * even if the application doesn't currently + * have the X focus. */ { ToplevelFocusInfo *tlFocusPtr; DisplayFocusInfo *displayFocusPtr; @@ -568,9 +560,9 @@ TkSetFocusWin(winPtr, force) displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr); /* - * If force is set, we should make sure we grab the focus regardless - * of the current focus window since under Windows, we may need to - * take control away from another application. + * If force is set, we should make sure we grab the focus regardless of + * the current focus window since under Windows, we may need to take + * control away from another application. */ if (winPtr == displayFocusPtr->focusWinPtr && !force) { @@ -578,18 +570,19 @@ TkSetFocusWin(winPtr, force) } /* - * Find the top-level window for winPtr, then find (or create) - * a record for the top-level. Also see whether winPtr and all its - * ancestors are mapped. + * Find the top-level window for winPtr, then find (or create) a record + * for the top-level. Also see whether winPtr and all its ancestors are + * mapped. */ allMapped = 1; for (topLevelPtr = winPtr; ; topLevelPtr = topLevelPtr->parentPtr) { if (topLevelPtr == NULL) { /* - * The window is being deleted. No point in worrying about - * giving it the focus. + * The window is being deleted. No point in worrying about giving + * it the focus. */ + return; } if (!(topLevelPtr->flags & TK_MAPPED)) { @@ -601,11 +594,11 @@ TkSetFocusWin(winPtr, force) } /* - * If the new focus window isn't mapped, then we can't focus on it - * (X will generate an error, for example). Instead, create an - * event handler that will set the focus to this window once it gets - * mapped. At the same time, delete any old handler that might be - * around; it's no longer relevant. + * If the new focus window isn't mapped, then we can't focus on it (X will + * generate an error, for example). Instead, create an event handler that + * will set the focus to this window once it gets mapped. At the same + * time, delete any old handler that might be around; it's no longer + * relevant. */ if (displayFocusPtr->focusOnMapPtr != NULL) { @@ -639,16 +632,15 @@ TkSetFocusWin(winPtr, force) tlFocusPtr->focusWinPtr = winPtr; /* - * Reset the window system's focus window and generate focus events, - * with two special cases: + * Reset the window system's focus window and generate focus events, with + * two special cases: * - * 1. If the application is embedded and doesn't currently have the - * focus, don't set the focus directly. Instead, see if the - * embedding code can claim the focus from the enclosing - * container. - * 2. Otherwise, if the application doesn't currently have the - * focus, don't change the window system's focus unless it was - * already in this application or "force" was specified. + * 1. If the application is embedded and doesn't currently have the focus, + * don't set the focus directly. Instead, see if the embedding code can + * claim the focus from the enclosing container. + * 2. Otherwise, if the application doesn't currently have the focus, + * don't change the window system's focus unless it was already in this + * application or "force" was specified. */ if ((topLevelPtr->flags & TK_EMBEDDED) @@ -656,12 +648,11 @@ TkSetFocusWin(winPtr, force) TkpClaimFocus(topLevelPtr, force); } else if ((displayFocusPtr->focusWinPtr != NULL) || force) { /* - * Generate events to shift focus between Tk windows. - * We do this regardless of what TkpChangeFocus does with - * the real X focus so that Tk widgets track focus commands - * when there is no window manager. GenerateFocusEvents will - * set up a serial number marker so we discard focus events - * that are triggered by the ChangeFocus. + * Generate events to shift focus between Tk windows. We do this + * regardless of what TkpChangeFocus does with the real X focus so + * that Tk widgets track focus commands when there is no window + * manager. GenerateFocusEvents will set up a serial number marker so + * we discard focus events that are triggered by the ChangeFocus. */ serial = TkpChangeFocus(TkpGetWrapperWindow(topLevelPtr), force); @@ -679,13 +670,13 @@ TkSetFocusWin(winPtr, force) * * TkGetFocusWin -- * - * Given a window, this procedure returns the current focus - * window for its application and display. + * Given a window, this function returns the current focus window for its + * application and display. * * Results: - * The return value is a pointer to the window that currently - * has the input focus for the specified application and - * display, or NULL if none. + * The return value is a pointer to the window that currently has the + * input focus for the specified application and display, or NULL if + * none. * * Side effects: * None. @@ -695,8 +686,8 @@ TkSetFocusWin(winPtr, force) TkWindow * TkGetFocusWin(winPtr) - TkWindow *winPtr; /* Window that selects an application - * and a display. */ + TkWindow *winPtr; /* Window that selects an application and a + * display. */ { DisplayFocusInfo *displayFocusPtr; @@ -713,16 +704,16 @@ TkGetFocusWin(winPtr) * * TkFocusKeyEvent -- * - * Given a window and a key press or release event that arrived for - * the window, use information about the keyboard focus to compute - * which window should really get the event. In addition, update - * the event to refer to its new window. + * Given a window and a key press or release event that arrived for the + * window, use information about the keyboard focus to compute which + * window should really get the event. In addition, update the event to + * refer to its new window. * * Results: - * The return value is a pointer to the window that has the input - * focus in winPtr's application, or NULL if winPtr's application - * doesn't have the input focus. If a non-NULL value is returned, - * eventPtr will be updated to refer properly to the focus window. + * The return value is a pointer to the window that has the input focus + * in winPtr's application, or NULL if winPtr's application doesn't have + * the input focus. If a non-NULL value is returned, eventPtr will be + * updated to refer properly to the focus window. * * Side effects: * None. @@ -732,10 +723,10 @@ TkGetFocusWin(winPtr) TkWindow * TkFocusKeyEvent(winPtr, eventPtr) - TkWindow *winPtr; /* Window that selects an application - * and a display. */ - XEvent *eventPtr; /* X event to redirect (should be KeyPress - * or KeyRelease). */ + TkWindow *winPtr; /* Window that selects an application and a + * display. */ + XEvent *eventPtr; /* X event to redirect (should be KeyPress or + * KeyRelease). */ { DisplayFocusInfo *displayFocusPtr; TkWindow *focusWinPtr; @@ -762,9 +753,9 @@ TkFocusKeyEvent(winPtr, eventPtr) if ((focusWinPtr != NULL) && (focusWinPtr->mainPtr == winPtr->mainPtr)) { /* - * Map the x and y coordinates to make sense in the context of - * the focus window, if possible (make both -1 if the map-from - * and map-to windows don't share the same screen). + * Map the x and y coordinates to make sense in the context of the + * focus window, if possible (make both -1 if the map-from and map-to + * windows don't share the same screen). */ if ((focusWinPtr->display != winPtr->display) @@ -783,9 +774,9 @@ TkFocusKeyEvent(winPtr, eventPtr) } /* - * The event doesn't belong to us. Perhaps, due to embedding, it - * really belongs to someone else. Give the embedding code a chance - * to redirect the event. + * The event doesn't belong to us. Perhaps, due to embedding, it really + * belongs to someone else. Give the embedding code a chance to redirect + * the event. */ TkpRedirectKeyEvent(winPtr, eventPtr); @@ -797,9 +788,8 @@ TkFocusKeyEvent(winPtr, eventPtr) * * TkFocusDeadWindow -- * - * This procedure is invoked when it is determined that - * a window is dead. It cleans up focus-related information - * about the window. + * This function is invoked when it is determined that a window is dead. + * It cleans up focus-related information about the window. * * Results: * None. @@ -812,24 +802,25 @@ TkFocusKeyEvent(winPtr, eventPtr) void TkFocusDeadWindow(winPtr) - register TkWindow *winPtr; /* Information about the window - * that is being deleted. */ + register TkWindow *winPtr; /* Information about the window that is being + * deleted. */ { ToplevelFocusInfo *tlFocusPtr, *prevPtr; DisplayFocusInfo *displayFocusPtr; TkDisplay *dispPtr = winPtr->dispPtr; /* - * Certain special windows like those used for send and clipboard - * have no mainPtr. + * Certain special windows like those used for send and clipboard have no + * mainPtr. */ - if (winPtr->mainPtr == NULL) - return; + if (winPtr->mainPtr == NULL) { + return; + } /* - * Search for focus records that refer to this window either as - * the top-level window or the current focus window. + * Search for focus records that refer to this window either as the + * top-level window or the current focus window. */ displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr); @@ -838,16 +829,14 @@ TkFocusDeadWindow(winPtr) prevPtr = tlFocusPtr, tlFocusPtr = tlFocusPtr->nextPtr) { if (winPtr == tlFocusPtr->topLevelPtr) { /* - * The top-level window is the one being deleted: free - * the focus record and release the focus back to PointerRoot - * if we acquired it implicitly. + * The top-level window is the one being deleted: free the focus + * record and release the focus back to PointerRoot if we acquired + * it implicitly. */ if (dispPtr->implicitWinPtr == winPtr) { - if (dispPtr->focusDebug) { - printf("releasing focus to root after %s died\n", - tlFocusPtr->topLevelPtr->pathName); - } + DEBUG(dispPtr, ("releasing focus to root after %s died\n", + tlFocusPtr->topLevelPtr->pathName)); dispPtr->implicitWinPtr = NULL; displayFocusPtr->focusWinPtr = NULL; dispPtr->focusPtr = NULL; @@ -865,18 +854,15 @@ TkFocusDeadWindow(winPtr) break; } else if (winPtr == tlFocusPtr->focusWinPtr) { /* - * The deleted window had the focus for its top-level: - * move the focus to the top-level itself. + * The deleted window had the focus for its top-level: move the + * focus to the top-level itself. */ tlFocusPtr->focusWinPtr = tlFocusPtr->topLevelPtr; if ((displayFocusPtr->focusWinPtr == winPtr) && !(tlFocusPtr->topLevelPtr->flags & TK_ALREADY_DEAD)) { - if (dispPtr->focusDebug) { - printf("forwarding focus to %s after %s died\n", - tlFocusPtr->topLevelPtr->pathName, - winPtr->pathName); - } + DEBUG(dispPtr, ("forwarding focus to %s after %s died\n", + tlFocusPtr->topLevelPtr->pathName, winPtr->pathName)); GenerateFocusEvents(displayFocusPtr->focusWinPtr, tlFocusPtr->topLevelPtr); displayFocusPtr->focusWinPtr = tlFocusPtr->topLevelPtr; @@ -896,8 +882,8 @@ TkFocusDeadWindow(winPtr) * * GenerateFocusEvents -- * - * This procedure is called to create FocusIn and FocusOut events to - * move the input focus from one window to another. + * This function is called to create FocusIn and FocusOut events to move + * the input focus from one window to another. * * Results: * None. @@ -910,8 +896,8 @@ TkFocusDeadWindow(winPtr) static void GenerateFocusEvents(sourcePtr, destPtr) - TkWindow *sourcePtr; /* Window that used to have the focus (may - * be NULL). */ + TkWindow *sourcePtr; /* Window that used to have the focus (may be + * NULL). */ TkWindow *destPtr; /* New window to have the focus (may be * NULL). */ @@ -940,18 +926,18 @@ GenerateFocusEvents(sourcePtr, destPtr) * * FocusMapProc -- * - * This procedure is called as an event handler for VisibilityNotify - * events, if a window receives the focus at a time when its - * toplevel isn't mapped. The procedure is needed because X - * won't allow the focus to be set to an unmapped window; we - * detect when the toplevel is mapped and set the focus to it then. + * This function is called as an event handler for VisibilityNotify + * events, if a window receives the focus at a time when its toplevel + * isn't mapped. The function is needed because X won't allow the focus + * to be set to an unmapped window; we detect when the toplevel is mapped + * and set the focus to it then. * * Results: * None. * * Side effects: - * If this is a map event, the focus gets set to the toplevel - * given by clientData. + * If this is a map event, the focus gets set to the toplevel given by + * clientData. * *---------------------------------------------------------------------- */ @@ -967,10 +953,8 @@ FocusMapProc(clientData, eventPtr) if (eventPtr->type == VisibilityNotify) { displayFocusPtr = FindDisplayFocusInfo(winPtr->mainPtr, winPtr->dispPtr); - if (winPtr->dispPtr->focusDebug) { - printf("auto-focussing on %s, force %d\n", winPtr->pathName, - displayFocusPtr->forceFocus); - } + DEBUG(winPtr->dispPtr, ("auto-focussing on %s, force %d\n", + winPtr->pathName, displayFocusPtr->forceFocus)); Tk_DeleteEventHandler((Tk_Window) winPtr, VisibilityChangeMask, FocusMapProc, clientData); displayFocusPtr->focusOnMapPtr = NULL; @@ -983,9 +967,9 @@ FocusMapProc(clientData, eventPtr) * * FindDisplayFocusInfo -- * - * Given an application and a display, this procedure locate the - * focus record for that combination. If no such record exists, - * it creates a new record and initializes it. + * Given an application and a display, this function locate the focus + * record for that combination. If no such record exists, it creates a + * new record and initializes it. * * Results: * The return value is a pointer to the record. @@ -1014,7 +998,7 @@ FindDisplayFocusInfo(mainPtr, dispPtr) } /* - * The record doesn't exist yet. Make a new one. + * The record doesn't exist yet. Make a new one. */ displayFocusPtr = (DisplayFocusInfo *) ckalloc(sizeof(DisplayFocusInfo)); @@ -1049,17 +1033,24 @@ TkFocusFree(mainPtr) TkMainInfo *mainPtr; /* Record that identifies a particular * application. */ { - DisplayFocusInfo *displayFocusPtr; - ToplevelFocusInfo *tlFocusPtr; - while (mainPtr->displayFocusPtr != NULL) { - displayFocusPtr = mainPtr->displayFocusPtr; + DisplayFocusInfo *displayFocusPtr = mainPtr->displayFocusPtr; + mainPtr->displayFocusPtr = mainPtr->displayFocusPtr->nextPtr; ckfree((char *) displayFocusPtr); } while (mainPtr->tlFocusPtr != NULL) { - tlFocusPtr = mainPtr->tlFocusPtr; + ToplevelFocusInfo *tlFocusPtr = mainPtr->tlFocusPtr; + mainPtr->tlFocusPtr = mainPtr->tlFocusPtr->nextPtr; ckfree((char *) tlFocusPtr); } } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkFont.c b/generic/tkFont.c index 8274cfe..8574ff0 100644 --- a/generic/tkFont.c +++ b/generic/tkFont.c @@ -1,17 +1,16 @@ -/* +/* * tkFont.c -- * - * This file maintains a database of fonts for the Tk toolkit. - * It also provides several utility procedures for measuring and - * displaying text. + * This file maintains a database of fonts for the Tk toolkit. It also + * provides several utility functions for measuring and displaying text. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1998 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkFont.c,v 1.22 2004/01/13 02:06:00 davygrvy Exp $ + * RCS: @(#) $Id: tkFont.c,v 1.23 2005/08/10 22:02:22 dkf Exp $ */ #include "tkPort.h" @@ -19,28 +18,28 @@ #include "tkFont.h" /* - * The following structure is used to keep track of all the fonts that - * exist in the current application. It must be stored in the - * TkMainInfo for the application. + * The following structure is used to keep track of all the fonts that exist + * in the current application. It must be stored in the TkMainInfo for the + * application. */ - + typedef struct TkFontInfo { - Tcl_HashTable fontCache; /* Map a string to an existing Tk_Font. - * Keys are string font names, values are - * TkFont pointers. */ + Tcl_HashTable fontCache; /* Map a string to an existing Tk_Font. Keys + * are string font names, values are TkFont + * pointers. */ Tcl_HashTable namedTable; /* Map a name to a set of attributes for a * font, used when constructing a Tk_Font from - * a named font description. Keys are - * strings, values are NamedFont pointers. */ + * a named font description. Keys are strings, + * values are NamedFont pointers. */ TkMainInfo *mainPtr; /* Application that owns this structure. */ int updatePending; /* Non-zero when a World Changed event has - * already been queued to handle a change to - * a named font. */ + * already been queued to handle a change to a + * named font. */ } TkFontInfo; /* * The following data structure is used to keep track of the font attributes - * for each named font that has been defined. The named font is only deleted + * for each named font that has been defined. The named font is only deleted * when the last reference to it goes away. */ @@ -50,21 +49,20 @@ typedef struct NamedFont { * last reference goes away. */ TkFontAttributes fa; /* Desired attributes for named font. */ } NamedFont; - + /* - * The following two structures are used to keep track of string - * measurement information when using the text layout facilities. + * The following two structures are used to keep track of string measurement + * information when using the text layout facilities. * * A LayoutChunk represents a contiguous range of text that can be measured - * and displayed by low-level text calls. In general, chunks will be - * delimited by newlines and tabs. Low-level, platform-specific things - * like kerning and non-integer character widths may occur between the - * characters in a single chunk, but not between characters in different - * chunks. - * - * A TextLayout is a collection of LayoutChunks. It can be displayed with - * respect to any origin. It is the implementation of the Tk_TextLayout - * opaque token. + * and displayed by low-level text calls. In general, chunks will be delimited + * by newlines and tabs. Low-level, platform-specific things like kerning and + * non-integer character widths may occur between the characters in a single + * chunk, but not between characters in different chunks. + * + * A TextLayout is a collection of LayoutChunks. It can be displayed with + * respect to any origin. It is the implementation of the Tk_TextLayout opaque + * token. */ typedef struct LayoutChunk { @@ -74,19 +72,19 @@ typedef struct LayoutChunk { int numBytes; /* The number of bytes in this chunk. */ int numChars; /* The number of characters in this chunk. */ int numDisplayChars; /* The number of characters to display when - * this chunk is displayed. Can be less than + * this chunk is displayed. Can be less than * numChars if extra space characters were - * absorbed by the end of the chunk. This - * will be < 0 if this is a chunk that is - * holding a tab or newline. */ + * absorbed by the end of the chunk. This will + * be < 0 if this is a chunk that is holding a + * tab or newline. */ int x, y; /* The origin of the first character in this * chunk with respect to the upper-left hand * corner of the TextLayout. */ - int totalWidth; /* Width in pixels of this chunk. Used - * when hit testing the invisible spaces at - * the end of a chunk. */ + int totalWidth; /* Width in pixels of this chunk. Used when + * hit testing the invisible spaces at the end + * of a chunk. */ int displayWidth; /* Width in pixels of the displayable - * characters in this chunk. Can be less than + * characters in this chunk. Can be less than * width if extra space characters were * absorbed by the end of the chunk. */ } LayoutChunk; @@ -94,20 +92,20 @@ typedef struct LayoutChunk { typedef struct TextLayout { Tk_Font tkfont; /* The font used when laying out the text. */ CONST char *string; /* The string that was layed out. */ - int width; /* The maximum width of all lines in the - * text layout. */ - int numChunks; /* Number of chunks actually used in - * following array. */ - LayoutChunk chunks[1]; /* Array of chunks. The actual size will - * be maxChunks. THIS FIELD MUST BE THE LAST - * IN THE STRUCTURE. */ + int width; /* The maximum width of all lines in the text + * layout. */ + int numChunks; /* Number of chunks actually used in following + * array. */ + LayoutChunk chunks[1]; /* Array of chunks. The actual size will be + * maxChunks. THIS FIELD MUST BE THE LAST IN + * THE STRUCTURE. */ } TextLayout; /* * The following structures are used as two-way maps between the values for - * the fields in the TkFontAttributes structure and the strings used in - * Tcl, when parsing both option-value format and style-list format font - * name strings. + * the fields in the TkFontAttributes structure and the strings used in Tcl, + * when parsing both option-value format and style-list format font name + * strings. */ static TkStateMap weightMap[] = { @@ -146,7 +144,7 @@ static TkStateMap xlfdWeightMap[] = { {TK_FW_BOLD, "demi"}, {TK_FW_BOLD, "demibold"}, {TK_FW_NORMAL, NULL} /* Assume anything else is "normal". */ -}; +}; static TkStateMap xlfdSlantMap[] = { {TK_FS_ROMAN, "r"}, @@ -164,8 +162,8 @@ static TkStateMap xlfdSetwidthMap[] = { }; /* - * The following structure and defines specify the valid builtin options - * when configuring a set of font attributes. + * The following structure and defines specify the valid builtin options when + * configuring a set of font attributes. */ static CONST char *fontOpt[] = { @@ -187,10 +185,10 @@ static CONST char *fontOpt[] = { #define FONT_NUMFIELDS 6 /* - * Hardcoded font aliases. These are used to describe (mostly) identical - * fonts whose names differ from platform to platform. If the - * user-supplied font name matches any of the names in one of the alias - * lists, the other names in the alias list are also automatically tried. + * Hardcoded font aliases. These are used to describe (mostly) identical fonts + * whose names differ from platform to platform. If the user-supplied font + * name matches any of the names in one of the alias lists, the other names in + * the alias list are also automatically tried. */ static char *timesAliases[] = { @@ -228,7 +226,7 @@ static char *gothicAliases[] = { /* Windows (MS goshikku). */ "\344\270\270\343\202\264\343\202\267\343\203\203\343\202\257\342\210\222\357\274\255", /* Mac (goshikku-M). */ - NULL + NULL }; static char *dingbatsAliases[] = { @@ -247,43 +245,46 @@ static char **fontAliases[] = { gothicAliases, dingbatsAliases, NULL -}; +}; /* - * Hardcoded font classes. If the character cannot be found in the base - * font, the classes are examined in order to see if some other similar - * font should be examined also. + * Hardcoded font classes. If the character cannot be found in the base font, + * the classes are examined in order to see if some other similar font should + * be examined also. */ static char *systemClass[] = { - "fixed", /* Unix. */ - /* Windows. */ - "chicago", "osaka", "sistemny", /* Mac. */ + "fixed", /* Unix. */ + /* Windows. */ + "chicago", "osaka", "sistemny", + /* Mac. */ NULL }; static char *serifClass[] = { - "times", "palatino", "mincho", /* All platforms. */ - "song ti", /* Unix. */ - "ms serif", "simplified arabic", /* Windows. */ - "latinski", /* Mac. */ + "times", "palatino", "mincho", + /* All platforms. */ + "song ti", /* Unix. */ + "ms serif", "simplified arabic", + /* Windows. */ + "latinski", /* Mac. */ NULL }; static char *sansClass[] = { - "helvetica", "gothic", /* All platforms. */ - /* Unix. */ + "helvetica", "gothic", /* All platforms. */ + /* Unix. */ "ms sans serif", "traditional arabic", - /* Windows. */ - "bastion", /* Mac. */ + /* Windows. */ + "bastion", /* Mac. */ NULL }; static char *monoClass[] = { - "courier", "gothic", /* All platforms. */ - "fangsong ti", /* Unix. */ - "simplified arabic fixed", /* Windows. */ - "monaco", "pryamoy", /* Mac. */ + "courier", "gothic", /* All platforms. */ + "fangsong ti", /* Unix. */ + "simplified arabic fixed", /* Windows. */ + "monaco", "pryamoy", /* Mac. */ NULL }; @@ -301,9 +302,9 @@ static char **fontFallbacks[] = { }; /* - * Global fallbacks. If the character could not be found in the preferred - * fallback list, this list is examined. If the character still cannot be - * found, all font families in the system are examined. + * Global fallbacks. If the character could not be found in the preferred + * fallback list, this list is examined. If the character still cannot be + * found, all font families in the system are examined. */ static char *globalFontClass[] = { @@ -316,43 +317,37 @@ static char *globalFontClass[] = { }; #define GetFontAttributes(tkfont) \ - ((CONST TkFontAttributes *) &((TkFont *) (tkfont))->fa) + ((CONST TkFontAttributes *) &((TkFont *) (tkfont))->fa) #define GetFontMetrics(tkfont) \ - ((CONST TkFontMetrics *) &((TkFont *) (tkfont))->fm) + ((CONST TkFontMetrics *) &((TkFont *) (tkfont))->fm) -static int ConfigAttributesObj _ANSI_ARGS_((Tcl_Interp *interp, +static int ConfigAttributesObj(Tcl_Interp *interp, Tk_Window tkwin, int objc, Tcl_Obj *CONST objv[], - TkFontAttributes *faPtr)); -static int CreateNamedFont _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window tkwin, CONST char *name, - TkFontAttributes *faPtr)); -static void DupFontObjProc _ANSI_ARGS_((Tcl_Obj *srcObjPtr, - Tcl_Obj *dupObjPtr)); -static int FieldSpecified _ANSI_ARGS_((CONST char *field)); -static void FreeFontObjProc _ANSI_ARGS_((Tcl_Obj *objPtr)); -static int GetAttributeInfoObj _ANSI_ARGS_((Tcl_Interp *interp, - CONST TkFontAttributes *faPtr, Tcl_Obj *objPtr)); -static LayoutChunk * NewChunk _ANSI_ARGS_((TextLayout **layoutPtrPtr, - int *maxPtr, CONST char *start, int numChars, - int curX, int newX, int y)); -static int ParseFontNameObj _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window tkwin, Tcl_Obj *objPtr, - TkFontAttributes *faPtr)); -static void RecomputeWidgets _ANSI_ARGS_((TkWindow *winPtr)); -static int SetFontFromAny _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *objPtr)); -static void TheWorldHasChanged _ANSI_ARGS_(( - ClientData clientData)); -static void UpdateDependentFonts _ANSI_ARGS_((TkFontInfo *fiPtr, - Tk_Window tkwin, Tcl_HashEntry *namedHashPtr)); + TkFontAttributes *faPtr); +static int CreateNamedFont(Tcl_Interp *interp, Tk_Window tkwin, + CONST char *name, TkFontAttributes *faPtr); +static void DupFontObjProc(Tcl_Obj *srcObjPtr, Tcl_Obj *dupObjPtr); +static int FieldSpecified(CONST char *field); +static void FreeFontObjProc(Tcl_Obj *objPtr); +static int GetAttributeInfoObj(Tcl_Interp *interp, + CONST TkFontAttributes *faPtr, Tcl_Obj *objPtr); +static LayoutChunk * NewChunk(TextLayout **layoutPtrPtr, int *maxPtr, + CONST char *start, int numChars, int curX, + int newX, int y); +static int ParseFontNameObj(Tcl_Interp *interp, Tk_Window tkwin, + Tcl_Obj *objPtr, TkFontAttributes *faPtr); +static void RecomputeWidgets(TkWindow *winPtr); +static int SetFontFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); +static void TheWorldHasChanged(ClientData clientData); +static void UpdateDependentFonts(TkFontInfo *fiPtr, + Tk_Window tkwin, Tcl_HashEntry *namedHashPtr); /* * The following structure defines the implementation of the "font" Tcl - * object, used for drawing. The internalRep.twoPtrValue.ptr1 field of - * each font object points to the TkFont structure for the font, or - * NULL. + * object, used for drawing. The internalRep.twoPtrValue.ptr1 field of each + * font object points to the TkFont structure for the font, or NULL. */ Tcl_ObjType tkFontObjType = { @@ -369,13 +364,13 @@ Tcl_ObjType tkFontObjType = { * * TkFontPkgInit -- * - * This procedure is called when an application is created. It - * initializes all the structures that are used by the font - * package on a per application basis. + * This function is called when an application is created. It initializes + * all the structures that are used by the font package on a per + * application basis. * * Results: - * Stores a token in the mainPtr to hold information needed by this - * package on a per application basis. + * Stores a token in the mainPtr to hold information needed by this + * package on a per application basis. * * Side effects: * Memory allocated. @@ -403,9 +398,9 @@ TkFontPkgInit(mainPtr) * * TkFontPkgFree -- * - * This procedure is called when an application is deleted. It - * deletes all the structures that were used by the font package - * for this application. + * This function is called when an application is deleted. It deletes all + * the structures that were used by the font package for this + * application. * * Results: * None. @@ -432,14 +427,16 @@ TkFontPkgFree(mainPtr) searchPtr != NULL; searchPtr = Tcl_NextHashEntry(&search)) { fontsLeft++; - fprintf(stderr, "Font %s still in cache.\n", + fprintf(stderr, "Font %s still in cache.\n", Tcl_GetHashKey(&fiPtr->fontCache, searchPtr)); } + #ifdef PURIFY if (fontsLeft) { Tcl_Panic("TkFontPkgFree: all fonts should have been freed already"); } #endif + Tcl_DeleteHashTable(&fiPtr->fontCache); hPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search); @@ -457,10 +454,10 @@ TkFontPkgFree(mainPtr) /* *--------------------------------------------------------------------------- * - * Tk_FontObjCmd -- + * Tk_FontObjCmd -- * - * This procedure is implemented to process the "font" Tcl command. - * See the user documentation for details on what it does. + * This function is implemented to process the "font" Tcl command. See + * the user documentation for details on what it does. * * Results: * A standard Tcl result. @@ -504,259 +501,256 @@ Tk_FontObjCmd(clientData, interp, objc, objv) } switch ((enum options) index) { - case FONT_ACTUAL: { - int skip, result; - Tk_Font tkfont; - Tcl_Obj *objPtr; - CONST TkFontAttributes *faPtr; - - skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin); - if (skip < 0) { - return TCL_ERROR; - } - if ((objc < 3) || (objc - skip > 4)) { - Tcl_WrongNumArgs(interp, 2, objv, - "font ?-displayof window? ?option?"); - return TCL_ERROR; - } - tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); - if (tkfont == NULL) { - return TCL_ERROR; - } - objc -= skip; - objv += skip; - faPtr = GetFontAttributes(tkfont); + case FONT_ACTUAL: { + int skip, result; + Tk_Font tkfont; + Tcl_Obj *objPtr; + CONST TkFontAttributes *faPtr; + + skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin); + if (skip < 0) { + return TCL_ERROR; + } + if ((objc < 3) || (objc - skip > 4)) { + Tcl_WrongNumArgs(interp, 2, objv, + "font ?-displayof window? ?option?"); + return TCL_ERROR; + } + tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); + if (tkfont == NULL) { + return TCL_ERROR; + } + objc -= skip; + objv += skip; + faPtr = GetFontAttributes(tkfont); + objPtr = NULL; + if (objc > 3) { + objPtr = objv[3]; + } + result = GetAttributeInfoObj(interp, faPtr, objPtr); + Tk_FreeFont(tkfont); + return result; + } + case FONT_CONFIGURE: { + int result; + char *string; + Tcl_Obj *objPtr; + NamedFont *nfPtr; + Tcl_HashEntry *namedHashPtr; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "fontname ?options?"); + return TCL_ERROR; + } + string = Tcl_GetString(objv[2]); + namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, string); + nfPtr = NULL; /* lint. */ + if (namedHashPtr != NULL) { + nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); + } + if ((namedHashPtr == NULL) || (nfPtr->deletePending != 0)) { + Tcl_AppendResult(interp, "named font \"", string, + "\" doesn't exist", NULL); + return TCL_ERROR; + } + if (objc == 3) { objPtr = NULL; - if (objc > 3) { - objPtr = objv[3]; - } - result = GetAttributeInfoObj(interp, faPtr, objPtr); - Tk_FreeFont(tkfont); + } else if (objc == 4) { + objPtr = objv[3]; + } else { + result = ConfigAttributesObj(interp, tkwin, objc - 3, objv + 3, + &nfPtr->fa); + UpdateDependentFonts(fiPtr, tkwin, namedHashPtr); return result; } - case FONT_CONFIGURE: { - int result; - char *string; - Tcl_Obj *objPtr; - NamedFont *nfPtr; - Tcl_HashEntry *namedHashPtr; - - if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "fontname ?options?"); - return TCL_ERROR; - } - string = Tcl_GetString(objv[2]); - namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, string); - nfPtr = NULL; /* lint. */ - if (namedHashPtr != NULL) { - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); - } - if ((namedHashPtr == NULL) || (nfPtr->deletePending != 0)) { - Tcl_AppendResult(interp, "named font \"", string, - "\" doesn't exist", NULL); - return TCL_ERROR; - } - if (objc == 3) { - objPtr = NULL; - } else if (objc == 4) { - objPtr = objv[3]; - } else { - result = ConfigAttributesObj(interp, tkwin, objc - 3, - objv + 3, &nfPtr->fa); - UpdateDependentFonts(fiPtr, tkwin, namedHashPtr); - return result; - } - return GetAttributeInfoObj(interp, &nfPtr->fa, objPtr); - } - case FONT_CREATE: { - int skip, i; - char *name; - char buf[16 + TCL_INTEGER_SPACE]; - TkFontAttributes fa; - Tcl_HashEntry *namedHashPtr; + return GetAttributeInfoObj(interp, &nfPtr->fa, objPtr); + } + case FONT_CREATE: { + int skip, i; + char *name; + char buf[16 + TCL_INTEGER_SPACE]; + TkFontAttributes fa; + Tcl_HashEntry *namedHashPtr; - skip = 3; - if (objc < 3) { + skip = 3; + if (objc < 3) { + name = NULL; + } else { + name = Tcl_GetString(objv[2]); + if (name[0] == '-') { name = NULL; - } else { - name = Tcl_GetString(objv[2]); - if (name[0] == '-') { - name = NULL; - } - } - if (name == NULL) { - /* - * No font name specified. Generate one of the form "fontX". - */ - - for (i = 1; ; i++) { - sprintf(buf, "font%d", i); - namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, buf); - if (namedHashPtr == NULL) { - break; - } - } - name = buf; - skip = 2; } - TkInitFontAttributes(&fa); - if (ConfigAttributesObj(interp, tkwin, objc - skip, objv + skip, - &fa) != TCL_OK) { - return TCL_ERROR; - } - if (CreateNamedFont(interp, tkwin, name, &fa) != TCL_OK) { - return TCL_ERROR; - } - Tcl_AppendResult(interp, name, NULL); - break; } - case FONT_DELETE: { - int i; - char *string; - NamedFont *nfPtr; - Tcl_HashEntry *namedHashPtr; - + if (name == NULL) { /* - * Delete the named font. If there are still widgets using this - * font, then it isn't deleted right away. + * No font name specified. Generate one of the form "fontX". */ - if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "fontname ?fontname ...?"); - return TCL_ERROR; - } - for (i = 2; i < objc; i++) { - string = Tcl_GetString(objv[i]); - namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, string); + for (i = 1; ; i++) { + sprintf(buf, "font%d", i); + namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, buf); if (namedHashPtr == NULL) { - Tcl_AppendResult(interp, "named font \"", string, - "\" doesn't exist", (char *) NULL); - return TCL_ERROR; - } - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); - if (nfPtr->refCount != 0) { - nfPtr->deletePending = 1; - } else { - Tcl_DeleteHashEntry(namedHashPtr); - ckfree((char *) nfPtr); + break; } } - break; + name = buf; + skip = 2; + } + TkInitFontAttributes(&fa); + if (ConfigAttributesObj(interp, tkwin, objc - skip, objv + skip, + &fa) != TCL_OK) { + return TCL_ERROR; } - case FONT_FAMILIES: { - int skip; + if (CreateNamedFont(interp, tkwin, name, &fa) != TCL_OK) { + return TCL_ERROR; + } + Tcl_AppendResult(interp, name, NULL); + break; + } + case FONT_DELETE: { + int i; + char *string; + NamedFont *nfPtr; + Tcl_HashEntry *namedHashPtr; - skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin); - if (skip < 0) { - return TCL_ERROR; - } - if (objc - skip != 2) { - Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?"); - return TCL_ERROR; - } - TkpGetFontFamilies(interp, tkwin); - break; + /* + * Delete the named font. If there are still widgets using this font, + * then it isn't deleted right away. + */ + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "fontname ?fontname ...?"); + return TCL_ERROR; } - case FONT_MEASURE: { - char *string; - Tk_Font tkfont; - int length, skip; - Tcl_Obj *resultPtr; - - skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin); - if (skip < 0) { - return TCL_ERROR; - } - if (objc - skip != 4) { - Tcl_WrongNumArgs(interp, 2, objv, - "font ?-displayof window? text"); + for (i = 2; i < objc; i++) { + string = Tcl_GetString(objv[i]); + namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, string); + if (namedHashPtr == NULL) { + Tcl_AppendResult(interp, "named font \"", string, + "\" doesn't exist", (char *) NULL); return TCL_ERROR; } - tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); - if (tkfont == NULL) { - return TCL_ERROR; + nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); + if (nfPtr->refCount != 0) { + nfPtr->deletePending = 1; + } else { + Tcl_DeleteHashEntry(namedHashPtr); + ckfree((char *) nfPtr); } - string = Tcl_GetStringFromObj(objv[3 + skip], &length); - resultPtr = Tcl_GetObjResult(interp); - Tcl_SetIntObj(resultPtr, Tk_TextWidth(tkfont, string, length)); - Tk_FreeFont(tkfont); - break; } - case FONT_METRICS: { - Tk_Font tkfont; - int skip, index, i; - CONST TkFontMetrics *fmPtr; - static CONST char *switches[] = { - "-ascent", "-descent", "-linespace", "-fixed", NULL - }; + break; + } + case FONT_FAMILIES: { + int skip; - skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin); - if (skip < 0) { - return TCL_ERROR; - } - if ((objc < 3) || ((objc - skip) > 4)) { - Tcl_WrongNumArgs(interp, 2, objv, - "font ?-displayof window? ?option?"); - return TCL_ERROR; - } - tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); - if (tkfont == NULL) { + skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin); + if (skip < 0) { + return TCL_ERROR; + } + if (objc - skip != 2) { + Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?"); + return TCL_ERROR; + } + TkpGetFontFamilies(interp, tkwin); + break; + } + case FONT_MEASURE: { + char *string; + Tk_Font tkfont; + int length, skip; + Tcl_Obj *resultPtr; + + skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin); + if (skip < 0) { + return TCL_ERROR; + } + if (objc - skip != 4) { + Tcl_WrongNumArgs(interp, 2, objv, "font ?-displayof window? text"); + return TCL_ERROR; + } + tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); + if (tkfont == NULL) { + return TCL_ERROR; + } + string = Tcl_GetStringFromObj(objv[3 + skip], &length); + resultPtr = Tcl_GetObjResult(interp); + Tcl_SetIntObj(resultPtr, Tk_TextWidth(tkfont, string, length)); + Tk_FreeFont(tkfont); + break; + } + case FONT_METRICS: { + Tk_Font tkfont; + int skip, index, i; + CONST TkFontMetrics *fmPtr; + static CONST char *switches[] = { + "-ascent", "-descent", "-linespace", "-fixed", NULL + }; + + skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin); + if (skip < 0) { + return TCL_ERROR; + } + if ((objc < 3) || ((objc - skip) > 4)) { + Tcl_WrongNumArgs(interp, 2, objv, + "font ?-displayof window? ?option?"); + return TCL_ERROR; + } + tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); + if (tkfont == NULL) { + return TCL_ERROR; + } + objc -= skip; + objv += skip; + fmPtr = GetFontMetrics(tkfont); + if (objc == 3) { + char buf[64 + TCL_INTEGER_SPACE * 4]; + + sprintf(buf, "-ascent %d -descent %d -linespace %d -fixed %d", + fmPtr->ascent, fmPtr->descent, + fmPtr->ascent + fmPtr->descent, fmPtr->fixed); + Tcl_AppendResult(interp, buf, NULL); + } else { + if (Tcl_GetIndexFromObj(interp, objv[3], switches, "metric", 0, + &index) != TCL_OK) { + Tk_FreeFont(tkfont); return TCL_ERROR; } - objc -= skip; - objv += skip; - fmPtr = GetFontMetrics(tkfont); - if (objc == 3) { - char buf[64 + TCL_INTEGER_SPACE * 4]; - - sprintf(buf, "-ascent %d -descent %d -linespace %d -fixed %d", - fmPtr->ascent, fmPtr->descent, - fmPtr->ascent + fmPtr->descent, - fmPtr->fixed); - Tcl_AppendResult(interp, buf, NULL); - } else { - if (Tcl_GetIndexFromObj(interp, objv[3], switches, - "metric", 0, &index) != TCL_OK) { - Tk_FreeFont(tkfont); - return TCL_ERROR; - } - i = 0; /* Needed only to prevent compiler - * warning. */ - switch (index) { - case 0: i = fmPtr->ascent; break; - case 1: i = fmPtr->descent; break; - case 2: i = fmPtr->ascent + fmPtr->descent; break; - case 3: i = fmPtr->fixed; break; - } - Tcl_SetIntObj(Tcl_GetObjResult(interp), i); + i = 0; /* Needed only to prevent compiler warning. */ + switch (index) { + case 0: i = fmPtr->ascent; break; + case 1: i = fmPtr->descent; break; + case 2: i = fmPtr->ascent + fmPtr->descent; break; + case 3: i = fmPtr->fixed; break; } - Tk_FreeFont(tkfont); - break; + Tcl_SetIntObj(Tcl_GetObjResult(interp), i); } - case FONT_NAMES: { - char *string; - NamedFont *nfPtr; - Tcl_HashSearch search; - Tcl_HashEntry *namedHashPtr; - Tcl_Obj *strPtr, *resultPtr; - - if (objc != 2) { - Tcl_WrongNumArgs(interp, 1, objv, "names"); - return TCL_ERROR; - } - resultPtr = Tcl_GetObjResult(interp); - namedHashPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search); - while (namedHashPtr != NULL) { - nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); - if (nfPtr->deletePending == 0) { - string = Tcl_GetHashKey(&fiPtr->namedTable, namedHashPtr); - strPtr = Tcl_NewStringObj(string, -1); - Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); - } - namedHashPtr = Tcl_NextHashEntry(&search); + Tk_FreeFont(tkfont); + break; + } + case FONT_NAMES: { + char *string; + NamedFont *nfPtr; + Tcl_HashSearch search; + Tcl_HashEntry *namedHashPtr; + Tcl_Obj *strPtr, *resultPtr; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "names"); + return TCL_ERROR; + } + resultPtr = Tcl_GetObjResult(interp); + namedHashPtr = Tcl_FirstHashEntry(&fiPtr->namedTable, &search); + while (namedHashPtr != NULL) { + nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); + if (nfPtr->deletePending == 0) { + string = Tcl_GetHashKey(&fiPtr->namedTable, namedHashPtr); + strPtr = Tcl_NewStringObj(string, -1); + Tcl_ListObjAppendElement(NULL, resultPtr, strPtr); } - break; + namedHashPtr = Tcl_NextHashEntry(&search); } + break; + } } return TCL_OK; } @@ -766,10 +760,10 @@ Tk_FontObjCmd(clientData, interp, objc, objv) * * UpdateDependentFonts, TheWorldHasChanged, RecomputeWidgets -- * - * Called when the attributes of a named font changes. Updates all - * the instantiated fonts that depend on that named font and then - * uses the brute force approach and prepares every widget to - * recompute its geometry. + * Called when the attributes of a named font changes. Updates all the + * instantiated fonts that depend on that named font and then uses the + * brute force approach and prepares every widget to recompute its + * geometry. * * Results: * None. @@ -794,8 +788,8 @@ UpdateDependentFonts(fiPtr, tkwin, namedHashPtr) nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); if (nfPtr->refCount == 0) { /* - * Well nobody's using this named font, so don't have to tell - * any widgets to recompute themselves. + * Well nobody's using this named font, so don't have to tell any + * widgets to recompute themselves. */ return; @@ -842,22 +836,23 @@ RecomputeWidgets(winPtr) /* * Notify all the descendants of this window that the world has changed. * - * This could be done recursively or iteratively. The recursive version - * is easier to implement and understand, and typically, windows with a - * -font option will be leaf nodes in the widget heirarchy (buttons, - * labels, etc.), so the recursion depth will be shallow. + * This could be done recursively or iteratively. The recursive version is + * easier to implement and understand, and typically, windows with a -font + * option will be leaf nodes in the widget heirarchy (buttons, labels, + * etc.), so the recursion depth will be shallow. * - * However, the additional overhead of the recursive calls may become - * a performance problem if typical usage alters such that -font'ed widgets - * appear high in the heirarchy, causing deep recursion. This could happen + * However, the additional overhead of the recursive calls may become a + * performance problem if typical usage alters such that -font'ed widgets + * appear high in the heirarchy, causing deep recursion. This could happen * with text widgets, or more likely with the (not yet existant) labeled - * frame widget. With these widgets it is possible, even likely, that a + * frame widget. With these widgets it is possible, even likely, that a * -font'ed widget (text or labeled frame) will not be a leaf node, but - * will instead have many descendants. If this is ever found to cause - * a performance problem, it may be worth investigating an iterative - * version of the code below. + * will instead have many descendants. If this is ever found to cause a + * performance problem, it may be worth investigating an iterative version + * of the code below. */ - for (winPtr = winPtr->childList; winPtr != NULL; winPtr = winPtr->nextPtr) { + + for (winPtr=winPtr->childList ; winPtr!=NULL ; winPtr=winPtr->nextPtr) { RecomputeWidgets(winPtr); } } @@ -867,21 +862,21 @@ RecomputeWidgets(winPtr) * * CreateNamedFont -- * - * Create the specified named font with the given attributes in the - * named font table associated with the interp. + * Create the specified named font with the given attributes in the named + * font table associated with the interp. * * Results: - * Returns TCL_OK if the font was successfully created, or TCL_ERROR - * if the named font already existed. If TCL_ERROR is returned, an - * error message is left in the interp's result. + * Returns TCL_OK if the font was successfully created, or TCL_ERROR if + * the named font already existed. If TCL_ERROR is returned, an error + * message is left in the interp's result. * * Side effects: * Assume there used to exist a named font by the specified name, and * that the named font had been deleted, but there were still some - * widgets using the named font at the time it was deleted. If a - * new named font is created with the same name, all those widgets - * that were using the old named font will be redisplayed using - * the new named font's attributes. + * widgets using the named font at the time it was deleted. If a new + * named font is created with the same name, all those widgets that were + * using the old named font will be redisplayed using the new named + * font's attributes. * *--------------------------------------------------------------------------- */ @@ -896,12 +891,12 @@ CreateNamedFont(interp, tkwin, name, faPtr) TkFontInfo *fiPtr; Tcl_HashEntry *namedHashPtr; int new; - NamedFont *nfPtr; + NamedFont *nfPtr; fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; namedHashPtr = Tcl_CreateHashEntry(&fiPtr->namedTable, name, &new); - + if (new == 0) { nfPtr = (NamedFont *) Tcl_GetHashValue(namedHashPtr); if (nfPtr->deletePending == 0) { @@ -912,9 +907,9 @@ CreateNamedFont(interp, tkwin, name, faPtr) } /* - * Recreating a named font with the same name as a previous - * named font. Some widgets were still using that named - * font, so they need to get redisplayed. + * Recreating a named font with the same name as a previous named + * font. Some widgets were still using that named font, so they need + * to get redisplayed. */ nfPtr->fa = *faPtr; @@ -927,7 +922,7 @@ CreateNamedFont(interp, tkwin, name, faPtr) nfPtr->deletePending = 0; Tcl_SetHashValue(namedHashPtr, nfPtr); nfPtr->fa = *faPtr; - nfPtr->refCount = 0; + nfPtr->refCount = 0; nfPtr->deletePending = 0; return TCL_OK; } @@ -935,21 +930,21 @@ CreateNamedFont(interp, tkwin, name, faPtr) /* *--------------------------------------------------------------------------- * - * Tk_GetFont -- + * Tk_GetFont -- * * Given a string description of a font, map the description to a * corresponding Tk_Font that represents the font. * * Results: - * The return value is token for the font, or NULL if an error - * prevented the font from being created. If NULL is returned, an - * error message will be left in the interp's result. + * The return value is token for the font, or NULL if an error prevented + * the font from being created. If NULL is returned, an error message + * will be left in the interp's result. * * Side effects: - * The font is added to an internal database with a reference - * count. For each call to this procedure, there should eventually - * be a call to Tk_FreeFont() or Tk_FreeFontFromObj() so that the - * database is cleaned up when fonts aren't in use anymore. + * The font is added to an internal database with a reference count. For + * each call to this function, there should eventually be a call to + * Tk_FreeFont() or Tk_FreeFontFromObj() so that the database is cleaned + * up when fonts aren't in use anymore. * *--------------------------------------------------------------------------- */ @@ -961,34 +956,34 @@ Tk_GetFont(interp, tkwin, string) CONST char *string; /* String describing font, as: named font, * native format, or parseable string. */ { - Tk_Font tkfont; + Tk_Font tkfont; Tcl_Obj *strPtr; strPtr = Tcl_NewStringObj((char *) string, -1); Tcl_IncrRefCount(strPtr); tkfont = Tk_AllocFontFromObj(interp, tkwin, strPtr); - Tcl_DecrRefCount(strPtr); + Tcl_DecrRefCount(strPtr); return tkfont; } /* *--------------------------------------------------------------------------- * - * Tk_AllocFontFromObj -- + * Tk_AllocFontFromObj -- * * Given a string description of a font, map the description to a * corresponding Tk_Font that represents the font. * * Results: - * The return value is token for the font, or NULL if an error - * prevented the font from being created. If NULL is returned, an - * error message will be left in interp's result object. + * The return value is token for the font, or NULL if an error prevented + * the font from being created. If NULL is returned, an error message + * will be left in interp's result object. * * Side effects: - * The font is added to an internal database with a reference - * count. For each call to this procedure, there should eventually - * be a call to Tk_FreeFont() or Tk_FreeFontFromObj() so that the - * database is cleaned up when fonts aren't in use anymore. + * The font is added to an internal database with a reference count. For + * each call to this function, there should eventually be a call to + * Tk_FreeFont() or Tk_FreeFontFromObj() so that the database is cleaned + * up when fonts aren't in use anymore. * *--------------------------------------------------------------------------- */ @@ -1016,8 +1011,8 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr) if (oldFontPtr != NULL) { if (oldFontPtr->resourceRefCount == 0) { /* - * This is a stale reference: it refers to a TkFont that's - * no longer in use. Clear the reference. + * This is a stale reference: it refers to a TkFont that's no + * longer in use. Clear the reference. */ FreeFontObjProc(objPtr); @@ -1029,8 +1024,8 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr) } /* - * Next, search the list of fonts that have the name we want, to see - * if one of them is for the right screen. + * Next, search the list of fonts that have the name we want, to see if + * one of them is for the right screen. */ new = 0; @@ -1053,7 +1048,7 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr) } /* - * The desired font isn't in the table. Make a new one. + * The desired font isn't in the table. Make a new one. */ namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, @@ -1121,7 +1116,7 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr) * Get information used for drawing underlines in generic code on a * non-underlined font. */ - + descent = fontPtr->fm.descent; fontPtr->underlinePos = descent / 2; fontPtr->underlineHeight = TkFontGetPixels(tkwin, fontPtr->fa.size) / 10; @@ -1130,9 +1125,9 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr) } if (fontPtr->underlinePos + fontPtr->underlineHeight > descent) { /* - * If this set of values would cause the bottom of the underline - * bar to stick below the descent of the font, jack the underline - * up a bit higher. + * If this set of values would cause the bottom of the underline bar + * to stick below the descent of the font, jack the underline up a bit + * higher. */ fontPtr->underlineHeight = descent - fontPtr->underlinePos; @@ -1141,7 +1136,7 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr) fontPtr->underlineHeight = 1; } } - + objPtr->internalRep.twoPtrValue.ptr1 = (VOID *) fontPtr; return (Tk_Font) fontPtr; } @@ -1151,16 +1146,16 @@ Tk_AllocFontFromObj(interp, tkwin, objPtr) * * Tk_GetFontFromObj -- * - * Find the font that corresponds to a given object. The font must - * have already been created by Tk_GetFont or Tk_AllocFontFromObj. + * Find the font that corresponds to a given object. The font must have + * already been created by Tk_GetFont or Tk_AllocFontFromObj. * * Results: - * The return value is a token for the font that matches objPtr - * and is suitable for use in tkwin. + * The return value is a token for the font that matches objPtr and is + * suitable for use in tkwin. * * Side effects: - * If the object is not already a font ref, the conversion will free - * any old internal representation. + * If the object is not already a font ref, the conversion will free any + * old internal representation. * *---------------------------------------------------------------------- */ @@ -1173,7 +1168,7 @@ Tk_GetFontFromObj(tkwin, objPtr) TkFontInfo *fiPtr = ((TkWindow *) tkwin)->mainPtr->fontInfoPtr; TkFont *fontPtr; Tcl_HashEntry *hashPtr; - + if (objPtr->typePtr != &tkFontObjType) { SetFontFromAny((Tcl_Interp *) NULL, objPtr); } @@ -1183,8 +1178,8 @@ Tk_GetFontFromObj(tkwin, objPtr) if (fontPtr != NULL) { if (fontPtr->resourceRefCount == 0) { /* - * This is a stale reference: it refers to a TkFont that's - * no longer in use. Clear the reference. + * This is a stale reference: it refers to a TkFont that's no + * longer in use. Clear the reference. */ FreeFontObjProc(objPtr); @@ -1195,8 +1190,8 @@ Tk_GetFontFromObj(tkwin, objPtr) } /* - * Next, search the list of fonts that have the name we want, to see - * if one of them is for the right screen. + * Next, search the list of fonts that have the name we want, to see if + * one of them is for the right screen. */ if (fontPtr != NULL) { @@ -1225,15 +1220,15 @@ Tk_GetFontFromObj(tkwin, objPtr) * * SetFontFromAny -- * - * Convert the internal representation of a Tcl object to the - * font internal form. + * Convert the internal representation of a Tcl object to the font + * internal form. * * Results: * Always returns TCL_OK. * * Side effects: - * The object is left with its typePtr pointing to tkFontObjType. - * The TkFont pointer is NULL. + * The object is left with its typePtr pointing to tkFontObjType. The + * TkFont pointer is NULL. * *---------------------------------------------------------------------- */ @@ -1246,7 +1241,7 @@ SetFontFromAny(interp, objPtr) Tcl_ObjType *typePtr; /* - * Free the old internalRep before setting the new one. + * Free the old internalRep before setting the new one. */ Tcl_GetString(objPtr); @@ -1268,10 +1263,10 @@ SetFontFromAny(interp, objPtr) * Given a font, return a textual string identifying it. * * Results: - * The return value is the description that was passed to - * Tk_GetFont() to create the font. The storage for the returned - * string is only guaranteed to persist until the font is deleted. - * The caller should not modify this string. + * The return value is the description that was passed to Tk_GetFont() to + * create the font. The storage for the returned string is only + * guaranteed to persist until the font is deleted. The caller should not + * modify this string. * * Side effects: * None. @@ -1292,7 +1287,7 @@ Tk_NameOfFont(tkfont) /* *--------------------------------------------------------------------------- * - * Tk_FreeFont -- + * Tk_FreeFont -- * * Called to release a font allocated by Tk_GetFont(). * @@ -1300,8 +1295,8 @@ Tk_NameOfFont(tkfont) * None. * * Side effects: - * The reference count associated with font is decremented, and - * only deallocated when no one is using it. + * The reference count associated with font is decremented, and only + * deallocated when no one is using it. * *--------------------------------------------------------------------------- */ @@ -1323,9 +1318,8 @@ Tk_FreeFont(tkfont) } if (fontPtr->namedHashPtr != NULL) { /* - * This font derived from a named font. Reduce the reference - * count on the named font and free it if no-one else is - * using it. + * This font derived from a named font. Reduce the reference count on + * the named font and free it if no-one else is using it. */ nfPtr = (NamedFont *) Tcl_GetHashValue(fontPtr->namedHashPtr); @@ -1359,7 +1353,7 @@ Tk_FreeFont(tkfont) /* *--------------------------------------------------------------------------- * - * Tk_FreeFontFromObj -- + * Tk_FreeFontFromObj -- * * Called to release a font inside a Tcl_Obj *. Decrements the refCount * of the font and removes it from the hash tables if necessary. @@ -1368,16 +1362,16 @@ Tk_FreeFont(tkfont) * None. * * Side effects: - * The reference count associated with font is decremented, and - * only deallocated when no one is using it. + * The reference count associated with font is decremented, and only + * deallocated when no one is using it. * *--------------------------------------------------------------------------- */ void Tk_FreeFontFromObj(tkwin, objPtr) - Tk_Window tkwin; /* The window this font lives in. Needed - * for the screen value. */ + Tk_Window tkwin; /* The window this font lives in. Needed for + * the screen value. */ Tcl_Obj *objPtr; /* The Tcl_Obj * to be freed. */ { Tk_FreeFont(Tk_GetFontFromObj(tkwin, objPtr)); @@ -1386,19 +1380,18 @@ Tk_FreeFontFromObj(tkwin, objPtr) /* *--------------------------------------------------------------------------- * - * FreeFontObjProc -- + * FreeFontObjProc -- * - * This proc is called to release an object reference to a font. - * Called when the object's internal rep is released or when - * the cached fontPtr needs to be changed. + * This proc is called to release an object reference to a font. Called + * when the object's internal rep is released or when the cached fontPtr + * needs to be changed. * * Results: * None. * * Side effects: - * The object reference count is decremented. When both it - * and the hash ref count go to zero, the font's resources - * are released. + * The object reference count is decremented. When both it and the hash + * ref count go to zero, the font's resources are released. * *--------------------------------------------------------------------------- */ @@ -1421,17 +1414,17 @@ FreeFontObjProc(objPtr) /* *--------------------------------------------------------------------------- * - * DupFontObjProc -- + * DupFontObjProc -- * - * When a cached font object is duplicated, this is called to - * update the internal reps. + * When a cached font object is duplicated, this is called to update the + * internal reps. * * Results: * None. * * Side effects: - * The font's objRefCount is incremented and the internal rep - * of the copy is set to point to it. + * The font's objRefCount is incremented and the internal rep of the copy + * is set to point to it. * *--------------------------------------------------------------------------- */ @@ -1442,7 +1435,7 @@ DupFontObjProc(srcObjPtr, dupObjPtr) Tcl_Obj *dupObjPtr; /* The object we are copying to. */ { TkFont *fontPtr = (TkFont *) srcObjPtr->internalRep.twoPtrValue.ptr1; - + dupObjPtr->typePtr = srcObjPtr->typePtr; dupObjPtr->internalRep.twoPtrValue.ptr1 = (VOID *) fontPtr; @@ -1456,10 +1449,10 @@ DupFontObjProc(srcObjPtr, dupObjPtr) * * Tk_FontId -- * - * Given a font, return an opaque handle that should be selected - * into the XGCValues structure in order to get the constructed - * gc to use this font. This procedure would go away if the - * XGCValues structure were replaced with a TkGCValues structure. + * Given a font, return an opaque handle that should be selected into the + * XGCValues structure in order to get the constructed gc to use this + * font. This function would go away if the XGCValues structure were + * replaced with a TkGCValues structure. * * Results: * As above. @@ -1485,26 +1478,27 @@ Tk_FontId(tkfont) * * Tk_GetFontMetrics -- * - * Returns overall ascent and descent metrics for the given font. - * These values can be used to space multiple lines of text and - * to align the baselines of text in different fonts. + * Returns overall ascent and descent metrics for the given font. These + * values can be used to space multiple lines of text and to align the + * baselines of text in different fonts. * * Results: - * If *heightPtr is non-NULL, it is filled with the overall height - * of the font, which is the sum of the ascent and descent. - * If *ascentPtr or *descentPtr is non-NULL, they are filled with - * the ascent and/or descent information for the font. + * If *heightPtr is non-NULL, it is filled with the overall height of the + * font, which is the sum of the ascent and descent. If *ascentPtr or + * *descentPtr is non-NULL, they are filled with the ascent and/or + * descent information for the font. * * Side effects: * None. * *--------------------------------------------------------------------------- */ + void Tk_GetFontMetrics(tkfont, fmPtr) Tk_Font tkfont; /* Font in which metrics are calculated. */ - Tk_FontMetrics *fmPtr; /* Pointer to structure in which font - * metrics for tkfont will be stored. */ + Tk_FontMetrics *fmPtr; /* Pointer to structure in which font metrics + * for tkfont will be stored. */ { TkFont *fontPtr; @@ -1519,25 +1513,24 @@ Tk_GetFontMetrics(tkfont, fmPtr) * * Tk_PostscriptFontName -- * - * Given a Tk_Font, return the name of the corresponding Postscript - * font. + * Given a Tk_Font, return the name of the corresponding Postscript font. * * Results: - * The return value is the pointsize of the given Tk_Font. - * The name of the Postscript font is appended to dsPtr. + * The return value is the pointsize of the given Tk_Font. The name of + * the Postscript font is appended to dsPtr. * * Side effects: - * If the font does not exist on the printer, the print job will - * fail at print time. Given a "reasonable" Postscript printer, - * the following Tk_Font font families should print correctly: + * If the font does not exist on the printer, the print job will fail at + * print time. Given a "reasonable" Postscript printer, the following + * Tk_Font font families should print correctly: * * Avant Garde, Arial, Bookman, Courier, Courier New, Geneva, * Helvetica, Monaco, New Century Schoolbook, New York, * Palatino, Symbol, Times, Times New Roman, Zapf Chancery, * and Zapf Dingbats. * - * Any other Tk_Font font families may not print correctly - * because the computed Postscript font name may be incorrect. + * Any other Tk_Font font families may not print correctly because the + * computed Postscript font name may be incorrect. * *--------------------------------------------------------------------------- */ @@ -1558,9 +1551,9 @@ Tk_PostscriptFontName(tkfont, dsPtr) fontPtr = (TkFont *) tkfont; /* - * Convert the case-insensitive Tk_Font family name to the - * case-sensitive Postscript family name. Take out any spaces and - * capitalize the first letter of each word. + * Convert the case-insensitive Tk_Font family name to the case-sensitive + * Postscript family name. Take out any spaces and capitalize the first + * letter of each word. */ family = fontPtr->fa.family; @@ -1588,8 +1581,8 @@ Tk_PostscriptFontName(tkfont, dsPtr) /* * Inline, capitalize the first letter of each word, lowercase the * rest of the letters in each word, and then take out the spaces - * between the words. This may make the DString shorter, which is - * safe to do. + * between the words. This may make the DString shorter, which is safe + * to do. */ Tcl_DStringAppend(dsPtr, family, -1); @@ -1606,7 +1599,7 @@ Tk_PostscriptFontName(tkfont, dsPtr) ch = Tcl_UniCharToUpper(ch); upper = 0; } else { - ch = Tcl_UniCharToLower(ch); + ch = Tcl_UniCharToLower(ch); } dest += Tcl_UniCharToUtf(ch, dest); } @@ -1670,7 +1663,7 @@ Tk_PostscriptFontName(tkfont, dsPtr) */ if ((slantString == NULL) && (weightString == NULL)) { - if ((strcmp(family, "Times") == 0) + if ((strcmp(family, "Times") == 0) || (strcmp(family, "NewCenturySchlbk") == 0) || (strcmp(family, "Palatino") == 0)) { Tcl_DStringAppend(dsPtr, "-Roman", -1); @@ -1694,8 +1687,8 @@ Tk_PostscriptFontName(tkfont, dsPtr) * Tk_TextWidth -- * * A wrapper function for the more complicated interface of - * Tk_MeasureChars. Computes how much space the given - * simple string needs. + * Tk_MeasureChars. Computes how much space the given simple string + * needs. * * Results: * The return value is the width (in pixels) of the given string. @@ -1710,8 +1703,8 @@ int Tk_TextWidth(tkfont, string, numBytes) Tk_Font tkfont; /* Font in which text will be measured. */ CONST char *string; /* String whose width will be computed. */ - int numBytes; /* Number of bytes to consider from - * string, or < 0 for strlen(). */ + int numBytes; /* Number of bytes to consider from string, or + * < 0 for strlen(). */ { int width; @@ -1727,13 +1720,13 @@ Tk_TextWidth(tkfont, string, numBytes) * * Tk_UnderlineChars -- * - * This procedure draws an underline for a given range of characters - * in a given string. It doesn't draw the characters (which are - * assumed to have been displayed previously); it just draws the - * underline. This procedure would mainly be used to quickly - * underline a few characters without having to construct an - * underlined font. To produce properly underlined text, the - * appropriate underlined font should be constructed and used. + * This function draws an underline for a given range of characters in a + * given string. It doesn't draw the characters (which are assumed to + * have been displayed previously); it just draws the underline. This + * function would mainly be used to quickly underline a few characters + * without having to construct an underlined font. To produce properly + * underlined text, the appropriate underlined font should be constructed + * and used. * * Results: * None. @@ -1751,8 +1744,8 @@ Tk_UnderlineChars(display, drawable, gc, tkfont, string, x, y, firstByte, Drawable drawable; /* Window or pixmap in which to draw. */ GC gc; /* Graphics context for actually drawing * line. */ - Tk_Font tkfont; /* Font used in GC; must have been allocated - * by Tk_GetFont(). Used for character + Tk_Font tkfont; /* Font used in GC; must have been allocated + * by Tk_GetFont(). Used for character * dimensions, etc. */ CONST char *string; /* String containing characters to be * underlined or overstruck. */ @@ -1766,7 +1759,7 @@ Tk_UnderlineChars(display, drawable, gc, tkfont, string, x, y, firstByte, int startX, endX; fontPtr = (TkFont *) tkfont; - + Tk_MeasureChars(tkfont, string, firstByte, -1, 0, &startX); Tk_MeasureChars(tkfont, string, lastByte, -1, 0, &endX); @@ -1780,29 +1773,26 @@ Tk_UnderlineChars(display, drawable, gc, tkfont, string, x, y, firstByte, * * Tk_ComputeTextLayout -- * - * Computes the amount of screen space needed to display a - * multi-line, justified string of text. Records all the - * measurements that were done to determine to size and - * positioning of the individual lines of text; this information - * can be used by the Tk_DrawTextLayout() procedure to + * Computes the amount of screen space needed to display a multi-line, + * justified string of text. Records all the measurements that were done + * to determine to size and positioning of the individual lines of text; + * this information can be used by the Tk_DrawTextLayout() function to * display the text quickly (without remeasuring it). * - * This procedure is useful for simple widgets that want to - * display single-font, multi-line text and want Tk to handle the - * details. + * This function is useful for simple widgets that want to display + * single-font, multi-line text and want Tk to handle the details. * * Results: - * The return value is a Tk_TextLayout token that holds the - * measurement information for the given string. The token is - * only valid for the given string. If the string is freed, - * the token is no longer valid and must also be freed. To free - * the token, call Tk_FreeTextLayout(). + * The return value is a Tk_TextLayout token that holds the measurement + * information for the given string. The token is only valid for the + * given string. If the string is freed, the token is no longer valid and + * must also be freed. To free the token, call Tk_FreeTextLayout(). * - * The dimensions of the screen area needed to display the text - * are stored in *widthPtr and *heightPtr. + * The dimensions of the screen area needed to display the text are + * stored in *widthPtr and *heightPtr. * * Side effects: - * Memory is allocated to hold the measurement information. + * Memory is allocated to hold the measurement information. * *--------------------------------------------------------------------------- */ @@ -1815,15 +1805,15 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, * computed. */ int numChars; /* Number of characters to consider from * string, or < 0 for strlen(). */ - int wrapLength; /* Longest permissible line length, in - * pixels. <= 0 means no automatic wrapping: - * just let lines get as long as needed. */ + int wrapLength; /* Longest permissible line length, in pixels. + * <= 0 means no automatic wrapping: just let + * lines get as long as needed. */ Tk_Justify justify; /* How to justify lines. */ - int flags; /* Flag bits OR-ed together. - * TK_IGNORE_TABS means that tab characters - * should not be expanded. TK_IGNORE_NEWLINES - * means that newline characters should not - * cause a line break. */ + int flags; /* Flag bits OR-ed together. TK_IGNORE_TABS + * means that tab characters should not be + * expanded. TK_IGNORE_NEWLINES means that + * newline characters should not cause a line + * break. */ int *widthPtr; /* Filled with width of string. */ int *heightPtr; /* Filled with height of string. */ { @@ -1839,7 +1829,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, int curLine, layoutHeight; Tcl_DStringInit(&lineBuffer); - + fontPtr = (TkFont *) tkfont; if ((fontPtr == NULL) || (string == NULL)) { if (widthPtr != NULL) { @@ -1883,7 +1873,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, special = string; flags &= TK_IGNORE_TABS | TK_IGNORE_NEWLINES; - flags |= TK_WHOLE_WORDS | TK_AT_LEAST_ONE; + flags |= TK_WHOLE_WORDS | TK_AT_LEAST_ONE; for (start = string; start < end; ) { if (start >= special) { /* @@ -1891,7 +1881,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, * * INTL: Note that it is safe to increment by byte, because we are * looking for 7-bit characters that will appear unchanged in - * UTF-8. At some point we may need to support the full Unicode + * UTF-8. At some point we may need to support the full Unicode * whitespace set. */ @@ -1911,7 +1901,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, /* * Special points at the next special character (or the end of the - * string). Process characters between start and special. + * string). Process characters between start and special. */ chunkPtr = NULL; @@ -1923,7 +1913,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, if (bytesThisChunk > 0) { chunkPtr = NewChunk(&layoutPtr, &maxChunks, start, bytesThisChunk, curX, newX, baseline); - + start += bytesThisChunk; curX = newX; } @@ -1954,7 +1944,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, flags &= ~TK_AT_LEAST_ONE; continue; } - } else { + } else { NewChunk(&layoutPtr, &maxChunks, start, 1, curX, curX, baseline)->numDisplayChars = -1; start++; @@ -1963,9 +1953,9 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, } /* - * No more characters are going to go on this line, either because - * no more characters can fit or there are no more characters left. - * Consume all extra spaces at end of line. + * No more characters are going to go on this line, either because no + * more characters can fit or there are no more characters left. + * Consume all extra spaces at end of line. */ while ((start < end) && isspace(UCHAR(*start))) { /* INTL: ISO space */ @@ -1985,9 +1975,9 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, CONST char *end; /* - * Append all the extra spaces on this line to the end of the - * last text chunk. This is a little tricky because we are - * switching back and forth between characters and bytes. + * Append all the extra spaces on this line to the end of the last + * text chunk. This is a little tricky because we are switching + * back and forth between characters and bytes. */ end = chunkPtr->start + chunkPtr->numBytes; @@ -2001,7 +1991,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, } } - wrapLine: + wrapLine: flags |= TK_AT_LEAST_ONE; /* @@ -2014,8 +2004,8 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, } /* - * Remember width of this line, so that all chunks on this line - * can be centered or right justified, if necessary. + * Remember width of this line, so that all chunks on this line can be + * centered or right justified, if necessary. */ Tcl_DStringAppend(&lineBuffer, (char *) &curX, sizeof(curX)); @@ -2025,9 +2015,8 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, } /* - * If last line ends with a newline, then we need to make a 0 width - * chunk on the next line. Otherwise "Hello" and "Hello\n" are the - * same height. + * If last line ends with a newline, then we need to make a 0 width chunk + * on the next line. Otherwise "Hello" and "Hello\n" are the same height. */ if ((layoutPtr->numChunks > 0) && ((flags & TK_IGNORE_NEWLINES) == 0)) { @@ -2038,7 +2027,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, Tcl_DStringAppend(&lineBuffer, (char *) &curX, sizeof(curX)); baseline += height; } - } + } layoutPtr->width = maxWidth; layoutHeight = baseline - fmPtr->ascent; @@ -2046,9 +2035,9 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, layoutHeight = height; /* - * This fake chunk is used by the other procedures so that they can - * pretend that there is a chunk with no chars in it, which makes - * the coding simpler. + * This fake chunk is used by the other functions so that they can + * pretend that there is a chunk with no chars in it, which makes the + * coding simpler. */ layoutPtr->numChunks = 1; @@ -2065,7 +2054,7 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, * Using maximum line length, shift all the chunks so that the lines * are all justified correctly. */ - + curLine = 0; chunkPtr = layoutPtr->chunks; y = chunkPtr->y; @@ -2103,8 +2092,8 @@ Tk_ComputeTextLayout(tkfont, string, numChars, wrapLength, justify, flags, * * Tk_FreeTextLayout -- * - * This procedure is called to release the storage associated with - * a Tk_TextLayout when it is no longer needed. + * This function is called to release the storage associated with a + * Tk_TextLayout when it is no longer needed. * * Results: * None. @@ -2135,9 +2124,8 @@ Tk_FreeTextLayout(textLayout) * Use the information in the Tk_TextLayout token to display a * multi-line, justified string of text. * - * This procedure is useful for simple widgets that need to - * display single-font, multi-line text and want Tk to handle - * the details. + * This function is useful for simple widgets that need to display + * single-font, multi-line text and want Tk to handle the details. * * Results: * None. @@ -2153,16 +2141,16 @@ Tk_DrawTextLayout(display, drawable, gc, layout, x, y, firstChar, lastChar) Display *display; /* Display on which to draw. */ Drawable drawable; /* Window or pixmap in which to draw. */ GC gc; /* Graphics context to use for drawing text. */ - Tk_TextLayout layout; /* Layout information, from a previous call - * to Tk_ComputeTextLayout(). */ + Tk_TextLayout layout; /* Layout information, from a previous call to + * Tk_ComputeTextLayout(). */ int x, y; /* Upper-left hand corner of rectangle in * which to draw (pixels). */ int firstChar; /* The index of the first character to draw - * from the given text item. 0 specfies the + * from the given text item. 0 specfies the * beginning. */ - int lastChar; /* The index just after the last character - * to draw from the given text item. A number - * < 0 means to draw all characters. */ + int lastChar; /* The index just after the last character to + * draw from the given text item. A number < 0 + * means to draw all characters. */ { TextLayout *layoutPtr; int i, numDisplayChars, drawX; @@ -2213,15 +2201,14 @@ Tk_DrawTextLayout(display, drawable, gc, layout, x, y, firstChar, lastChar) * * Tk_UnderlineTextLayout -- * - * Use the information in the Tk_TextLayout token to display an - * underline below an individual character. This procedure does - * not draw the text, just the underline. + * Use the information in the Tk_TextLayout token to display an underline + * below an individual character. This function does not draw the text, + * just the underline. * - * This procedure is useful for simple widgets that need to - * display single-font, multi-line text with an individual - * character underlined and want Tk to handle the details. - * To display larger amounts of underlined text, construct - * and use an underlined font. + * This function is useful for simple widgets that need to display + * single-font, multi-line text with an individual character underlined + * and want Tk to handle the details. To display larger amounts of + * underlined text, construct and use an underlined font. * * Results: * None. @@ -2237,12 +2224,12 @@ Tk_UnderlineTextLayout(display, drawable, gc, layout, x, y, underline) Display *display; /* Display on which to draw. */ Drawable drawable; /* Window or pixmap in which to draw. */ GC gc; /* Graphics context to use for drawing text. */ - Tk_TextLayout layout; /* Layout information, from a previous call - * to Tk_ComputeTextLayout(). */ + Tk_TextLayout layout; /* Layout information, from a previous call to + * Tk_ComputeTextLayout(). */ int x, y; /* Upper-left hand corner of rectangle in * which to draw (pixels). */ - int underline; /* Index of the single character to - * underline, or -1 for no underline. */ + int underline; /* Index of the single character to underline, + * or -1 for no underline. */ { TextLayout *layoutPtr; TkFont *fontPtr; @@ -2253,7 +2240,7 @@ Tk_UnderlineTextLayout(display, drawable, gc, layout, x, y, underline) layoutPtr = (TextLayout *) layout; fontPtr = (TkFont *) layoutPtr->tkfont; - XFillRectangle(display, drawable, gc, x + xx, + XFillRectangle(display, drawable, gc, x + xx, y + yy + fontPtr->fm.ascent + fontPtr->underlinePos, (unsigned int) width, (unsigned int) fontPtr->underlineHeight); } @@ -2265,25 +2252,25 @@ Tk_UnderlineTextLayout(display, drawable, gc, layout, x, y, underline) * Tk_PointToChar -- * * Use the information in the Tk_TextLayout token to determine the - * character closest to the given point. The point must be - * specified with respect to the upper-left hand corner of the - * text layout, which is considered to be located at (0, 0). + * character closest to the given point. The point must be specified with + * respect to the upper-left hand corner of the text layout, which is + * considered to be located at (0, 0). * - * Any point whose y-value is less that 0 will be considered closest - * to the first character in the text layout; any point whose y-value - * is greater than the height of the text layout will be considered - * closest to the last character in the text layout. + * Any point whose y-value is less that 0 will be considered closest to + * the first character in the text layout; any point whose y-value is + * greater than the height of the text layout will be considered closest + * to the last character in the text layout. * - * Any point whose x-value is less than 0 will be considered closest - * to the first character on that line; any point whose x-value is - * greater than the width of the text layout will be considered - * closest to the last character on that line. + * Any point whose x-value is less than 0 will be considered closest to + * the first character on that line; any point whose x-value is greater + * than the width of the text layout will be considered closest to the + * last character on that line. * * Results: - * The return value is the index of the character that was - * closest to the point. Given a text layout with no characters, - * the value 0 will always be returned, referring to a hypothetical - * zero-width placeholder character. + * The return value is the index of the character that was closest to the + * point. Given a text layout with no characters, the value 0 will always + * be returned, referring to a hypothetical zero-width placeholder + * character. * * Side effects: * None. @@ -2293,11 +2280,11 @@ Tk_UnderlineTextLayout(display, drawable, gc, layout, x, y, underline) int Tk_PointToChar(layout, x, y) - Tk_TextLayout layout; /* Layout information, from a previous call - * to Tk_ComputeTextLayout(). */ - int x, y; /* Coordinates of point to check, with - * respect to the upper-left corner of the - * text layout. */ + Tk_TextLayout layout; /* Layout information, from a previous call to + * Tk_ComputeTextLayout(). */ + int x, y; /* Coordinates of point to check, with respect + * to the upper-left corner of the text + * layout. */ { TextLayout *layoutPtr; LayoutChunk *chunkPtr, *lastPtr; @@ -2306,8 +2293,8 @@ Tk_PointToChar(layout, x, y) if (y < 0) { /* - * Point lies above any line in this layout. Return the index of - * the first char. + * Point lies above any line in this layout. Return the index of the + * first char. */ return 0; @@ -2326,26 +2313,26 @@ Tk_PointToChar(layout, x, y) if (y < baseline + fontPtr->fm.descent) { if (x < chunkPtr->x) { /* - * Point is to the left of all chunks on this line. Return - * the index of the first character on this line. + * Point is to the left of all chunks on this line. Return the + * index of the first character on this line. */ return numChars; } if (x >= layoutPtr->width) { /* - * If point lies off right side of the text layout, return - * the last char in the last chunk on this line. Without - * this, it might return the index of the first char that - * was located outside of the text layout. + * If point lies off right side of the text layout, return the + * last char in the last chunk on this line. Without this, it + * might return the index of the first char that was located + * outside of the text layout. */ x = INT_MAX; } /* - * Examine all chunks on this line to see which one contains - * the specified point. + * Examine all chunks on this line to see which one contains the + * specified point. */ lastPtr = chunkPtr; @@ -2376,7 +2363,7 @@ Tk_PointToChar(layout, x, y) /* * Point is to the right of all chars in all the chunks on this - * line. Return the index just past the last char in the last + * line. Return the index just past the last char in the last * chunk on this line. */ @@ -2392,8 +2379,8 @@ Tk_PointToChar(layout, x, y) } /* - * Point lies below any line in this text layout. Return the index - * just past the last char. + * Point lies below any line in this text layout. Return the index just + * past the last char. */ return (lastPtr->start + lastPtr->numChars) - layoutPtr->string; @@ -2404,29 +2391,28 @@ Tk_PointToChar(layout, x, y) * * Tk_CharBbox -- * - * Use the information in the Tk_TextLayout token to return the - * bounding box for the character specified by index. + * Use the information in the Tk_TextLayout token to return the bounding + * box for the character specified by index. * - * The width of the bounding box is the advance width of the - * character, and does not include and left- or right-bearing. - * Any character that extends partially outside of the - * text layout is considered to be truncated at the edge. Any - * character which is located completely outside of the text - * layout is considered to be zero-width and pegged against - * the edge. + * The width of the bounding box is the advance width of the character, + * and does not include and left- or right-bearing. Any character that + * extends partially outside of the text layout is considered to be + * truncated at the edge. Any character which is located completely + * outside of the text layout is considered to be zero-width and pegged + * against the edge. * * The height of the bounding box is the line height for this font, - * extending from the top of the ascent to the bottom of the - * descent. Information about the actual height of the individual - * letter is not available. + * extending from the top of the ascent to the bottom of the descent. + * Information about the actual height of the individual letter is not + * available. + * + * A text layout that contains no characters is considered to contain a + * single zero-width placeholder character. * - * A text layout that contains no characters is considered to - * contain a single zero-width placeholder character. - * * Results: - * The return value is 0 if the index did not specify a character - * in the text layout, or non-zero otherwise. In that case, - * *bbox is filled with the bounding box of the character. + * The return value is 0 if the index did not specify a character in the + * text layout, or non-zero otherwise. In that case, *bbox is filled with + * the bounding box of the character. * * Side effects: * None. @@ -2500,12 +2486,13 @@ Tk_CharBbox(layout, index, xPtr, yPtr, widthPtr, heightPtr) } /* - * Ensure that the bbox lies within the text layout. This forces all - * chars that extend off the right edge of the text layout to have - * truncated widths, and all chars that are completely off the right - * edge of the text layout to peg to the edge and have 0 width. + * Ensure that the bbox lies within the text layout. This forces all chars + * that extend off the right edge of the text layout to have truncated + * widths, and all chars that are completely off the right edge of the + * text layout to peg to the edge and have 0 width. */ - check: + + check: if (yPtr != NULL) { *yPtr = chunkPtr->y - fontPtr->fm.ascent; } @@ -2534,16 +2521,15 @@ Tk_CharBbox(layout, index, xPtr, yPtr, widthPtr, heightPtr) * * Tk_DistanceToTextLayout -- * - * Computes the distance in pixels from the given point to the - * given text layout. Non-displaying space characters that occur - * at the end of individual lines in the text layout are ignored - * for hit detection purposes. + * Computes the distance in pixels from the given point to the given text + * layout. Non-displaying space characters that occur at the end of + * individual lines in the text layout are ignored for hit detection + * purposes. * * Results: - * The return value is 0 if the point (x, y) is inside the text - * layout. If the point isn't inside the text layout then the - * return value is the distance in pixels from the point to the - * text item. + * The return value is 0 if the point (x, y) is inside the text layout. + * If the point isn't inside the text layout then the return value is the + * distance in pixels from the point to the text item. * * Side effects: * None. @@ -2568,14 +2554,14 @@ Tk_DistanceToTextLayout(layout, x, y) fontPtr = (TkFont *) layoutPtr->tkfont; ascent = fontPtr->fm.ascent; descent = fontPtr->fm.descent; - + minDist = 0; chunkPtr = layoutPtr->chunks; for (i = 0; i < layoutPtr->numChunks; i++) { if (chunkPtr->start[0] == '\n') { /* - * Newline characters are not counted when computing distance - * (but tab characters would still be considered). + * Newline characters are not counted when computing distance (but + * tab characters would still be considered). */ chunkPtr++; @@ -2619,15 +2605,15 @@ Tk_DistanceToTextLayout(layout, x, y) * * Tk_IntersectTextLayout -- * - * Determines whether a text layout lies entirely inside, - * entirely outside, or overlaps a given rectangle. Non-displaying - * space characters that occur at the end of individual lines in - * the text layout are ignored for intersection calculations. + * Determines whether a text layout lies entirely inside, entirely + * outside, or overlaps a given rectangle. Non-displaying space + * characters that occur at the end of individual lines in the text + * layout are ignored for intersection calculations. * * Results: - * The return value is -1 if the text layout is entirely outside of - * the rectangle, 0 if it overlaps, and 1 if it is entirely inside - * of the rectangle. + * The return value is -1 if the text layout is entirely outside of the + * rectangle, 0 if it overlaps, and 1 if it is entirely inside of the + * rectangle. * * Side effects: * None. @@ -2637,13 +2623,13 @@ Tk_DistanceToTextLayout(layout, x, y) int Tk_IntersectTextLayout(layout, x, y, width, height) - Tk_TextLayout layout; /* Layout information, from a previous call - * to Tk_ComputeTextLayout(). */ + Tk_TextLayout layout; /* Layout information, from a previous call to + * Tk_ComputeTextLayout(). */ int x, y; /* Upper-left hand corner, in pixels, of * rectangular area to compare with text - * layout. Coordinates are with respect to - * the upper-left hand corner of the text - * layout itself. */ + * layout. Coordinates are with respect to the + * upper-left hand corner of the text layout + * itself. */ int width, height; /* The width and height of the above * rectangular area, in pixels. */ { @@ -2655,11 +2641,11 @@ Tk_IntersectTextLayout(layout, x, y, width, height) /* * Scan the chunks one at a time, seeing whether each is entirely in, - * entirely out, or overlapping the rectangle. If an overlap is - * detected, return immediately; otherwise wait until all chunks have - * been processed and see if they were all inside or all outside. + * entirely out, or overlapping the rectangle. If an overlap is detected, + * return immediately; otherwise wait until all chunks have been processed + * and see if they were all inside or all outside. */ - + layoutPtr = (TextLayout *) layout; chunkPtr = layoutPtr->chunks; fontPtr = (TkFont *) layoutPtr->tkfont; @@ -2710,34 +2696,32 @@ Tk_IntersectTextLayout(layout, x, y, width, height) * * Tk_TextLayoutToPostscript -- * - * Outputs the contents of a text layout in Postscript format. - * The set of lines in the text layout will be rendered by the user - * supplied Postscript function. The function should be of the form: + * Outputs the contents of a text layout in Postscript format. The set of + * lines in the text layout will be rendered by the user supplied + * Postscript function. The function should be of the form: * * justify x y string function -- * * Justify is -1, 0, or 1, depending on whether the following string - * should be left, center, or right justified, x and y is the - * location for the origin of the string, string is the sequence - * of characters to be printed, and function is the name of the - * caller-provided function; the function should leave nothing - * on the stack. - * - * The meaning of the origin of the string (x and y) depends on - * the justification. For left justification, x is where the - * left edge of the string should appear. For center justification, - * x is where the center of the string should appear. And for right - * justification, x is where the right edge of the string should - * appear. This behavior is necessary because, for example, right - * justified text on the screen is justified with screen metrics. - * The same string needs to be justified with printer metrics on - * the printer to appear in the correct place with respect to other - * similarly justified strings. In all circumstances, y is the - * location of the baseline for the string. + * should be left, center, or right justified, x and y is the location + * for the origin of the string, string is the sequence of characters to + * be printed, and function is the name of the caller-provided function; + * the function should leave nothing on the stack. + * + * The meaning of the origin of the string (x and y) depends on the + * justification. For left justification, x is where the left edge of the + * string should appear. For center justification, x is where the center + * of the string should appear. And for right justification, x is where + * the right edge of the string should appear. This behavior is necessary + * because, for example, right justified text on the screen is justified + * with screen metrics. The same string needs to be justified with + * printer metrics on the printer to appear in the correct place with + * respect to other similarly justified strings. In all circumstances, y + * is the location of the baseline for the string. * * Results: - * The interp's result is modified to hold the Postscript code that - * will render the text layout. + * The interp's result is modified to hold the Postscript code that will + * render the text layout. * * Side effects: * None. @@ -2786,23 +2770,24 @@ Tk_TextLayoutToPostscript(interp, layout) p = chunkPtr->start; for (j = 0; j < chunkPtr->numDisplayChars; j++) { /* - * INTL: For now we just treat the characters as binary - * data and display the lower byte. Eventually this should - * be revised to handle international postscript fonts. + * INTL: For now we just treat the characters as binary data + * and display the lower byte. Eventually this should be + * revised to handle international postscript fonts. */ - last_p=p; - p +=(charsize= Tcl_UtfToUniChar(p,&ch)); - Tcl_UtfToExternal(interp,NULL,last_p,charsize,0,NULL,one_char,4, - NULL,&bytecount,NULL); - if (bytecount == 1) { + + last_p = p; + p += (charsize = Tcl_UtfToUniChar(p,&ch)); + Tcl_UtfToExternal(interp, NULL, last_p, charsize, 0, NULL, + one_char, 4, NULL, &bytecount, NULL); + if (bytecount == 1) { c = UCHAR(one_char[0]); /* c = UCHAR( ch & 0xFF) */; if ((c == '(') || (c == ')') || (c == '\\') || (c < 0x20) || (c >= UCHAR(0x7f))) { /* - * Tricky point: the "03" is necessary in the sprintf + * Tricky point: the "03" is necessary in the sprintf * below, so that a full three digits of octal are - * always generated. Without the "03", a number + * always generated. Without the "03", a number * following this sequence could be interpreted by * Postscript as part of this sequence. */ @@ -2813,20 +2798,24 @@ Tk_TextLayoutToPostscript(interp, layout) buf[used++] = c; } } else { - /* This character doesn't belong to system character set. - * So, we must use full glyph name */ + /* + * This character doesn't belong to system character set. + * So, we must use full glyph name. + */ sprintf(uindex,"%04X",ch); /* endianness? */ - if ((glyphname = Tcl_GetVar2( interp , "::tk::psglyphs",uindex,0))) { - if (used > 0 && buf [used-1] == '(') + if ((glyphname = Tcl_GetVar2(interp , "::tk::psglyphs",uindex,0))) { + if (used > 0 && buf [used-1] == '(') { --used; - else + } else { buf[used++] = ')'; + } buf[used++] = '/'; - while( (*glyphname) && (used < (MAXUSE+27))) + while ((*glyphname) && (used < (MAXUSE+27))) { buf[used++] = *glyphname++ ; + } buf[used++] = '('; } - + } if (used >= MAXUSE) { buf[used] = '\0'; @@ -2837,10 +2826,10 @@ Tk_TextLayoutToPostscript(interp, layout) } if (used >= MAXUSE) { /* - * If there are a whole bunch of returns or tabs in a row, - * then buf[] could get filled up. + * If there are a whole bunch of returns or tabs in a row, then + * buf[] could get filled up. */ - + buf[used] = '\0'; Tcl_AppendResult(interp, buf, (char *) NULL); used = 0; @@ -2863,15 +2852,14 @@ Tk_TextLayoutToPostscript(interp, layout) * initialized font attributes structure. * * Results: - * A standard Tcl return value. If TCL_ERROR is returned, an - * error message will be left in interp's result object. + * A standard Tcl return value. If TCL_ERROR is returned, an error + * message will be left in interp's result object. * * Side effects: * The fields of the font attributes structure get filled in with - * information from argc/argv. If an error occurs while parsing, - * the font attributes structure will contain all modifications - * specified in the command line options up to the point of the - * error. + * information from argc/argv. If an error occurs while parsing, the font + * attributes structure will contain all modifications specified in the + * command line options up to the point of the error. * *--------------------------------------------------------------------------- */ @@ -2882,14 +2870,14 @@ ConfigAttributesObj(interp, tkwin, objc, objv, faPtr) Tk_Window tkwin; /* For display on which font will be used. */ int objc; /* Number of elements in argv. */ Tcl_Obj *CONST objv[]; /* Command line options. */ - TkFontAttributes *faPtr; /* Font attributes structure whose fields - * are to be modified. Structure must already - * be properly initialized. */ + TkFontAttributes *faPtr; /* Font attributes structure whose fields are + * to be modified. Structure must already be + * properly initialized. */ { int i, n, index; Tcl_Obj *optionPtr, *valuePtr; char *value; - + for (i = 0; i < objc; i += 2) { optionPtr = objv[i]; valuePtr = objv[i + 1]; @@ -2900,10 +2888,9 @@ ConfigAttributesObj(interp, tkwin, objc, objv, faPtr) } if ((i+2 >= objc) && (objc & 1)) { /* - * This test occurs after Tcl_GetIndexFromObj() so that - * "font create xyz -xyz" will return the error message - * that "-xyz" is a bad option, rather than that the value - * for "-xyz" is missing. + * This test occurs after Tcl_GetIndexFromObj() so that "font + * create xyz -xyz" will return the error message that "-xyz" is a + * bad option, rather than that the value for "-xyz" is missing. */ Tcl_AppendResult(interp, "value for \"", @@ -2913,48 +2900,42 @@ ConfigAttributesObj(interp, tkwin, objc, objv, faPtr) } switch (index) { - case FONT_FAMILY: { - value = Tcl_GetString(valuePtr); - faPtr->family = Tk_GetUid(value); - break; - } - case FONT_SIZE: { - if (Tcl_GetIntFromObj(interp, valuePtr, &n) != TCL_OK) { - return TCL_ERROR; - } - faPtr->size = n; - break; + case FONT_FAMILY: + value = Tcl_GetString(valuePtr); + faPtr->family = Tk_GetUid(value); + break; + case FONT_SIZE: + if (Tcl_GetIntFromObj(interp, valuePtr, &n) != TCL_OK) { + return TCL_ERROR; } - case FONT_WEIGHT: { - n = TkFindStateNumObj(interp, optionPtr, weightMap, valuePtr); - if (n == TK_FW_UNKNOWN) { - return TCL_ERROR; - } - faPtr->weight = n; - break; + faPtr->size = n; + break; + case FONT_WEIGHT: + n = TkFindStateNumObj(interp, optionPtr, weightMap, valuePtr); + if (n == TK_FW_UNKNOWN) { + return TCL_ERROR; } - case FONT_SLANT: { - n = TkFindStateNumObj(interp, optionPtr, slantMap, valuePtr); - if (n == TK_FS_UNKNOWN) { - return TCL_ERROR; - } - faPtr->slant = n; - break; + faPtr->weight = n; + break; + case FONT_SLANT: + n = TkFindStateNumObj(interp, optionPtr, slantMap, valuePtr); + if (n == TK_FS_UNKNOWN) { + return TCL_ERROR; } - case FONT_UNDERLINE: { - if (Tcl_GetBooleanFromObj(interp, valuePtr, &n) != TCL_OK) { - return TCL_ERROR; - } - faPtr->underline = n; - break; + faPtr->slant = n; + break; + case FONT_UNDERLINE: + if (Tcl_GetBooleanFromObj(interp, valuePtr, &n) != TCL_OK) { + return TCL_ERROR; } - case FONT_OVERSTRIKE: { - if (Tcl_GetBooleanFromObj(interp, valuePtr, &n) != TCL_OK) { - return TCL_ERROR; - } - faPtr->overstrike = n; - break; + faPtr->underline = n; + break; + case FONT_OVERSTRIKE: + if (Tcl_GetBooleanFromObj(interp, valuePtr, &n) != TCL_OK) { + return TCL_ERROR; } + faPtr->overstrike = n; + break; } } return TCL_OK; @@ -2968,14 +2949,13 @@ ConfigAttributesObj(interp, tkwin, objc, objv, faPtr) * Return information about the font attributes as a Tcl list. * * Results: - * The return value is TCL_OK if the objPtr was non-NULL and - * specified a valid font attribute, TCL_ERROR otherwise. If TCL_OK - * is returned, the interp's result object is modified to hold a - * description of either the current value of a single option, or a - * list of all options and their current values for the given font - * attributes. If TCL_ERROR is returned, the interp's result is - * set to an error message describing that the objPtr did not refer - * to a valid option. + * The return value is TCL_OK if the objPtr was non-NULL and specified a + * valid font attribute, TCL_ERROR otherwise. If TCL_OK is returned, the + * interp's result object is modified to hold a description of either the + * current value of a single option, or a list of all options and their + * current values for the given font attributes. If TCL_ERROR is + * returned, the interp's result is set to an error message describing + * that the objPtr did not refer to a valid option. * * Side effects: * None. @@ -2985,12 +2965,12 @@ ConfigAttributesObj(interp, tkwin, objc, objv, faPtr) static int GetAttributeInfoObj(interp, faPtr, objPtr) - Tcl_Interp *interp; /* Interp to hold result. */ - CONST TkFontAttributes *faPtr; /* The font attributes to inspect. */ - Tcl_Obj *objPtr; /* If non-NULL, indicates the single - * option whose value is to be - * returned. Otherwise information is - * returned for all options. */ + Tcl_Interp *interp; /* Interp to hold result. */ + CONST TkFontAttributes *faPtr; + /* The font attributes to inspect. */ + Tcl_Obj *objPtr; /* If non-NULL, indicates the single option + * whose value is to be returned. Otherwise + * information is returned for all options. */ { int i, index, start, end; CONST char *str; @@ -3012,32 +2992,32 @@ GetAttributeInfoObj(interp, faPtr, objPtr) valuePtr = NULL; for (i = start; i < end; i++) { switch (i) { - case FONT_FAMILY: - str = faPtr->family; - valuePtr = Tcl_NewStringObj(str, ((str == NULL) ? 0 : -1)); - break; + case FONT_FAMILY: + str = faPtr->family; + valuePtr = Tcl_NewStringObj(str, ((str == NULL) ? 0 : -1)); + break; - case FONT_SIZE: - valuePtr = Tcl_NewIntObj(faPtr->size); - break; + case FONT_SIZE: + valuePtr = Tcl_NewIntObj(faPtr->size); + break; - case FONT_WEIGHT: - str = TkFindStateString(weightMap, faPtr->weight); - valuePtr = Tcl_NewStringObj(str, -1); - break; - - case FONT_SLANT: - str = TkFindStateString(slantMap, faPtr->slant); - valuePtr = Tcl_NewStringObj(str, -1); - break; + case FONT_WEIGHT: + str = TkFindStateString(weightMap, faPtr->weight); + valuePtr = Tcl_NewStringObj(str, -1); + break; - case FONT_UNDERLINE: - valuePtr = Tcl_NewBooleanObj(faPtr->underline); - break; + case FONT_SLANT: + str = TkFindStateString(slantMap, faPtr->slant); + valuePtr = Tcl_NewStringObj(str, -1); + break; - case FONT_OVERSTRIKE: - valuePtr = Tcl_NewBooleanObj(faPtr->overstrike); - break; + case FONT_UNDERLINE: + valuePtr = Tcl_NewBooleanObj(faPtr->underline); + break; + + case FONT_OVERSTRIKE: + valuePtr = Tcl_NewBooleanObj(faPtr->overstrike); + break; } if (objPtr != NULL) { Tcl_SetObjResult(interp, valuePtr); @@ -3055,8 +3035,8 @@ GetAttributeInfoObj(interp, faPtr, objPtr) * * ParseFontNameObj -- * - * Converts a object into a set of font attributes that can be used - * to construct a font. + * Converts a object into a set of font attributes that can be used to + * construct a font. * * The string rep of the object can be one of the following forms: * XLFD (see X documentation) @@ -3064,10 +3044,10 @@ GetAttributeInfoObj(interp, faPtr, objPtr) * "-option value [-option value ...]" * * Results: - * The return value is TCL_ERROR if the object was syntactically - * invalid. In that case an error message is left in interp's - * result object. Otherwise, fills the font attribute buffer with - * the values parsed from the string and returns TCL_OK; + * The return value is TCL_ERROR if the object was syntactically invalid. + * In that case an error message is left in interp's result object. + * Otherwise, fills the font attribute buffer with the values parsed from + * the string and returns TCL_OK; * * Side effects: * None. @@ -3077,12 +3057,12 @@ GetAttributeInfoObj(interp, faPtr, objPtr) static int ParseFontNameObj(interp, tkwin, objPtr, faPtr) - Tcl_Interp *interp; /* Interp for error return. Must not be + Tcl_Interp *interp; /* Interp for error return. Must not be * NULL. */ Tk_Window tkwin; /* For display on which font is used. */ Tcl_Obj *objPtr; /* Parseable font description object. */ TkFontAttributes *faPtr; /* Filled with attributes parsed from font - * name. Any attributes that were not + * name. Any attributes that were not * specified in font name are filled with * default values. */ { @@ -3090,7 +3070,7 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr) int objc, result, i, n; Tcl_Obj **objv; char *string; - + TkInitFontAttributes(faPtr); string = Tcl_GetString(objPtr); @@ -3099,7 +3079,7 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr) * This may be an XLFD or an "-option value" string. * * If the string begins with "-*" or a "-foundry-family-*" pattern, - * then consider it an XLFD. + * then consider it an XLFD. */ if (string[1] == '*') { @@ -3117,16 +3097,16 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr) return ConfigAttributesObj(interp, tkwin, objc, objv, faPtr); } - + if (*string == '*') { /* - * This is appears to be an XLFD. Under Unix, all valid XLFDs were - * already handled by TkpGetNativeFont. If we are here, either we - * have something that initially looks like an XLFD but isn't or we - * have encountered an XLFD on Windows or Mac. + * This is appears to be an XLFD. Under Unix, all valid XLFDs were + * already handled by TkpGetNativeFont. If we are here, either we have + * something that initially looks like an XLFD but isn't or we have + * encountered an XLFD on Windows or Mac. */ - xlfd: + xlfd: result = TkFontParseXLFD(string, faPtr, NULL); if (result == TCL_OK) { return TCL_OK; @@ -3134,8 +3114,8 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr) } /* - * Wasn't an XLFD or "-option value" string. Try it as a - * "font size style" list. + * Wasn't an XLFD or "-option value" string. Try it as a "font size style" + * list. */ if ((Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv) != TCL_OK) @@ -3198,9 +3178,8 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr) * * NewChunk -- * - * Helper function for Tk_ComputeTextLayout(). Encapsulates a - * measured set of characters in a chunk that can be quickly - * drawn. + * Helper function for Tk_ComputeTextLayout(). Encapsulates a measured + * set of characters in a chunk that can be quickly drawn. * * Results: * A pointer to the new chunk in the text layout. @@ -3208,13 +3187,13 @@ ParseFontNameObj(interp, tkwin, objPtr, faPtr) * Side effects: * The text layout is reallocated to hold more chunks as necessary. * - * Currently, Tk_ComputeTextLayout() stores contiguous ranges of - * "normal" characters in a chunk, along with individual tab - * and newline chars in their own chunks. All characters in the - * text layout are accounted for. + * Currently, Tk_ComputeTextLayout() stores contiguous ranges of "normal" + * characters in a chunk, along with individual tab and newline chars in + * their own chunks. All characters in the text layout are accounted for. * *--------------------------------------------------------------------------- */ + static LayoutChunk * NewChunk(layoutPtrPtr, maxPtr, start, numBytes, curX, newX, y) TextLayout **layoutPtrPtr; @@ -3229,7 +3208,7 @@ NewChunk(layoutPtrPtr, maxPtr, start, numBytes, curX, newX, y) LayoutChunk *chunkPtr; int maxChunks, numChars; size_t s; - + layoutPtr = *layoutPtrPtr; maxChunks = *maxPtr; if (layoutPtr->numChunks == maxChunks) { @@ -3264,8 +3243,8 @@ NewChunk(layoutPtrPtr, maxPtr, start, numBytes, curX, newX, y) * * Results: * Return value is TCL_ERROR if string was not a fully specified XLFD. - * Otherwise, fills font attribute buffer with the values parsed - * from the XLFD and returns TCL_OK. + * Otherwise, fills font attribute buffer with the values parsed from the + * XLFD and returns TCL_OK. * * Side effects: * None. @@ -3277,13 +3256,13 @@ int TkFontParseXLFD(string, faPtr, xaPtr) CONST char *string; /* Parseable font description string. */ TkFontAttributes *faPtr; /* Filled with attributes parsed from font - * name. Any attributes that were not + * name. Any attributes that were not * specified in font name are filled with * default values. */ TkXLFDAttributes *xaPtr; /* Filled with X-specific attributes parsed - * from font name. Any attributes that were + * from font name. Any attributes that were * not specified in font name are filled with - * default values. May be NULL if such + * default values. May be NULL if such * information is not desired. */ { char *src; @@ -3292,7 +3271,7 @@ TkFontParseXLFD(string, faPtr, xaPtr) char *field[XLFD_NUMFIELDS + 2]; Tcl_DString ds; TkXLFDAttributes xa; - + if (xaPtr == NULL) { xaPtr = &xa; } @@ -3331,13 +3310,13 @@ TkFontParseXLFD(string, faPtr, xaPtr) /* * An XLFD of the form -adobe-times-medium-r-*-12-*-* is pretty common, - * but it is (strictly) malformed, because the first * is eliding both - * the Setwidth and the Addstyle fields. If the Addstyle field is a - * number, then assume the above incorrect form was used and shift all - * the rest of the fields right by one, so the number gets interpreted - * as a pixelsize. This fix is so that we don't get a million reports - * that "it works under X (as a native font name), but gives a syntax - * error under Windows (as a parsed set of attributes)". + * but it is (strictly) malformed, because the first * is eliding both the + * Setwidth and the Addstyle fields. If the Addstyle field is a number, + * then assume the above incorrect form was used and shift all the rest of + * the fields right by one, so the number gets interpreted as a pixelsize. + * This fix is so that we don't get a million reports that "it works under + * X (as a native font name), but gives a syntax error under Windows (as a + * parsed set of attributes)". */ if ((i > XLFD_ADD_STYLE) && (FieldSpecified(field[XLFD_ADD_STYLE]))) { @@ -3387,8 +3366,8 @@ TkFontParseXLFD(string, faPtr, xaPtr) /* XLFD_ADD_STYLE ignored. */ /* - * Pointsize in tenths of a point, but treat it as tenths of a pixel - * for historical compatibility. + * Pointsize in tenths of a point, but treat it as tenths of a pixel for + * historical compatibility. */ faPtr->size = 12; @@ -3415,7 +3394,7 @@ TkFontParseXLFD(string, faPtr, xaPtr) } /* - * Pixel height of font. If specified, overrides pointsize. + * Pixel height of font. If specified, overrides pointsize. */ if (FieldSpecified(field[XLFD_PIXEL_SIZE])) { @@ -3425,9 +3404,9 @@ TkFontParseXLFD(string, faPtr, xaPtr) * * [ N1 N2 N3 N4 ] * - * where N1 is the pixel size, and where N2, N3, and N4 - * are some additional numbers that I don't know - * the purpose of, so I ignore them. + * where N1 is the pixel size, and where N2, N3, and N4 are some + * additional numbers that I don't know the purpose of, so I + * ignore them. */ faPtr->size = atoi(field[XLFD_PIXEL_SIZE] + 1); @@ -3461,12 +3440,12 @@ TkFontParseXLFD(string, faPtr, xaPtr) * * FieldSpecified -- * - * Helper function for TkParseXLFD(). Determines if a field in the - * XLFD was set to a non-null, non-don't-care value. + * Helper function for TkParseXLFD(). Determines if a field in the XLFD + * was set to a non-null, non-don't-care value. * * Results: - * The return value is 0 if the field in the XLFD was not set and - * should be ignored, non-zero otherwise. + * The return value is 0 if the field in the XLFD was not set and should + * be ignored, non-zero otherwise. * * Side effects: * None. @@ -3476,10 +3455,11 @@ TkFontParseXLFD(string, faPtr, xaPtr) static int FieldSpecified(field) - CONST char *field; /* The field of the XLFD to check. Strictly - * speaking, only when the string is "*" does it mean - * don't-care. However, an unspecified or question - * mark is also interpreted as don't-care. */ + CONST char *field; /* The field of the XLFD to check. Strictly + * speaking, only when the string is "*" does + * it mean don't-care. However, an unspecified + * or question mark is also interpreted as + * don't-care. */ { char ch; @@ -3506,7 +3486,7 @@ FieldSpecified(field) * *--------------------------------------------------------------------------- */ - + int TkFontGetPixels(tkwin, size) Tk_Window tkwin; /* For point->pixel conversion factor. */ @@ -3540,7 +3520,7 @@ TkFontGetPixels(tkwin, size) * *--------------------------------------------------------------------------- */ - + int TkFontGetPoints(tkwin, size) Tk_Window tkwin; /* For pixel->point conversion factor. */ @@ -3563,24 +3543,24 @@ TkFontGetPoints(tkwin, size) * * TkFontGetAliasList -- * - * Given a font name, find the list of all aliases for that font - * name. One of the names in this list will probably be the name - * that this platform expects when asking for the font. + * Given a font name, find the list of all aliases for that font name. + * One of the names in this list will probably be the name that this + * platform expects when asking for the font. * * Results: - * As above. The return value is NULL if the font name has no - * aliases. + + * As above. The return value is NULL if the font name has no aliases. * * Side effects: * None. * *------------------------------------------------------------------------- */ - + char ** TkFontGetAliasList(faceName) CONST char *faceName; /* Font name to test for aliases. */ -{ +{ int i, j; for (i = 0; fontAliases[i] != NULL; i++) { @@ -3598,9 +3578,8 @@ TkFontGetAliasList(faceName) * * TkFontGetFallbacks -- * - * Get the list of font fallbacks that the platform-specific code - * can use to try to find the closest matching font the name - * requested. + * Get the list of font fallbacks that the platform-specific code can use + * to try to find the closest matching font the name requested. * * Results: * As above. @@ -3610,7 +3589,7 @@ TkFontGetAliasList(faceName) * *------------------------------------------------------------------------- */ - + char *** TkFontGetFallbacks() { @@ -3635,7 +3614,7 @@ TkFontGetFallbacks() * *------------------------------------------------------------------------- */ - + char ** TkFontGetGlobalClass() { @@ -3647,8 +3626,8 @@ TkFontGetGlobalClass() * * TkFontGetSymbolClass -- * - * Get the list of fonts that are symbolic; used if the operating - * system cannot apriori identify symbolic fonts on its own. + * Get the list of fonts that are symbolic; used if the operating system + * cannot apriori identify symbolic fonts on its own. * * Results: * As above. @@ -3658,7 +3637,7 @@ TkFontGetGlobalClass() * *------------------------------------------------------------------------- */ - + char ** TkFontGetSymbolClass() { @@ -3670,13 +3649,12 @@ TkFontGetSymbolClass() * * TkDebugFont -- * - * This procedure returns debugging information about a font. + * This function returns debugging information about a font. * * Results: * The return value is a list with one sublist for each TkFont - * corresponding to "name". Each sublist has two elements that - * contain the resourceRefCount and objRefCount fields from the - * TkFont structure. + * corresponding to "name". Each sublist has two elements that contain + * the resourceRefCount and objRefCount fields from the TkFont structure. * * Side effects: * None. @@ -3686,8 +3664,8 @@ TkFontGetSymbolClass() Tcl_Obj * TkDebugFont(tkwin, name) - Tk_Window tkwin; /* The window in which the font will be - * used (not currently used). */ + Tk_Window tkwin; /* The window in which the font will be used + * (not currently used). */ char *name; /* Name of the desired color. */ { TkFont *fontPtr; @@ -3707,7 +3685,7 @@ TkDebugFont(tkwin, name) Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewIntObj(fontPtr->resourceRefCount)); Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewIntObj(fontPtr->objRefCount)); + Tcl_NewIntObj(fontPtr->objRefCount)); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } } @@ -3719,13 +3697,13 @@ TkDebugFont(tkwin, name) * * TkFontGetFirstTextLayout -- * - * This procedure returns the first chunk of a Tk_TextLayout, - * i.e. until the first font change on the first line (or the - * whole first line if there is no such font change). + * This function returns the first chunk of a Tk_TextLayout, i.e. until + * the first font change on the first line (or the whole first line if + * there is no such font change). * * Results: - * The return value is the byte length of the chunk, the chunk - * itself is copied into dst and its Tk_Font into font. + * The return value is the byte length of the chunk, the chunk itself is + * copied into dst and its Tk_Font into font. * * Side effects: * None. @@ -3735,21 +3713,20 @@ TkDebugFont(tkwin, name) int TkFontGetFirstTextLayout( - Tk_TextLayout layout, /* Layout information, from a previous call - * to Tk_ComputeTextLayout(). */ - Tk_Font * font, - char * dst) + Tk_TextLayout layout, /* Layout information, from a previous call to + * Tk_ComputeTextLayout(). */ + Tk_Font *font, + char *dst) { TextLayout *layoutPtr; LayoutChunk *chunkPtr; int numBytesInChunk; layoutPtr = (TextLayout *)layout; - if ((layoutPtr==NULL) - || (layoutPtr->numChunks==0) - || (layoutPtr->chunks->numDisplayChars <= 0)) { - dst[0] = '\0'; - return 0; + if ((layoutPtr==NULL) || (layoutPtr->numChunks==0) + || (layoutPtr->chunks->numDisplayChars <= 0)) { + dst[0] = '\0'; + return 0; } chunkPtr = layoutPtr->chunks; numBytesInChunk = chunkPtr->numBytes; @@ -3757,3 +3734,11 @@ TkFontGetFirstTextLayout( *font = layoutPtr->tkfont; return numBytesInChunk; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkFrame.c b/generic/tkFrame.c index f116f6c..4cdee7e 100644 --- a/generic/tkFrame.c +++ b/generic/tkFrame.c @@ -1,18 +1,17 @@ -/* +/* * tkFrame.c -- * * This module implements "frame", "labelframe" and "toplevel" widgets - * for the Tk toolkit. Frames are windows with a background color - * and possibly a 3-D effect, but not much else in the way of - * attributes. + * for the Tk toolkit. Frames are windows with a background color and + * possibly a 3-D effect, but not much else in the way of attributes. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkFrame.c,v 1.21 2005/08/09 07:39:17 das Exp $ + * RCS: @(#) $Id: tkFrame.c,v 1.22 2005/08/10 22:02:22 dkf Exp $ */ #include "default.h" @@ -33,29 +32,29 @@ enum FrameType { */ typedef struct { - Tk_Window tkwin; /* Window that embodies the frame. NULL - * means that the window has been destroyed - * but the data structures haven't yet been - * cleaned up. */ - Display *display; /* Display containing widget. Used, among + Tk_Window tkwin; /* Window that embodies the frame. NULL means + * that the window has been destroyed but the + * data structures haven't yet been cleaned + * up. */ + Display *display; /* Display containing widget. Used, among * other things, so that resources can be * freed even after tkwin has gone away. */ - Tcl_Interp *interp; /* Interpreter associated with widget. Used - * to delete widget command. */ + Tcl_Interp *interp; /* Interpreter associated with widget. Used to + * delete widget command. */ Tcl_Command widgetCmd; /* Token for frame's widget command. */ Tk_OptionTable optionTable; /* Table that defines configuration options * available for this widget. */ char *className; /* Class name for widget (from configuration - * option). Malloc-ed. */ + * option). Malloc-ed. */ enum FrameType type; /* Type of widget, such as TYPE_FRAME. */ - char *screenName; /* Screen on which widget is created. Non-null - * only for top-levels. Malloc-ed, may be + char *screenName; /* Screen on which widget is created. Non-null + * only for top-levels. Malloc-ed, may be * NULL. */ char *visualName; /* Textual description of visual for window, - * from -visual option. Malloc-ed, may be + * from -visual option. Malloc-ed, may be * NULL. */ char *colormapName; /* Textual description of colormap for window, - * from -colormap option. Malloc-ed, may be + * from -colormap option. Malloc-ed, may be * NULL. */ char *menuName; /* Textual description of menu to use for * menubar. Malloc-ed, may be NULL. */ @@ -63,32 +62,32 @@ typedef struct { * allocated for this window, which must be * freed when the window is deleted. */ Tk_3DBorder border; /* Structure used to draw 3-D border and - * background. NULL means no background - * or border. */ + * background. NULL means no background or + * border. */ int borderWidth; /* Width of 3-D border (if any). */ int relief; /* 3-d effect: TK_RELIEF_RAISED etc. */ - int highlightWidth; /* Width in pixels of highlight to draw - * around widget when it has the focus. - * 0 means don't draw a highlight. */ + int highlightWidth; /* Width in pixels of highlight to draw around + * widget when it has the focus. 0 means don't + * draw a highlight. */ XColor *highlightBgColorPtr; - /* Color for drawing traversal highlight - * area when highlight is off. */ + /* Color for drawing traversal highlight area + * when highlight is off. */ XColor *highlightColorPtr; /* Color for drawing traversal highlight. */ - int width; /* Width to request for window. <= 0 means + int width; /* Width to request for window. <= 0 means * don't request any size. */ - int height; /* Height to request for window. <= 0 means + int height; /* Height to request for window. <= 0 means * don't request any size. */ Tk_Cursor cursor; /* Current cursor for window, or None. */ - char *takeFocus; /* Value of -takefocus option; not used in - * the C code, but used by keyboard traversal - * scripts. Malloc'ed, but may be NULL. */ + 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 isContainer; /* 1 means this window is a container, 0 means * that it isn't. */ char *useThis; /* If the window is embedded, this points to * the name of the window in which it is - * embedded (malloc'ed). For non-embedded + * embedded (malloc'ed). For non-embedded * windows this is NULL. */ - int flags; /* Various flags; see below for + int flags; /* Various flags; see below for * definitions. */ Tcl_Obj *padXPtr; /* Value of -padx option: specifies how many * pixels of extra space to leave on left and @@ -101,46 +100,41 @@ typedef struct { } Frame; /* - * A data structure of the following type is kept for each labelframe - * widget managed by this file: + * A data structure of the following type is kept for each labelframe widget + * managed by this file: */ typedef struct { Frame frame; /* A pointer to the generic frame structure. * This must be the first element of the * Labelframe. */ - /* * Labelframe specific configuration settings. */ - Tcl_Obj *textPtr; /* Value of -text option: specifies text to * display in button. */ - Tk_Font tkfont; /* Value of -font option: specifies font - * to use for display text. */ + Tk_Font tkfont; /* Value of -font option: specifies font to + * use for display text. */ XColor *textColorPtr; /* Value of -fg option: specifies foreground * color in normal mode. */ int labelAnchor; /* Value of -labelanchor option: specifies * where to place the label. */ - Tk_Window labelWin; /* Value of -labelwidget option: Window to - * use as label for the frame. */ - + Tk_Window labelWin; /* Value of -labelwidget option: Window to use + * as label for the frame. */ /* * Labelframe specific fields for use with configuration settings above. */ - GC textGC; /* GC for drawing text in normal mode. */ Tk_TextLayout textLayout; /* Stored text layout information. */ XRectangle labelBox; /* The label's actual size and position. */ int labelReqWidth; /* The label's requested width. */ int labelReqHeight; /* The label's requested height. */ int labelTextX, labelTextY; /* Position of the text to be drawn. */ - } Labelframe; /* - * The following macros define how many extra pixels to leave - * around a label's text. + * The following macros define how many extra pixels to leave around a label's + * text. */ #define LABELSPACING 1 @@ -149,20 +143,19 @@ typedef struct { /* * Flag bits for frames: * - * REDRAW_PENDING: Non-zero means a DoWhenIdle handler - * has already been queued to redraw - * this window. - * GOT_FOCUS: Non-zero means this widget currently - * has the input focus. + * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has + * already been queued to redraw this window. + * GOT_FOCUS: Non-zero means this widget currently has the + * input focus. */ #define REDRAW_PENDING 1 #define GOT_FOCUS 4 /* - * The following enum is used to define a type for the -labelanchor option - * of the Labelframe widget. These values are used as indices into the - * string table below. + * The following enum is used to define a type for the -labelanchor option of + * the Labelframe widget. These values are used as indices into the string + * table below. */ enum labelanchor { @@ -178,8 +171,8 @@ static char *labelAnchorStrings[] = { }; /* - * Information used for parsing configuration options. There are - * one common table used by all and one table for each widget class. + * Information used for parsing configuration options. There are one common + * table used by all and one table for each widget class. */ static Tk_OptionSpec commonOptSpec[] = { @@ -233,7 +226,7 @@ static Tk_OptionSpec frameOptSpec[] = { (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), - 0, 0, 0}, + 0, 0, 0}, {TK_OPTION_STRING, "-class", "class", "Class", DEF_FRAME_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0}, @@ -249,7 +242,7 @@ static Tk_OptionSpec toplevelOptSpec[] = { (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), - 0, 0, 0}, + 0, 0, 0}, {TK_OPTION_STRING, "-class", "class", "Class", DEF_TOPLEVEL_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0}, @@ -274,7 +267,7 @@ static Tk_OptionSpec labelframeOptSpec[] = { (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", DEF_LABELFRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), - 0, 0, 0}, + 0, 0, 0}, {TK_OPTION_STRING, "-class", "class", "Class", DEF_LABELFRAME_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0}, @@ -286,10 +279,10 @@ static Tk_OptionSpec labelframeOptSpec[] = { DEF_LABELFRAME_FG, -1, Tk_Offset(Labelframe, textColorPtr), 0, 0, 0}, {TK_OPTION_STRING_TABLE, "-labelanchor", "labelAnchor", "LabelAnchor", DEF_LABELFRAME_LABELANCHOR, -1, Tk_Offset(Labelframe, labelAnchor), - 0, (ClientData) labelAnchorStrings, 0}, + 0, (ClientData) labelAnchorStrings, 0}, {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget", - (char *) NULL, -1, Tk_Offset(Labelframe, labelWin), - TK_OPTION_NULL_OK, 0, 0}, + (char *) NULL, -1, Tk_Offset(Labelframe, labelWin), + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", DEF_LABELFRAME_RELIEF, -1, Tk_Offset(Frame, relief), 0, 0, 0}, @@ -318,37 +311,36 @@ static Tk_OptionSpec *optionSpecs[] = { }; /* - * Forward declarations for procedures defined later in this file: + * Forward declarations for functions defined later in this file: */ -static void ComputeFrameGeometry _ANSI_ARGS_((Frame *framePtr)); -static int ConfigureFrame _ANSI_ARGS_((Tcl_Interp *interp, - Frame *framePtr, int objc, Tcl_Obj *CONST objv[])); -static int CreateFrame _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int objc, Tcl_Obj *CONST argv[], - enum FrameType type, char *appName)); -static void DestroyFrame _ANSI_ARGS_((char *memPtr)); -static void DestroyFramePartly _ANSI_ARGS_((Frame *framePtr)); -static void DisplayFrame _ANSI_ARGS_((ClientData clientData)); -static void FrameCmdDeletedProc _ANSI_ARGS_(( - ClientData clientData)); -static void FrameEventProc _ANSI_ARGS_((ClientData clientData, - XEvent *eventPtr)); -static void FrameLostSlaveProc _ANSI_ARGS_(( - ClientData clientData, Tk_Window tkwin)); -static void FrameRequestProc _ANSI_ARGS_((ClientData clientData, - Tk_Window tkwin)); -static void FrameStructureProc _ANSI_ARGS_(( - ClientData clientData, XEvent *eventPtr)); -static int FrameWidgetObjCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); -static void FrameWorldChanged _ANSI_ARGS_(( - ClientData instanceData)); -static void MapFrame _ANSI_ARGS_((ClientData clientData)); +static void ComputeFrameGeometry(Frame *framePtr); +static int ConfigureFrame(Tcl_Interp *interp, Frame *framePtr, + int objc, Tcl_Obj *CONST objv[]); +static int CreateFrame(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST argv[], + enum FrameType type, char *appName); +static void DestroyFrame(char *memPtr); +static void DestroyFramePartly(Frame *framePtr); +static void DisplayFrame(ClientData clientData); +static void FrameCmdDeletedProc(ClientData clientData); +static void FrameEventProc(ClientData clientData, + XEvent *eventPtr); +static void FrameLostSlaveProc(ClientData clientData, + Tk_Window tkwin); +static void FrameRequestProc(ClientData clientData, + Tk_Window tkwin); +static void FrameStructureProc(ClientData clientData, + XEvent *eventPtr); +static int FrameWidgetObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]); +static void FrameWorldChanged(ClientData instanceData); +static void MapFrame(ClientData clientData); /* - * The structure below defines frame class behavior by means of procedures - * that can be invoked from generic window code. + * The structure below defines frame class behavior by means of functions that + * can be invoked from generic window code. */ static Tk_ClassProcs frameClass = { @@ -362,9 +354,9 @@ static Tk_ClassProcs frameClass = { */ static Tk_GeomMgr frameGeomType = { - "labelframe", /* name */ - FrameRequestProc, /* requestProc */ - FrameLostSlaveProc /* lostSlaveProc */ + "labelframe", /* name */ + FrameRequestProc, /* requestProc */ + FrameLostSlaveProc /* lostSlaveProc */ }; @@ -373,16 +365,16 @@ static Tk_GeomMgr frameGeomType = { * * Tk_FrameObjCmd, Tk_ToplevelObjCmd, Tk_LabelframeObjCmd -- * - * These procedures are invoked to process the "frame", - * "toplevel" and "labelframe" Tcl commands. See the user - * documentation for details on what they do. + * These functions are invoked to process the "frame", "toplevel" and + * "labelframe" Tcl commands. See the user documentation for details on + * what they do. * * Results: * A standard Tcl result. * * Side effects: - * See the user documentation. These procedures are just wrappers; - * they call CreateFrame to do all of the real work. + * See the user documentation. These functions are just wrappers; they + * call CreateFrame to do all of the real work. * *-------------------------------------------------------------- */ @@ -425,10 +417,10 @@ Tk_LabelframeObjCmd(clientData, interp, objc, objv) * * TkCreateFrame -- * - * This procedure is the old command procedure for the "frame" - * and "toplevel" commands. Now it is used directly by Tk_Init to - * create a new main window. See the user documentation for the - * "frame" and "toplevel" commands for details on what it does. + * This function is the old command function for the "frame" and + * "toplevel" commands. Now it is used directly by Tk_Init to create a + * new main window. See the user documentation for the "frame" and + * "toplevel" commands for details on what it does. * * Results: * A standard Tcl result. @@ -449,11 +441,12 @@ TkCreateFrame(clientData, interp, argc, argv, toplevel, appName) * zero means create a frame. */ char *appName; /* Should only be non-NULL if there is no main * window associated with the interpreter. - * Gives the base name to use for the - * new application. */ + * Gives the base name to use for the new + * application. */ { int result, i; Tcl_Obj **objv = (Tcl_Obj **) ckalloc((argc+1) * sizeof(Tcl_Obj **)); + for (i=0; i<argc; i++) { objv[i] = Tcl_NewStringObj(argv[i], -1); Tcl_IncrRefCount(objv[i]); @@ -476,17 +469,16 @@ CreateFrame(clientData, interp, objc, objv, type, appName) Tcl_Obj *CONST objv[]; /* Argument objects. */ enum FrameType type; /* What widget type to create. */ char *appName; /* Should only be non-NULL if there are no - * Main window associated with the interpreter. - * Gives the base name to use for the - * new application. */ + * Main window associated with the + * interpreter. Gives the base name to use for + * the new application. */ { Tk_Window tkwin; Frame *framePtr; Tk_OptionTable optionTable; Tk_Window new; CONST char *className, *screenName, *visualName, *colormapName, *arg, *useOption; - int i, c, depth; - size_t length; + int i, c, length, depth; unsigned int mask; Colormap colormap; Visual *visual; @@ -497,58 +489,57 @@ CreateFrame(clientData, interp, objc, objv, type, appName) } /* - * Create the option table for this widget class. If it has already - * been created, the cached pointer will be returned. + * Create the option table for this widget class. If it has already been + * created, the cached pointer will be returned. */ optionTable = Tk_CreateOptionTable(interp, optionSpecs[type]); /* - * Pre-process the argument list. Scan through it to find any - * "-class", "-screen", "-visual", and "-colormap" options. These - * arguments need to be processed specially, before the window - * is configured using the usual Tk mechanisms. + * Pre-process the argument list. Scan through it to find any "-class", + * "-screen", "-visual", and "-colormap" options. These arguments need to + * be processed specially, before the window is configured using the usual + * Tk mechanisms. */ className = colormapName = screenName = visualName = useOption = NULL; colormap = None; for (i = 2; i < objc; i += 2) { - arg = Tcl_GetStringFromObj(objv[i], (int *) &length); + arg = Tcl_GetStringFromObj(objv[i], &length); if (length < 2) { continue; } c = arg[1]; - if ((c == 'c') && (strncmp(arg, "-class", length) == 0) - && (length >= 3)) { + if ((c == 'c') && (length >= 3) + && (strncmp(arg, "-class", (unsigned) length) == 0)) { className = Tcl_GetString(objv[i+1]); } else if ((c == 'c') - && (strncmp(arg, "-colormap", length) == 0)) { + && (strncmp(arg, "-colormap", (unsigned) length) == 0)) { colormapName = Tcl_GetString(objv[i+1]); } else if ((c == 's') && (type == TYPE_TOPLEVEL) - && (strncmp(arg, "-screen", length) == 0)) { + && (strncmp(arg, "-screen", (unsigned) length) == 0)) { screenName = Tcl_GetString(objv[i+1]); } else if ((c == 'u') && (type == TYPE_TOPLEVEL) - && (strncmp(arg, "-use", length) == 0)) { + && (strncmp(arg, "-use", (unsigned) length) == 0)) { useOption = Tcl_GetString(objv[i+1]); } else if ((c == 'v') - && (strncmp(arg, "-visual", length) == 0)) { + && (strncmp(arg, "-visual", (unsigned) length) == 0)) { visualName = Tcl_GetString(objv[i+1]); } } /* - * Create the window, and deal with the special options -use, - * -classname, -colormap, -screenname, and -visual. These options - * must be handle before calling ConfigureFrame below, and they must - * also be processed in a particular order, for the following - * reasons: - * 1. Must set the window's class before calling ConfigureFrame, - * so that unspecified options are looked up in the option - * database using the correct class. - * 2. Must set visual information before calling ConfigureFrame - * so that colors are allocated in a proper colormap. + * Create the window, and deal with the special options -use, -classname, + * -colormap, -screenname, and -visual. These options must be handle + * before calling ConfigureFrame below, and they must also be processed in + * a particular order, for the following reasons: + * 1. Must set the window's class before calling ConfigureFrame, so that + * unspecified options are looked up in the option database using the + * correct class. + * 2. Must set visual information before calling ConfigureFrame so that + * colors are allocated in a proper colormap. * 3. Must call TkpUseWindow before setting non-default visual - * information, since TkpUseWindow changes the defaults. + * information, since TkpUseWindow changes the defaults. */ if (screenName == NULL) { @@ -556,9 +547,8 @@ CreateFrame(clientData, interp, objc, objv, type, appName) } /* - * Main window associated with interpreter. - * If we're called by Tk_Init to create a - * new application, then this is NULL. + * Main window associated with interpreter. If we're called by Tk_Init to + * create a new application, then this is NULL. */ tkwin = Tk_MainWindow(interp); @@ -567,8 +557,8 @@ CreateFrame(clientData, interp, objc, objv, type, appName) screenName); } else if (appName == NULL) { /* - * This occurs when someone tried to create a frame/toplevel - * while we are being destroyed. Let an error be thrown. + * This occurs when someone tried to create a frame/toplevel while we + * are being destroyed. Let an error be thrown. */ Tcl_AppendResult(interp, "unable to create widget \"", @@ -576,7 +566,7 @@ CreateFrame(clientData, interp, objc, objv, type, appName) new = NULL; } else { /* - * We were called from Tk_Init; create a new application. + * We were called from Tk_Init; create a new application. */ new = TkCreateMainWindow(interp, screenName, appName); @@ -625,9 +615,9 @@ CreateFrame(clientData, interp, objc, objv, type, appName) } /* - * For top-level windows, provide an initial geometry request of - * 200x200, just so the window looks nicer on the screen if it - * doesn't request a size for itself. + * For top-level windows, provide an initial geometry request of 200x200, + * just so the window looks nicer on the screen if it doesn't request a + * size for itself. */ if (type == TYPE_TOPLEVEL) { @@ -635,9 +625,9 @@ CreateFrame(clientData, interp, objc, objv, type, appName) } /* - * Create the widget record, process configuration options, and - * create event handlers. Then fill in a few additional fields - * in the widget record from the special options. + * Create the widget record, process configuration options, and create + * event handlers. Then fill in a few additional fields in the widget + * record from the special options. */ if (type == TYPE_LABELFRAME) { @@ -668,11 +658,12 @@ CreateFrame(clientData, interp, objc, objv, type, appName) /* * Store backreference to frame widget in window structure. */ + Tk_SetClassProcs(new, &frameClass, (ClientData) framePtr); mask = ExposureMask | StructureNotifyMask | FocusChangeMask; if (type == TYPE_TOPLEVEL) { - mask |= ActivateMask; + mask |= ActivateMask; } Tk_CreateEventHandler(new, mask, FrameEventProc, (ClientData) framePtr); if ((Tk_InitOptions(interp, (char *) framePtr, optionTable, new) @@ -695,7 +686,7 @@ CreateFrame(clientData, interp, objc, objv, type, appName) Tcl_SetResult(interp, Tk_PathName(new), TCL_STATIC); return TCL_OK; - error: + error: if (new != NULL) { Tk_DestroyWindow(new); } @@ -707,9 +698,9 @@ CreateFrame(clientData, interp, objc, objv, type, appName) * * FrameWidgetObjCmd -- * - * This procedure is invoked to process the Tcl command - * that corresponds to a frame widget. See the user - * documentation for details on what it does. + * This function is invoked to process the Tcl command that corresponds + * to a frame widget. See the user documentation for details on what it + * does. * * Results: * A standard Tcl result. @@ -735,8 +726,7 @@ FrameWidgetObjCmd(clientData, interp, objc, objv) }; register Frame *framePtr = (Frame *) clientData; int result = TCL_OK, index; - size_t length; - int c, i; + int c, i, length; Tcl_Obj *objPtr; if (objc < 2) { @@ -749,23 +739,22 @@ FrameWidgetObjCmd(clientData, interp, objc, objv) } Tcl_Preserve((ClientData) framePtr); switch ((enum options) index) { - case FRAME_CGET: { + case FRAME_CGET: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); result = TCL_ERROR; goto done; } - objPtr = Tk_GetOptionValue(interp, (char *) framePtr, + objPtr = Tk_GetOptionValue(interp, (char *) framePtr, framePtr->optionTable, objv[2], framePtr->tkwin); - if (objPtr == NULL) { + if (objPtr == NULL) { result = TCL_ERROR; goto done; - } else { + } else { Tcl_SetObjResult(interp, objPtr); - } + } break; - } - case FRAME_CONFIGURE: { + case FRAME_CONFIGURE: if (objc <= 3) { objPtr = Tk_GetOptionInfo(interp, (char *) framePtr, framePtr->optionTable, @@ -779,33 +768,32 @@ FrameWidgetObjCmd(clientData, interp, objc, objv) } } else { /* - * Don't allow the options -class, -colormap, -container, - * -newcmap, -screen, -use, or -visual to be changed. + * Don't allow the options -class, -colormap, -container, -screen, + * -use, or -visual to be changed. */ for (i = 2; i < objc; i++) { - char *arg = Tcl_GetStringFromObj(objv[i], (int *) &length); + char *arg = Tcl_GetStringFromObj(objv[i], &length); if (length < 2) { continue; } c = arg[1]; - if (((c == 'c') && (strncmp(arg, "-class", length) == 0) - && (length >= 2)) - || ((c == 'c') - && (strncmp(arg, "-colormap", length) == 0) - && (length >= 3)) - || ((c == 'c') - && (strncmp(arg, "-container", length) == 0) - && (length >= 3)) - || ((c == 's') && (framePtr->type == TYPE_TOPLEVEL) - && (strncmp(arg, "-screen", length) == 0)) - || ((c == 'u') && (framePtr->type == TYPE_TOPLEVEL) - && (strncmp(arg, "-use", length) == 0)) - || ((c == 'v') - && (strncmp(arg, "-visual", length) == 0))) { - if(c == 'u') { - CONST char*string = Tcl_GetString(objv[i+1]); - if(TCL_OK != TkpUseWindow(interp, framePtr->tkwin, string)) { + if (((c == 'c') && (length >= 2) + && (strncmp(arg, "-class", (unsigned)length) == 0)) + || ((c == 'c') && (length >= 3) + && (strncmp(arg, "-colormap", (unsigned)length) == 0)) + || ((c == 'c') && (length >= 3) + && (strncmp(arg, "-container", (unsigned)length) == 0)) + || ((c == 's') && (framePtr->type == TYPE_TOPLEVEL) + && (strncmp(arg, "-screen", (unsigned)length) == 0)) + || ((c == 'u') && (framePtr->type == TYPE_TOPLEVEL) + && (strncmp(arg, "-use", (unsigned)length) == 0)) + || ((c == 'v') + && (strncmp(arg, "-visual", (unsigned)length) == 0))) { + if (c == 'u') { + CONST char *string = Tcl_GetString(objv[i+1]); + if (TkpUseWindow(interp, framePtr->tkwin, + string) != TCL_OK) { result = TCL_ERROR; goto done; } @@ -820,10 +808,9 @@ FrameWidgetObjCmd(clientData, interp, objc, objv) result = ConfigureFrame(interp, framePtr, objc-2, objv+2); } break; - } } - done: + done: Tcl_Release((ClientData) framePtr); return result; } @@ -833,9 +820,9 @@ FrameWidgetObjCmd(clientData, interp, objc, objv) * * DestroyFrame -- * - * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release - * to clean up the internal structure of a frame at a safe time - * (when no-one is using it anymore). + * This function is invoked by Tcl_EventuallyFree or Tcl_Release to clean + * up the internal structure of a frame at a safe time (when no-one is + * using it anymore). * * Results: * None. @@ -870,10 +857,9 @@ DestroyFrame(memPtr) * * DestroyFramePartly -- * - * This procedure is invoked to clean up everything that needs - * tkwin to be defined when deleted. During the destruction - * process tkwin is always set to NULL and this procedure must - * be called before that happens. + * This function is invoked to clean up everything that needs tkwin to be + * defined when deleted. During the destruction process tkwin is always + * set to NULL and this function must be called before that happens. * * Results: * None. @@ -903,7 +889,7 @@ DestroyFramePartly(framePtr) } Tk_FreeConfigOptions((char *) framePtr, framePtr->optionTable, - framePtr->tkwin); + framePtr->tkwin); } /* @@ -911,18 +897,17 @@ DestroyFramePartly(framePtr) * * ConfigureFrame -- * - * This procedure is called to process an objv/objc list, plus - * the Tk option database, in order to configure (or - * reconfigure) a frame widget. + * This function is called to process an objv/objc list, plus the Tk + * option database, in order to configure (or reconfigure) a frame + * widget. * * Results: - * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then the interp's result contains an error message. + * The return value is a standard Tcl result. If TCL_ERROR is returned, + * then the interp's result contains an error message. * * Side effects: - * Configuration information, such as text string, colors, font, - * etc. get set for framePtr; old resources get freed, if there - * were any. + * Configuration information, such as text string, colors, font, etc. get + * set for framePtr; old resources get freed, if there were any. * *---------------------------------------------------------------------- */ @@ -930,8 +915,8 @@ DestroyFramePartly(framePtr) static int ConfigureFrame(interp, framePtr, objc, objv) Tcl_Interp *interp; /* Used for error reporting. */ - register Frame *framePtr; /* Information about widget; may or may - * not already have values for some fields. */ + register Frame *framePtr; /* Information about widget; may or may not + * already have values for some fields. */ int objc; /* Number of valid entries in objv. */ Tcl_Obj *CONST objv[]; /* Arguments. */ { @@ -943,7 +928,7 @@ ConfigureFrame(interp, framePtr, objc, objv) /* * Need the old menubar name for the menu code to delete it. */ - + if (framePtr->menuName == NULL) { oldMenuName = NULL; } else { @@ -998,8 +983,8 @@ ConfigureFrame(interp, framePtr, objc, objv) } /* - * If a -labelwidget is specified, check that it is valid and set - * up geometry management for it. + * If a -labelwidget is specified, check that it is valid and set up + * geometry management for it. */ if (framePtr->type == TYPE_LABELFRAME) { @@ -1016,10 +1001,9 @@ ConfigureFrame(interp, framePtr, objc, objv) Tk_Window ancestor, parent, sibling = NULL; /* - * Make sure that the frame is either the parent of the - * window used as label or a descendant of that - * parent. Also, don't allow a top-level window to be - * managed inside the frame. + * Make sure that the frame is either the parent of the window + * used as label or a descendant of that parent. Also, don't + * allow a top-level window to be managed inside the frame. */ parent = Tk_Parent(labelframePtr->labelWin); @@ -1051,9 +1035,8 @@ ConfigureFrame(interp, framePtr, objc, objv) (ClientData) framePtr); /* - * If the frame is not parent to the label, make - * sure the label is above its sibling in the stacking - * order. + * If the frame is not parent to the label, make sure the + * label is above its sibling in the stacking order. */ if (sibling != NULL) { @@ -1073,19 +1056,19 @@ ConfigureFrame(interp, framePtr, objc, objv) * * FrameWorldChanged -- * - * This procedure is called when the world has changed in some - * way and the widget needs to recompute all its graphics contexts - * and determine its new geometry. + * This function is called when the world has changed in some way and the + * widget needs to recompute all its graphics contexts and determine its + * new geometry. * * Results: - * None. + * None. * * Side effects: - * Frame will be relayed out and redisplayed. + * Frame will be relayed out and redisplayed. * *--------------------------------------------------------------------------- */ - + static void FrameWorldChanged(instanceData) ClientData instanceData; /* Information about widget. */ @@ -1107,8 +1090,8 @@ FrameWorldChanged(instanceData) if (framePtr->type == TYPE_LABELFRAME) { /* - * The textGC is needed even in the labelWin case, so it's - * always created for a labelframe. + * The textGC is needed even in the labelWin case, so it's always + * created for a labelframe. */ gcValues.font = Tk_FontId(labelframePtr->tkfont); @@ -1124,7 +1107,7 @@ FrameWorldChanged(instanceData) /* * Calculate label size. */ - + labelframePtr->labelReqWidth = labelframePtr->labelReqHeight = 0; if (anyTextLabel) { @@ -1140,13 +1123,13 @@ FrameWorldChanged(instanceData) labelframePtr->labelReqHeight = Tk_ReqHeight(labelframePtr->labelWin); } - /* - * Make sure label size is at least as big as the border. - * This simplifies later calculations and gives a better - * appearance with thick borders. + /* + * Make sure label size is at least as big as the border. This + * simplifies later calculations and gives a better appearance with + * thick borders. */ - - if ((labelframePtr->labelAnchor >= LABELANCHOR_N) && + + if ((labelframePtr->labelAnchor >= LABELANCHOR_N) && (labelframePtr->labelAnchor <= LABELANCHOR_SW)) { if (labelframePtr->labelReqHeight < framePtr->borderWidth) { labelframePtr->labelReqHeight = framePtr->borderWidth; @@ -1162,34 +1145,34 @@ FrameWorldChanged(instanceData) * Calculate individual border widths. */ - bWidthBottom = bWidthTop = bWidthRight = bWidthLeft = - framePtr->borderWidth + framePtr->highlightWidth; + bWidthBottom = bWidthTop = bWidthRight = bWidthLeft = + framePtr->borderWidth + framePtr->highlightWidth; bWidthLeft += framePtr->padX; bWidthRight += framePtr->padX; bWidthTop += framePtr->padY; bWidthBottom += framePtr->padY; - + if (anyTextLabel || anyWindowLabel) { switch (labelframePtr->labelAnchor) { - case LABELANCHOR_E: - case LABELANCHOR_EN: - case LABELANCHOR_ES: + case LABELANCHOR_E: + case LABELANCHOR_EN: + case LABELANCHOR_ES: bWidthRight += labelframePtr->labelReqWidth - framePtr->borderWidth; break; - case LABELANCHOR_N: - case LABELANCHOR_NE: - case LABELANCHOR_NW: + case LABELANCHOR_N: + case LABELANCHOR_NE: + case LABELANCHOR_NW: bWidthTop += labelframePtr->labelReqHeight - framePtr->borderWidth; break; - case LABELANCHOR_S: - case LABELANCHOR_SE: - case LABELANCHOR_SW: + case LABELANCHOR_S: + case LABELANCHOR_SE: + case LABELANCHOR_SW: bWidthBottom += labelframePtr->labelReqHeight - framePtr->borderWidth; break; - default: + default: bWidthLeft += labelframePtr->labelReqWidth - framePtr->borderWidth; break; } @@ -1208,11 +1191,12 @@ FrameWorldChanged(instanceData) int minwidth = labelframePtr->labelReqWidth; int minheight = labelframePtr->labelReqHeight; int padding = framePtr->highlightWidth; + if (framePtr->borderWidth > 0) { padding += framePtr->borderWidth + LABELMARGIN; } padding *= 2; - if ((labelframePtr->labelAnchor >= LABELANCHOR_N) && + if ((labelframePtr->labelAnchor >= LABELANCHOR_N) && (labelframePtr->labelAnchor <= LABELANCHOR_SW)) { minwidth += padding; minheight += framePtr->borderWidth + framePtr->highlightWidth; @@ -1240,9 +1224,9 @@ FrameWorldChanged(instanceData) * * ComputeFrameGeometry -- * - * This procedure is called to compute various geometrical - * information for a frame, such as where various things get - * displayed. It's called when the window is reconfigured. + * This function is called to compute various geometrical information for + * a frame, such as where various things get displayed. It's called when + * the window is reconfigured. * * Results: * None. @@ -1267,12 +1251,13 @@ ComputeFrameGeometry(framePtr) */ if (framePtr->type != TYPE_LABELFRAME) return; - if ((labelframePtr->textPtr == NULL) && - (labelframePtr->labelWin == NULL)) return; + if (labelframePtr->textPtr == NULL && labelframePtr->labelWin == NULL) { + return; + } tkwin = framePtr->tkwin; - /* + /* * Calculate the available size for the label */ @@ -1281,15 +1266,15 @@ ComputeFrameGeometry(framePtr) padding = framePtr->highlightWidth; if (framePtr->borderWidth > 0) { - padding += framePtr->borderWidth + LABELMARGIN; + padding += framePtr->borderWidth + LABELMARGIN; } padding *= 2; maxHeight = Tk_Height(tkwin); maxWidth = Tk_Width(tkwin); - if ((labelframePtr->labelAnchor >= LABELANCHOR_N) && - (labelframePtr->labelAnchor <= LABELANCHOR_SW)) { + if ((labelframePtr->labelAnchor >= LABELANCHOR_N) && + (labelframePtr->labelAnchor <= LABELANCHOR_SW)) { maxWidth -= padding; if (maxWidth < 1) maxWidth = 1; } else { @@ -1304,9 +1289,9 @@ ComputeFrameGeometry(framePtr) } /* - * Calculate label and text position. - * The text's position is based on the requested size (= the text's - * real size) to get proper alignment if the text does not fit. + * Calculate label and text position. The text's position is based on the + * requested size (= the text's real size) to get proper alignment if the + * text does not fit. */ otherWidth = Tk_Width(tkwin) - labelframePtr->labelBox.width; @@ -1316,64 +1301,64 @@ ComputeFrameGeometry(framePtr) padding = framePtr->highlightWidth; switch (labelframePtr->labelAnchor) { - case LABELANCHOR_E: - case LABELANCHOR_EN: - case LABELANCHOR_ES: - labelframePtr->labelTextX = otherWidthT - padding; - labelframePtr->labelBox.x = otherWidth - padding; - break; - case LABELANCHOR_N: - case LABELANCHOR_NE: - case LABELANCHOR_NW: - labelframePtr->labelTextY = padding; - labelframePtr->labelBox.y = padding; - break; - case LABELANCHOR_S: - case LABELANCHOR_SE: - case LABELANCHOR_SW: - labelframePtr->labelTextY = otherHeightT - padding; - labelframePtr->labelBox.y = otherHeight - padding; - break; - default: - labelframePtr->labelTextX = padding; - labelframePtr->labelBox.x = padding; - break; + case LABELANCHOR_E: + case LABELANCHOR_EN: + case LABELANCHOR_ES: + labelframePtr->labelTextX = otherWidthT - padding; + labelframePtr->labelBox.x = otherWidth - padding; + break; + case LABELANCHOR_N: + case LABELANCHOR_NE: + case LABELANCHOR_NW: + labelframePtr->labelTextY = padding; + labelframePtr->labelBox.y = padding; + break; + case LABELANCHOR_S: + case LABELANCHOR_SE: + case LABELANCHOR_SW: + labelframePtr->labelTextY = otherHeightT - padding; + labelframePtr->labelBox.y = otherHeight - padding; + break; + default: + labelframePtr->labelTextX = padding; + labelframePtr->labelBox.x = padding; + break; } if (framePtr->borderWidth > 0) { - padding += framePtr->borderWidth + LABELMARGIN; + padding += framePtr->borderWidth + LABELMARGIN; } switch (labelframePtr->labelAnchor) { - case LABELANCHOR_NW: - case LABELANCHOR_SW: - labelframePtr->labelTextX = padding; - labelframePtr->labelBox.x = padding; - break; - case LABELANCHOR_N: - case LABELANCHOR_S: - labelframePtr->labelTextX = otherWidthT / 2; - labelframePtr->labelBox.x = otherWidth / 2; - break; - case LABELANCHOR_NE: - case LABELANCHOR_SE: - labelframePtr->labelTextX = otherWidthT - padding; - labelframePtr->labelBox.x = otherWidth - padding; - break; - case LABELANCHOR_EN: - case LABELANCHOR_WN: - labelframePtr->labelTextY = padding; - labelframePtr->labelBox.y = padding; - break; - case LABELANCHOR_E: - case LABELANCHOR_W: - labelframePtr->labelTextY = otherHeightT / 2; - labelframePtr->labelBox.y = otherHeight / 2; - break; - default: + case LABELANCHOR_NW: + case LABELANCHOR_SW: + labelframePtr->labelTextX = padding; + labelframePtr->labelBox.x = padding; + break; + case LABELANCHOR_N: + case LABELANCHOR_S: + labelframePtr->labelTextX = otherWidthT / 2; + labelframePtr->labelBox.x = otherWidth / 2; + break; + case LABELANCHOR_NE: + case LABELANCHOR_SE: + labelframePtr->labelTextX = otherWidthT - padding; + labelframePtr->labelBox.x = otherWidth - padding; + break; + case LABELANCHOR_EN: + case LABELANCHOR_WN: + labelframePtr->labelTextY = padding; + labelframePtr->labelBox.y = padding; + break; + case LABELANCHOR_E: + case LABELANCHOR_W: + labelframePtr->labelTextY = otherHeightT / 2; + labelframePtr->labelBox.y = otherHeight / 2; + break; + default: labelframePtr->labelTextY = otherHeightT - padding; labelframePtr->labelBox.y = otherHeight - padding; - break; + break; } } @@ -1382,14 +1367,13 @@ ComputeFrameGeometry(framePtr) * * DisplayFrame -- * - * This procedure is invoked to display a frame widget. + * This function is invoked to display a frame widget. * * Results: * None. * * Side effects: - * Commands are output to X to display the frame in its - * current mode. + * Commands are output to X to display the frame in its current mode. * *---------------------------------------------------------------------- */ @@ -1416,8 +1400,8 @@ DisplayFrame(clientData) hlWidth = framePtr->highlightWidth; if (hlWidth != 0) { - GC fgGC, bgGC; - + GC fgGC, bgGC; + bgGC = Tk_GCForColor(framePtr->highlightBgColorPtr, Tk_WindowId(tkwin)); if (framePtr->flags & GOT_FOCUS) { @@ -1439,11 +1423,11 @@ DisplayFrame(clientData) if (framePtr->type != TYPE_LABELFRAME) { /* - * Pass to platform specific draw function. In general, it just - * draws a simple rectangle, but it may "theme" the background. + * Pass to platform specific draw function. In general, it just draws + * a simple rectangle, but it may "theme" the background. */ - noLabel: + noLabel: TkpDrawFrame(tkwin, framePtr->border, hlWidth, framePtr->borderWidth, framePtr->relief); } else { @@ -1455,16 +1439,16 @@ DisplayFrame(clientData) } /* - * In order to avoid screen flashes, this procedure redraws the - * frame into off-screen memory, then copies it back on-screen - * in a single operation. This means there's no point in time - * where the on-screen image has been cleared. + * In order to avoid screen flashes, this function redraws the frame + * into off-screen memory, then copies it back on-screen in a single + * operation. This means there's no point in time where the on-screen + * image has been cleared. */ pixmap = Tk_GetPixmap(framePtr->display, Tk_WindowId(tkwin), Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin)); - - /* + + /* * Clear the pixmap. */ @@ -1480,61 +1464,56 @@ DisplayFrame(clientData) bdY2 = Tk_Height(tkwin) - hlWidth; switch (labelframePtr->labelAnchor) { - case LABELANCHOR_E: - case LABELANCHOR_EN: - case LABELANCHOR_ES: - bdX2 -= (labelframePtr->labelBox.width - framePtr->borderWidth) - / 2; + case LABELANCHOR_E: + case LABELANCHOR_EN: + case LABELANCHOR_ES: + bdX2 -= (labelframePtr->labelBox.width-framePtr->borderWidth) / 2; break; - case LABELANCHOR_N: - case LABELANCHOR_NE: - case LABELANCHOR_NW: - /* - * Since the glyphs of the text tend to be in the lower part - * we favor a lower border position by rounding up. + case LABELANCHOR_N: + case LABELANCHOR_NE: + case LABELANCHOR_NW: + /* + * Since the glyphs of the text tend to be in the lower part we + * favor a lower border position by rounding up. */ - bdY1 += (labelframePtr->labelBox.height - framePtr->borderWidth +1) - / 2; + bdY1 += (labelframePtr->labelBox.height-framePtr->borderWidth+1)/2; break; - case LABELANCHOR_S: - case LABELANCHOR_SE: - case LABELANCHOR_SW: - bdY2 -= (labelframePtr->labelBox.height - framePtr->borderWidth) - / 2; + case LABELANCHOR_S: + case LABELANCHOR_SE: + case LABELANCHOR_SW: + bdY2 -= (labelframePtr->labelBox.height-framePtr->borderWidth) / 2; break; - default: - bdX1 += (labelframePtr->labelBox.width - framePtr->borderWidth) - / 2; + default: + bdX1 += (labelframePtr->labelBox.width-framePtr->borderWidth) / 2; break; } - /* - * Draw border - */ + /* + * Draw border + */ Tk_Draw3DRectangle(tkwin, pixmap, framePtr->border, bdX1, bdY1, bdX2 - bdX1, bdY2 - bdY1, framePtr->borderWidth, framePtr->relief); - if (labelframePtr->labelWin == NULL) { - /* - * Clear behind the label - */ - - Tk_Fill3DRectangle(tkwin, pixmap, - framePtr->border, labelframePtr->labelBox.x, - labelframePtr->labelBox.y, labelframePtr->labelBox.width, - labelframePtr->labelBox.height, 0, TK_RELIEF_FLAT); - - /* - * Draw label. - * If there is not room for the entire label, use clipping to - * get a nice appearance. - */ - + if (labelframePtr->labelWin == NULL) { + /* + * Clear behind the label + */ + + Tk_Fill3DRectangle(tkwin, pixmap, + framePtr->border, labelframePtr->labelBox.x, + labelframePtr->labelBox.y, labelframePtr->labelBox.width, + labelframePtr->labelBox.height, 0, TK_RELIEF_FLAT); + + /* + * Draw label. If there is not room for the entire label, use + * clipping to get a nice appearance. + */ + if ((labelframePtr->labelBox.width < labelframePtr->labelReqWidth) - || (labelframePtr->labelBox.height < + || (labelframePtr->labelBox.height < labelframePtr->labelReqHeight)) { clipRegion = TkCreateRegion(); TkUnionRectWithRegion(&labelframePtr->labelBox, clipRegion, @@ -1543,37 +1522,37 @@ DisplayFrame(clientData) clipRegion); } - Tk_DrawTextLayout(framePtr->display, pixmap, - labelframePtr->textGC, labelframePtr->textLayout, - labelframePtr->labelTextX + LABELSPACING, - labelframePtr->labelTextY + LABELSPACING, 0, -1); + Tk_DrawTextLayout(framePtr->display, pixmap, + labelframePtr->textGC, labelframePtr->textLayout, + labelframePtr->labelTextX + LABELSPACING, + labelframePtr->labelTextY + LABELSPACING, 0, -1); if (clipRegion != NULL) { XSetClipMask(framePtr->display, labelframePtr->textGC, None); TkDestroyRegion(clipRegion); } - } else { + } else { /* * Reposition and map the window (but in different ways depending * on whether the frame is the window's parent). */ - + if (framePtr->tkwin == Tk_Parent(labelframePtr->labelWin)) { if ((labelframePtr->labelBox.x != Tk_X(labelframePtr->labelWin)) || (labelframePtr->labelBox.y != Tk_Y(labelframePtr->labelWin)) - || (labelframePtr->labelBox.width != + || (labelframePtr->labelBox.width != Tk_Width(labelframePtr->labelWin)) - || (labelframePtr->labelBox.height != + || (labelframePtr->labelBox.height != Tk_Height(labelframePtr->labelWin))) { Tk_MoveResizeWindow(labelframePtr->labelWin, - labelframePtr->labelBox.x, labelframePtr->labelBox.y, + labelframePtr->labelBox.x, labelframePtr->labelBox.y, labelframePtr->labelBox.width, labelframePtr->labelBox.height); } Tk_MapWindow(labelframePtr->labelWin); } else { - Tk_MaintainGeometry(labelframePtr->labelWin, framePtr->tkwin, + Tk_MaintainGeometry(labelframePtr->labelWin, framePtr->tkwin, labelframePtr->labelBox.x, labelframePtr->labelBox.y, labelframePtr->labelBox.width, labelframePtr->labelBox.height); @@ -1582,7 +1561,7 @@ DisplayFrame(clientData) /* - * Everything's been redisplayed; now copy the pixmap onto the screen + * Everything's been redisplayed; now copy the pixmap onto the screen * and free up the pixmap. */ @@ -1601,16 +1580,16 @@ DisplayFrame(clientData) * * FrameEventProc -- * - * This procedure is invoked by the Tk dispatcher on - * structure changes to a frame. For frames with 3D - * borders, this procedure is also invoked for exposures. + * This function is invoked by the Tk dispatcher on structure changes to + * a frame. For frames with 3D borders, this function is also invoked for + * exposures. * * Results: * None. * * Side effects: - * When the window gets deleted, internal structures get - * cleaned up. When it gets exposed, it is redisplayed. + * When the window gets deleted, internal structures get cleaned up. + * When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */ @@ -1635,15 +1614,14 @@ FrameEventProc(clientData, eventPtr) framePtr->menuName = NULL; } if (framePtr->tkwin != NULL) { - /* - * If this window is a container, then this event could be - * coming from the embedded application, in which case - * Tk_DestroyWindow hasn't been called yet. When Tk_DestroyWindow - * is called later, then another destroy event will be generated. - * We need to be sure we ignore the second event, since the frame - * could be gone by then. To do so, delete the event handler - * explicitly (normally it's done implicitly by Tk_DestroyWindow). + * If this window is a container, then this event could be coming + * from the embedded application, in which case Tk_DestroyWindow + * hasn't been called yet. When Tk_DestroyWindow is called later, + * then another destroy event will be generated. We need to be + * sure we ignore the second event, since the frame could be gone + * by then. To do so, delete the event handler explicitly + * (normally it's done implicitly by Tk_DestroyWindow). */ /* @@ -1651,13 +1629,13 @@ FrameEventProc(clientData, eventPtr) * DestroyFrame, we must free all options now. */ - DestroyFramePartly(framePtr); + DestroyFramePartly(framePtr); Tk_DeleteEventHandler(framePtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, FrameEventProc, (ClientData) framePtr); framePtr->tkwin = NULL; - Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd); + Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd); } if (framePtr->flags & REDRAW_PENDING) { Tcl_CancelIdleCall(DisplayFrame, (ClientData) framePtr); @@ -1684,7 +1662,7 @@ FrameEventProc(clientData, eventPtr) } return; - redraw: + redraw: if ((framePtr->tkwin != NULL) && !(framePtr->flags & REDRAW_PENDING)) { Tcl_DoWhenIdle(DisplayFrame, (ClientData) framePtr); framePtr->flags |= REDRAW_PENDING; @@ -1696,9 +1674,9 @@ FrameEventProc(clientData, eventPtr) * * FrameCmdDeletedProc -- * - * 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. + * This function 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. @@ -1724,19 +1702,19 @@ FrameCmdDeletedProc(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. + * This function 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 function destroys the + * widget. */ if (tkwin != NULL) { - /* - * Some options need tkwin to be freed, so we free them here, - * before setting tkwin to NULL. + /* + * Some options need tkwin to be freed, so we free them here, before + * setting tkwin to NULL. */ - DestroyFramePartly(framePtr); + DestroyFramePartly(framePtr); framePtr->tkwin = NULL; Tk_DestroyWindow(tkwin); @@ -1748,8 +1726,8 @@ FrameCmdDeletedProc(clientData) * * MapFrame -- * - * This procedure is invoked as a when-idle handler to map a - * newly-created top-level frame. + * This function is invoked as a when-idle handler to map a newly-created + * top-level frame. * * Results: * None. @@ -1767,10 +1745,10 @@ MapFrame(clientData) Frame *framePtr = (Frame *) clientData; /* - * Wait for all other background events to be processed before - * mapping window. This ensures that the window's correct geometry - * will have been determined before it is first mapped, so that the - * window manager doesn't get a false idea of its desired geometry. + * Wait for all other background events to be processed before mapping + * window. This ensures that the window's correct geometry will have been + * determined before it is first mapped, so that the window manager + * doesn't get a false idea of its desired geometry. */ Tcl_Preserve((ClientData) framePtr); @@ -1780,8 +1758,8 @@ MapFrame(clientData) } /* - * After each event, make sure that the window still exists - * and quit if the window has been destroyed. + * After each event, make sure that the window still exists and quit + * if the window has been destroyed. */ if (framePtr->tkwin == NULL) { @@ -1798,17 +1776,16 @@ MapFrame(clientData) * * TkInstallFrameMenu -- * - * This function is needed when a Windows HWND is created - * and a menubar has been set to the window with a system - * menu. It notifies the menu package so that the system - * menu can be rebuilt. + * This function is needed when a Windows HWND is created and a menubar + * has been set to the window with a system menu. It notifies the menu + * package so that the system menu can be rebuilt. * * Results: * None. * * Side effects: - * The system menu (if any) is created for the menubar - * associated with this frame. + * The system menu (if any) is created for the menubar associated with + * this frame. * *-------------------------------------------------------------- */ @@ -1825,7 +1802,7 @@ TkInstallFrameMenu(tkwin) if (framePtr == NULL) { Tcl_Panic("TkInstallFrameMenu couldn't get frame pointer"); } - TkpMenuNotifyToplevelCreate(winPtr->mainPtr->interp, + TkpMenuNotifyToplevelCreate(winPtr->mainPtr->interp, framePtr->menuName); } } @@ -1835,17 +1812,15 @@ TkInstallFrameMenu(tkwin) * * FrameStructureProc -- * - * This procedure is invoked whenever StructureNotify events - * occur for a window that's managed as label for the frame. - * This procudure's only purpose is to clean up when windows - * are deleted. + * This function is invoked whenever StructureNotify events occur for a + * window that's managed as label for the frame. This procudure's only + * purpose is to clean up when windows are deleted. * * Results: * None. * * Side effects: - * The window is disassociated from the frame when it is - * deleted. + * The window is disassociated from the frame when it is deleted. * *-------------------------------------------------------------- */ @@ -1859,8 +1834,8 @@ FrameStructureProc(clientData, eventPtr) if (eventPtr->type == DestroyNotify) { /* - * This should only happen in a labelframe but it doesn't - * hurt to be careful. + * This should only happen in a labelframe but it doesn't hurt to be + * careful. */ if (labelframePtr->frame.type == TYPE_LABELFRAME) { @@ -1875,24 +1850,23 @@ FrameStructureProc(clientData, eventPtr) * * FrameRequestProc -- * - * This procedure is invoked whenever a window that's associated - * with a frame changes its requested dimensions. + * This function is invoked whenever a window that's associated with a + * frame 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 frame. + * The size and location on the screen of the window may change depending + * on the options specified for the frame. * *-------------------------------------------------------------- */ static void FrameRequestProc(clientData, tkwin) - ClientData clientData; /* Pointer to record for frame. */ - Tk_Window tkwin; /* Window that changed its desired - * size. */ + ClientData clientData; /* Pointer to record for frame. */ + Tk_Window tkwin; /* Window that changed its desired size. */ { Frame *framePtr = (Frame *) clientData; @@ -1904,8 +1878,8 @@ FrameRequestProc(clientData, tkwin) * * FrameLostSlaveProc -- * - * This procedure is invoked by Tk whenever some other geometry - * claims control over a slave that used to be managed by us. + * This function is invoked by Tk whenever some other geometry claims + * control over a slave that used to be managed by us. * * Results: * None. @@ -1918,18 +1892,18 @@ FrameRequestProc(clientData, tkwin) static void FrameLostSlaveProc(clientData, tkwin) - ClientData clientData; /* Frame structure for slave window that - * was stolen away. */ + ClientData clientData; /* Frame structure for slave window that was + * stolen away. */ Tk_Window tkwin; /* Tk's handle for the slave window. */ { Frame *framePtr = (Frame *) clientData; Labelframe *labelframePtr = (Labelframe *) clientData; /* - * This should only happen in a labelframe but it doesn't - * hurt to be careful. + * This should only happen in a labelframe but it doesn't hurt to be + * careful. */ - + if (labelframePtr->frame.type == TYPE_LABELFRAME) { Tk_DeleteEventHandler(labelframePtr->labelWin, StructureNotifyMask, FrameStructureProc, (ClientData) labelframePtr); @@ -1947,15 +1921,14 @@ FrameLostSlaveProc(clientData, tkwin) * * TkToplevelWindowFromCommandToken -- * - * If the given command name to the command for a toplevel window - * in the given interpreter, return the tkwin for that toplevel - * window. Note that this lookup can't be done using the - * standard tkwin internal table because the command might have - * been renamed. + * If the given command name to the command for a toplevel window in the + * given interpreter, return the tkwin for that toplevel window. Note + * that this lookup can't be done using the standard tkwin internal table + * because the command might have been renamed. * * Results: - * A Tk_Window token, or NULL if the name does not refer to a - * toplevel window. + * A Tk_Window token, or NULL if the name does not refer to a toplevel + * window. * * Side effects: * None. @@ -1983,3 +1956,11 @@ TkToplevelWindowForCommand(interp, cmdName) } return framePtr->tkwin; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkGrid.c b/generic/tkGrid.c index 6e43869..cd4df5c 100644 --- a/generic/tkGrid.c +++ b/generic/tkGrid.c @@ -5,10 +5,10 @@ * * Copyright (c) 1996-1997 by Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkGrid.c,v 1.37 2005/04/04 08:53:00 dkf Exp $ + * RCS: @(#) $Id: tkGrid.c,v 1.38 2005/08/10 22:02:22 dkf Exp $ */ #include "tkInt.h" @@ -22,17 +22,17 @@ #endif #define MAX(x,y) ((x) > (y) ? (x) : (y)) -#define COLUMN (1) /* working on column offsets */ -#define ROW (2) /* working on row offsets */ +#define COLUMN (1) /* working on column offsets */ +#define ROW (2) /* working on row offsets */ #define CHECK_ONLY (1) /* check max slot constraint */ #define CHECK_SPACE (2) /* alloc more space, don't change max */ /* - * Pre-allocate enough row and column slots for "typical" sized tables - * this value should be chosen so by the time the extra malloc's are - * required, the layout calculations overwehlm them. [A "slot" contains - * information for either a row or column, depending upon the context.] + * Pre-allocate enough row and column slots for "typical" sized tables this + * value should be chosen so by the time the extra malloc's are required, the + * layout calculations overwehlm them. [A "slot" contains information for + * either a row or column, depending upon the context.] */ #define TYPICAL_SIZE 25 /* (arbitrary guess) */ @@ -45,9 +45,9 @@ #define UNIFORM_PREALLOC 10 /* - * Data structures are allocated dynamically to support arbitrary sized tables. - * However, the space is proportional to the highest numbered slot with - * some non-default property. This limit is used to head off mistakes and + * Data structures are allocated dynamically to support arbitrary sized + * tables. However, the space is proportional to the highest numbered slot + * with some non-default property. This limit is used to head off mistakes and * denial of service attacks by limiting the amount of storage required. */ @@ -68,8 +68,8 @@ #define GRID_DEFAULT_ANCHOR TK_ANCHOR_NW /* - * Structure to hold information for grid masters. A slot is either - * a row or column. + * Structure to hold information for grid masters. A slot is either a row or + * column. */ typedef struct SlotInfo { @@ -80,51 +80,49 @@ typedef struct SlotInfo { * this slot doesn't resize. Extra space in * the layout is given distributed among slots * inproportion to their weights. */ - int pad; /* Extra padding, in pixels, required for - * this slot. This amount is "added" to the - * largest slave in the slot. */ + int pad; /* Extra padding, in pixels, required for this + * slot. This amount is "added" to the largest + * slave in the slot. */ Tk_Uid uniform; /* Value of -uniform option. It is used to * group slots that should have the same * size. */ int offset; /* This is a cached value used for - * introspection. It is the pixel - * offset of the right or bottom edge - * of this slot from the beginning of the - * layout. */ + * introspection. It is the pixel offset of + * the right or bottom edge of this slot from + * the beginning of the layout. */ int temp; /* This is a temporary value used for - * calculating adjusted weights when - * shrinking the layout below its - * nominal size. */ + * calculating adjusted weights when shrinking + * the layout below its nominal size. */ } SlotInfo; /* - * Structure to hold information during layout calculations. There - * is one of these for each slot, an array for each of the rows or columns. + * Structure to hold information during layout calculations. There is one of + * these for each slot, an array for each of the rows or columns. */ typedef struct GridLayout { - struct Gridder *binNextPtr; /* The next slave window in this bin. - * Each bin contains a list of all - * slaves whose spans are >1 and whose - * right edges fall in this slot. */ - int minSize; /* Minimum size needed for this slot, - * in pixels. This is the space required - * to hold any slaves contained entirely - * in this slot, adjusted for any slot - * constrants, such as size or padding. */ + struct Gridder *binNextPtr; /* The next slave window in this bin. Each bin + * contains a list of all slaves whose spans + * are >1 and whose right edges fall in this + * slot. */ + int minSize; /* Minimum size needed for this slot, in + * pixels. This is the space required to hold + * any slaves contained entirely in this slot, + * adjusted for any slot constrants, such as + * size or padding. */ int pad; /* Padding needed for this slot */ int weight; /* Slot weight, controls resizing. */ Tk_Uid uniform; /* Value of -uniform option. It is used to * group slots that should have the same * size. */ - int minOffset; /* The minimum offset, in pixels, from - * the beginning of the layout to the - * right/bottom edge of the slot calculated - * from top/left to bottom/right. */ - int maxOffset; /* The maximum offset, in pixels, from - * the beginning of the layout to the - * right-or-bottom edge of the slot calculated - * from bottom-or-right to top-or-left. */ + int minOffset; /* The minimum offset, in pixels, from the + * beginning of the layout to the bottom/right + * edge of the slot calculated from top/left + * to bottom/right. */ + int maxOffset; /* The maximum offset, in pixels, from the + * beginning of the layout to the bottom/right + * edge of the slot calculated from + * bottom/right to top/left. */ } GridLayout; /* @@ -140,83 +138,83 @@ typedef struct { * column constraints. */ int rowEnd; /* The last row occupied by any slave. */ int rowMax; /* The number of rows with constraints. */ - int rowSpace; /* The number of slots currently allocated - * for row constraints. */ + int rowSpace; /* The number of slots currently allocated for + * row constraints. */ int startX; /* Pixel offset of this layout within its * master. */ int startY; /* Pixel offset of this layout within its * master. */ - Tk_Anchor anchor; /* Value of anchor option: specifies where - * a grid without weight should be placed. */ + Tk_Anchor anchor; /* Value of anchor option: specifies where a + * grid without weight should be placed. */ } GridMaster; /* - * For each window that the grid cares about (either because - * the window is managed by the grid or because the window - * has slaves that are managed by the grid), there is a - * structure of the following type: + * For each window that the grid cares about (either because the window is + * managed by the grid or because the window has slaves that are managed by + * the grid), there is a structure of the following type: */ typedef struct Gridder { - Tk_Window tkwin; /* Tk token for window. NULL means that - * the window has been deleted, but the - * gridder hasn't had a chance to clean up - * yet because the structure is still in - * use. */ - struct Gridder *masterPtr; /* Master window within which this window - * is managed (NULL means this window - * isn't managed by the gridder). */ - struct Gridder *nextPtr; /* Next window managed within same - * master. List order doesn't matter. */ - struct Gridder *slavePtr; /* First in list of slaves managed - * inside this window (NULL means - * no grid slaves). */ + Tk_Window tkwin; /* Tk token for window. NULL means that the + * window has been deleted, but the gridder + * hasn't had a chance to clean up yet because + * the structure is still in use. */ + struct Gridder *masterPtr; /* Master window within which this window is + * managed (NULL means this window isn't + * managed by the gridder). */ + struct Gridder *nextPtr; /* Next window managed within same master. + * List order doesn't matter. */ + struct Gridder *slavePtr; /* First in list of slaves managed inside this + * window (NULL means no grid slaves). */ GridMaster *masterDataPtr; /* Additional data for geometry master. */ - int column, row; /* Location in the grid (starting - * from zero). */ + int column, row; /* Location in the grid (starting from + * zero). */ int numCols, numRows; /* Number of columns or rows this slave spans. * Should be at least 1. */ int padX, padY; /* Total additional pixels to leave around the - * window. Some is of this space is on each - * side. This is space *outside* the window: + * window. Some is of this space is on each + * side. This is space *outside* the window: * we'll allocate extra space in frame but * won't enlarge window). */ - int padLeft, padTop; /* The part of padX or padY to use on the - * left or top of the widget, respectively. - * By default, this is half of padX or padY. */ + int padLeft, padTop; /* The part of padX or padY to use on the left + * or top of the widget, respectively. By + * default, this is half of padX or padY. */ int iPadX, iPadY; /* Total extra pixels to allocate inside the * window (half this amount will appear on * each side). */ int sticky; /* which sides of its cavity this window * sticks to. See below for definitions */ - int doubleBw; /* Twice the window's last known border - * width. If this changes, the window - * must be re-arranged within its master. */ - int *abortPtr; /* If non-NULL, it means that there is a nested - * call to ArrangeGrid already working on - * this window. *abortPtr may be set to 1 to - * abort that nested call. This happens, for - * example, if tkwin or any of its slaves + int doubleBw; /* Twice the window's last known border width. + * If this changes, the window must be + * re-arranged within its master. */ + int *abortPtr; /* If non-NULL, it means that there is a + * nested call to ArrangeGrid already working + * on this window. *abortPtr may be set to 1 + * to abort that nested call. This happens, + * for example, if tkwin or any of its slaves * is deleted. */ - int flags; /* Miscellaneous flags; see below - * for definitions. */ + int flags; /* Miscellaneous flags; see below for + * definitions. */ /* * These fields are used temporarily for layout calculations only. */ struct Gridder *binNextPtr; /* Link to next span>1 slave in this bin. */ - int size; /* Nominal size (width or height) in pixels - * of the slave. This includes the padding. */ + int size; /* Nominal size (width or height) in pixels of + * the slave. This includes the padding. */ } Gridder; -/* Flag values for "sticky"ness The 16 combinations subsume the packer's +/* + * Flag values for "sticky"ness. The 16 combinations subsume the packer's * notion of anchor and fill. * - * STICK_NORTH This window sticks to the top of its cavity. - * STICK_EAST This window sticks to the right edge of its cavity. - * STICK_SOUTH This window sticks to the bottom of its cavity. - * STICK_WEST This window sticks to the left edge of its cavity. + * STICK_NORTH This window sticks to the top of its cavity. + * STICK_EAST This window sticks to the right edge of its + * cavity. + * STICK_SOUTH This window sticks to the bottom of its cavity. + * STICK_WEST This window sticks to the left edge of its + * cavity. */ #define STICK_NORTH 1 @@ -237,14 +235,13 @@ typedef struct UniformGroup { /* * Flag values for Grid structures: * - * REQUESTED_RELAYOUT: 1 means a Tcl_DoWhenIdle request - * has already been made to re-arrange - * all the slaves of this window. - * - * DONT_PROPAGATE: 1 means don't set this window's requested - * size. 0 means if this window is a master - * then Tk will set its requested size to fit - * the needs of its slaves. + * REQUESTED_RELAYOUT 1 means a Tcl_DoWhenIdle request has already + * been made to re-arrange all the slaves of this + * window. + * DONT_PROPAGATE 1 means don't set this window's requested + * size. 0 means if this window is a master then + * Tk will set its requested size to fit the + * needs of its slaves. */ #define REQUESTED_RELAYOUT 1 @@ -254,50 +251,53 @@ typedef struct UniformGroup { * Prototypes for procedures used only in this file: */ -static void AdjustForSticky _ANSI_ARGS_((Gridder *slavePtr, int *xPtr, - int *yPtr, int *widthPtr, int *heightPtr)); -static int AdjustOffsets _ANSI_ARGS_((int width, - int elements, SlotInfo *slotPtr)); -static void ArrangeGrid _ANSI_ARGS_((ClientData clientData)); -static int CheckSlotData _ANSI_ARGS_((Gridder *masterPtr, int slot, - int slotType, int checkOnly)); -static int ConfigureSlaves _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window tkwin, int objc, Tcl_Obj *CONST objv[])); -static void DestroyGrid _ANSI_ARGS_((char *memPtr)); -static Gridder *GetGrid _ANSI_ARGS_((Tk_Window tkwin)); -static int GridAnchorCommand _ANSI_ARGS_((Tk_Window tkwin, - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); -static int GridBboxCommand _ANSI_ARGS_((Tk_Window tkwin, - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); -static int GridForgetRemoveCommand _ANSI_ARGS_((Tk_Window tkwin, - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); -static int GridInfoCommand _ANSI_ARGS_((Tk_Window tkwin, - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); -static int GridLocationCommand _ANSI_ARGS_((Tk_Window tkwin, - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); -static int GridPropagateCommand _ANSI_ARGS_((Tk_Window tkwin, - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); -static int GridRowColumnConfigureCommand _ANSI_ARGS_((Tk_Window tkwin, - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); -static int GridSizeCommand _ANSI_ARGS_((Tk_Window tkwin, - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); -static int GridSlavesCommand _ANSI_ARGS_((Tk_Window tkwin, - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); -static void GridStructureProc _ANSI_ARGS_(( - ClientData clientData, XEvent *eventPtr)); -static void GridLostSlaveProc _ANSI_ARGS_((ClientData clientData, - Tk_Window tkwin)); -static void GridReqProc _ANSI_ARGS_((ClientData clientData, - Tk_Window tkwin)); -static void InitMasterData _ANSI_ARGS_((Gridder *masterPtr)); -static Tcl_Obj *NewPairObj _ANSI_ARGS_((Tcl_Interp*, int, int)); -static Tcl_Obj *NewQuadObj _ANSI_ARGS_((Tcl_Interp*, int, int, int, int)); -static int ResolveConstraints _ANSI_ARGS_((Gridder *gridPtr, - int rowOrColumn, int maxOffset)); -static void SetGridSize _ANSI_ARGS_((Gridder *gridPtr)); -static void StickyToString _ANSI_ARGS_((int flags, char *result)); -static int StringToSticky _ANSI_ARGS_((char *string)); -static void Unlink _ANSI_ARGS_((Gridder *gridPtr)); +static void AdjustForSticky(Gridder *slavePtr, int *xPtr, + int *yPtr, int *widthPtr, int *heightPtr); +static int AdjustOffsets(int width, int elements, + SlotInfo *slotPtr); +static void ArrangeGrid(ClientData clientData); +static int CheckSlotData(Gridder *masterPtr, int slot, + int slotType, int checkOnly); +static int ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin, + int objc, Tcl_Obj *CONST objv[]); +static void DestroyGrid(char *memPtr); +static Gridder * GetGrid(Tk_Window tkwin); +static int GridAnchorCommand(Tk_Window tkwin, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); +static int GridBboxCommand(Tk_Window tkwin, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); +static int GridForgetRemoveCommand(Tk_Window tkwin, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]); +static int GridInfoCommand(Tk_Window tkwin, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); +static int GridLocationCommand(Tk_Window tkwin, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]); +static int GridPropagateCommand(Tk_Window tkwin, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]); +static int GridRowColumnConfigureCommand(Tk_Window tkwin, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]); +static int GridSizeCommand(Tk_Window tkwin, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); +static int GridSlavesCommand(Tk_Window tkwin, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); +static void GridStructureProc(ClientData clientData, + XEvent *eventPtr); +static void GridLostSlaveProc(ClientData clientData, + Tk_Window tkwin); +static void GridReqProc(ClientData clientData, Tk_Window tkwin); +static void InitMasterData(Gridder *masterPtr); +static Tcl_Obj * NewPairObj(int, int); +static Tcl_Obj * NewQuadObj(int, int, int, int); +static int ResolveConstraints(Gridder *gridPtr, int rowOrColumn, + int maxOffset); +static void SetGridSize(Gridder *gridPtr); +static void StickyToString(int flags, char *result); +static int StringToSticky(char *string); +static void Unlink(Gridder *gridPtr); static Tk_GeomMgr gridMgrType = { "grid", /* name */ @@ -310,8 +310,8 @@ static Tk_GeomMgr gridMgrType = { * * Tk_GridCmd -- * - * This procedure is invoked to process the "grid" Tcl command. - * See the user documentation for details on what it does. + * This procedure is invoked to process the "grid" Tcl command. See the + * user documentation for details on what it does. * * Results: * A standard Tcl result. @@ -324,8 +324,7 @@ static Tk_GeomMgr gridMgrType = { int Tk_GridObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Main window associated with - * interpreter. */ + ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ @@ -367,7 +366,8 @@ Tk_GridObjCmd(clientData, interp, objc, objv) return GridBboxCommand(tkwin, interp, objc, objv); case GRID_CONFIGURE: return ConfigureSlaves(interp, tkwin, objc-2, objv+2); - case GRID_FORGET: case GRID_REMOVE: + case GRID_FORGET: + case GRID_REMOVE: return GridForgetRemoveCommand(tkwin, interp, objc, objv); case GRID_INFO: return GridInfoCommand(tkwin, interp, objc, objv); @@ -404,7 +404,7 @@ Tk_GridObjCmd(clientData, interp, objc, objv) * * GridAnchorCommand -- * - * Implementation of the [grid anchor] subcommand. See the user + * Implementation of the [grid anchor] subcommand. See the user * documentation for details on what it does. * * Results: @@ -532,7 +532,7 @@ GridBboxCommand(tkwin, interp, objc, objv) gridPtr = masterPtr->masterDataPtr; if (gridPtr == NULL) { - Tcl_SetObjResult(interp, NewQuadObj(interp, 0, 0, 0, 0)); + Tcl_SetObjResult(interp, NewQuadObj(0, 0, 0, 0)); return TCL_OK; } @@ -541,7 +541,7 @@ GridBboxCommand(tkwin, interp, objc, objv) endY = MAX(gridPtr->rowEnd, gridPtr->rowMax); if ((endX == 0) || (endY == 0)) { - Tcl_SetObjResult(interp, NewQuadObj(interp, 0, 0, 0, 0)); + Tcl_SetObjResult(interp, NewQuadObj(0, 0, 0, 0)); return TCL_OK; } if (objc == 3) { @@ -590,7 +590,7 @@ GridBboxCommand(tkwin, interp, objc, objv) height = gridPtr->rowPtr[row2].offset - y; } - Tcl_SetObjResult(interp, NewQuadObj(interp, + Tcl_SetObjResult(interp, NewQuadObj( x + gridPtr->startX, y + gridPtr->startY, width, height)); return TCL_OK; } @@ -600,8 +600,8 @@ GridBboxCommand(tkwin, interp, objc, objv) * * GridForgetRemoveCommand -- * - * Implementation of the [grid forget]/[grid remove] subcommands. - * See the user documentation for details on what these do. + * Implementation of the [grid forget]/[grid remove] subcommands. See the + * user documentation for details on what these do. * * Results: * Standard Tcl result. @@ -673,7 +673,7 @@ GridForgetRemoveCommand(tkwin, interp, objc, objv) * * GridInfoCommand -- * - * Implementation of the [grid info] subcommand. See the user + * Implementation of the [grid info] subcommand. See the user * documentation for details on what it does. * * Results: @@ -729,7 +729,7 @@ GridInfoCommand(tkwin, interp, objc, objv) * * GridLocationCommand -- * - * Implementation of the [grid location] subcommand. See the user + * Implementation of the [grid location] subcommand. See the user * documentation for details on what it does. * * Results: @@ -752,8 +752,8 @@ GridLocationCommand(tkwin, interp, objc, objv) Gridder *masterPtr; /* master grid record */ GridMaster *gridPtr; /* pointer to grid data */ register SlotInfo *slotPtr; - int x, y; /* Offset in pixels, from edge of master. */ - int i, j; /* Corresponding column and row indeces. */ + int x, y; /* Offset in pixels, from edge of master. */ + int i, j; /* Corresponding column and row indeces. */ int endX, endY; /* end of grid */ if (objc != 5) { @@ -774,15 +774,15 @@ GridLocationCommand(tkwin, interp, objc, objv) masterPtr = GetGrid(master); if (masterPtr->masterDataPtr == NULL) { - Tcl_SetObjResult(interp, NewPairObj(interp, -1, -1)); + Tcl_SetObjResult(interp, NewPairObj(-1, -1)); return TCL_OK; } gridPtr = masterPtr->masterDataPtr; /* - * Update any pending requests. This is not always the - * steady state value, as more configure events could be in - * the pipeline, but its as close as its easy to get. + * Update any pending requests. This is not always the steady state value, + * as more configure events could be in the pipeline, but its as close as + * its easy to get. */ while (masterPtr->flags & REQUESTED_RELAYOUT) { @@ -813,7 +813,7 @@ GridLocationCommand(tkwin, interp, objc, objv) } } - Tcl_SetObjResult(interp, NewPairObj(interp, i, j)); + Tcl_SetObjResult(interp, NewPairObj(i, j)); return TCL_OK; } @@ -822,7 +822,7 @@ GridLocationCommand(tkwin, interp, objc, objv) * * GridPropagateCommand -- * - * Implementation of the [grid propagate] subcommand. See the user + * Implementation of the [grid propagate] subcommand. See the user * documentation for details on what it does. * * Results: @@ -863,7 +863,9 @@ GridPropagateCommand(tkwin, interp, objc, objv) return TCL_ERROR; } - /* Only request a relayout if the propagation bit changes */ + /* + * Only request a relayout if the propagation bit changes. + */ old = !(masterPtr->flags & DONT_PROPAGATE); if (propagate != old) { @@ -895,8 +897,7 @@ GridPropagateCommand(tkwin, interp, objc, objv) * GridRowColumnConfigureCommand -- * * Implementation of the [grid rowconfigure] and [grid columnconfigure] - * subcommands. See the user documentation for details on what these - * do. + * subcommands. See the user documentation for details on what these do. * * Results: * Standard Tcl result. @@ -971,8 +972,8 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv) } /* - * Return all of the options for this row or column. If the - * request is out of range, return all 0's. + * Return all of the options for this row or column. If the request is + * out of range, return all 0's. */ if (objc == 4) { @@ -1005,8 +1006,8 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv) } /* - * If only one option is given, with no value, the - * current value is returned. + * If only one option is given, with no value, the current value is + * returned. */ if (Tcl_GetIndexFromObj(interp, objv[4], optionStrings, @@ -1045,7 +1046,10 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv) allSlaves = 1; } else if (TkGetWindowFromObj(interp, tkwin, lObjv[j], &slave) == TCL_OK) { - /* Is it gridded in this master? */ + /* + * Is it gridded in this master? + */ + slavePtr = GetGrid(slave); if (slavePtr->masterPtr != masterPtr) { Tcl_ResetResult(interp); @@ -1067,6 +1071,7 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv) /* * The outer loop is only to handle "all". */ + do { if (slavePtr != NULL) { first = (slotType == COLUMN) ? @@ -1146,8 +1151,8 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv) } /* - * We changed a property, re-arrange the table, - * and check for constraint shrinkage. + * We changed a property, re-arrange the table, and check for constraint + * shrinkage. */ if (slotType == ROW) { @@ -1183,7 +1188,7 @@ GridRowColumnConfigureCommand(tkwin, interp, objc, objv) * * GridSizeCommand -- * - * Implementation of the [grid size] subcommand. See the user + * Implementation of the [grid size] subcommand. See the user * documentation for details on what it does. * * Results: @@ -1219,11 +1224,11 @@ GridSizeCommand(tkwin, interp, objc, objv) if (masterPtr->masterDataPtr != NULL) { SetGridSize(masterPtr); gridPtr = masterPtr->masterDataPtr; - Tcl_SetObjResult(interp, NewPairObj(interp, + Tcl_SetObjResult(interp, NewPairObj( MAX(gridPtr->columnEnd, gridPtr->columnMax), MAX(gridPtr->rowEnd, gridPtr->rowMax))); } else { - Tcl_SetObjResult(interp, NewPairObj(interp, 0, 0)); + Tcl_SetObjResult(interp, NewPairObj(0, 0)); } return TCL_OK; } @@ -1233,15 +1238,15 @@ GridSizeCommand(tkwin, interp, objc, objv) * * GridSlavesCommand -- * - * Implementation of the [grid slaves] subcommand. See the user + * Implementation of the [grid slaves] subcommand. See the user * documentation for details on what it does. * * Results: * Standard Tcl result. * * Side effects: - * Places a list of slaves of the specified window in the - * interpreter's result field. + * Places a list of slaves of the specified window in the interpreter's + * result field. * *---------------------------------------------------------------------- */ @@ -1319,15 +1324,15 @@ GridSlavesCommand(tkwin, interp, objc, objv) * * GridReqProc -- * - * This procedure is invoked by Tk_GeometryRequest for - * windows managed by the grid. + * This procedure is invoked by Tk_GeometryRequest for windows managed by + * the grid. * * Results: * None. * * Side effects: - * Arranges for tkwin, and all its managed siblings, to - * be re-arranged at the next idle point. + * Arranges for tkwin, and all its managed siblings, to be re-arranged at + * the next idle point. * *---------------------------------------------------------------------- */ @@ -1354,8 +1359,8 @@ GridReqProc(clientData, tkwin) * * GridLostSlaveProc -- * - * This procedure is invoked by Tk whenever some other geometry - * claims control over a slave that used to be managed by us. + * This procedure is invoked by Tk whenever some other geometry claims + * control over a slave that used to be managed by us. * * Results: * None. @@ -1368,8 +1373,8 @@ GridReqProc(clientData, tkwin) static void GridLostSlaveProc(clientData, tkwin) - ClientData clientData; /* Grid structure for slave window that - * was stolen away. */ + ClientData clientData; /* Grid structure for slave window that was + * stolen away. */ Tk_Window tkwin; /* Tk's handle for the slave window. */ { register Gridder *slavePtr = (Gridder *) clientData; @@ -1386,11 +1391,11 @@ GridLostSlaveProc(clientData, tkwin) * * AdjustOffsets -- * - * This procedure adjusts the size of the layout to fit in the - * space provided. If it needs more space, the extra is added - * according to the weights. If it needs less, the space is removed - * according to the weights, but at no time does the size drop below - * the minsize specified for that slot. + * This procedure adjusts the size of the layout to fit in the space + * provided. If it needs more space, the extra is added according to the + * weights. If it needs less, the space is removed according to the + * weights, but at no time does the size drop below the minsize specified + * for that slot. * * Results: * The size used by the layout. @@ -1412,8 +1417,8 @@ AdjustOffsets(size, slots, slotPtr) int totalWeight; /* Sum of the weights for all the slots. */ int weight; /* Sum of the weights so far. */ int minSize; /* Minimum possible layout size. */ - int newDiff; /* The most pixels that can be added on - * the current pass. */ + int newDiff; /* The most pixels that can be added on the + * current pass. */ diff = size - slotPtr[slots-1].offset; @@ -1439,7 +1444,7 @@ AdjustOffsets(size, slots, slotPtr) } /* - * Add extra space according to the slot weights. This is done + * Add extra space according to the slot weights. This is done * cumulatively to prevent round-off error accumulation. */ @@ -1453,9 +1458,9 @@ AdjustOffsets(size, slots, slotPtr) } /* - * The layout must shrink below its requested size. Compute the - * minimum possible size by looking at the slot minSizes. - * Store each slot's minimum size in temp. + * The layout must shrink below its requested size. Compute the minimum + * possible size by looking at the slot minSizes. Store each slot's + * minimum size in temp. */ minSize = 0; @@ -1471,8 +1476,8 @@ AdjustOffsets(size, slots, slotPtr) } /* - * If the requested size is less than the minimum required size, - * set the slot sizes to their minimum values. + * If the requested size is less than the minimum required size, set the + * slot sizes to their minimum values. */ if (size <= minSize) { @@ -1485,8 +1490,8 @@ AdjustOffsets(size, slots, slotPtr) } /* - * Remove space from slots according to their weights. The weights - * get renormalized anytime a slot shrinks to its minimum size. + * Remove space from slots according to their weights. The weights get + * renormalized anytime a slot shrinks to its minimum size. */ while (diff < 0) { @@ -1515,9 +1520,9 @@ AdjustOffsets(size, slots, slotPtr) newDiff = diff; for (slot = 0; slot < slots; slot++) { - int current; /* current size of this slot */ - int maxDiff; /* max diff that would cause - * this slot to equal its minsize */ + int current; /* Current size of this slot. */ + int maxDiff; /* Maximum diff that would cause this slot to + * equal its minsize. */ if (slotPtr[slot].temp == 0) { continue; } @@ -1549,12 +1554,12 @@ AdjustOffsets(size, slots, slotPtr) * * AdjustForSticky -- * - * This procedure adjusts the size of a slave in its cavity based - * on its "sticky" flags. + * This procedure adjusts the size of a slave in its cavity based on its + * "sticky" flags. * * Results: - * The input x, y, width, and height are changed to represent the - * desired coordinates of the slave. + * The input x, y, width, and height are changed to represent the desired + * coordinates of the slave. * * Side effects: * None. @@ -1608,10 +1613,10 @@ AdjustForSticky(slavePtr, xPtr, yPtr, widthPtr, heightPtr) * * ArrangeGrid -- * - * This procedure is invoked (using the Tcl_DoWhenIdle mechanism) - * to re-layout a set of windows managed by the grid. It is - * invoked at idle time so that a series of grid requests can be - * merged into a single layout operation. + * This procedure is invoked (using the Tcl_DoWhenIdle mechanism) to + * re-layout a set of windows managed by the grid. It is invoked at idle + * time so that a series of grid requests can be merged into a single + * layout operation. * * Results: * None. @@ -1631,17 +1636,17 @@ ArrangeGrid(clientData) register Gridder *slavePtr; GridMaster *slotPtr = masterPtr->masterDataPtr; int abort; - int width, height; /* requested size of layout, in pixels */ - int realWidth, realHeight; /* actual size layout should take-up */ + int width, height; /* Requested size of layout, in pixels. */ + int realWidth, realHeight; /* Actual size layout should take-up. */ int usedX, usedY; masterPtr->flags &= ~REQUESTED_RELAYOUT; /* - * If the master has no slaves anymore, then don't do anything - * at all: just leave the master's size as-is. Otherwise there is - * no way to "relinquish" control over the master so another geometry - * manager can take over. + * If the master has no slaves anymore, then don't do anything at all: + * just leave the master's size as-is. Otherwise there is no way to + * "relinquish" control over the master so another geometry manager can + * take over. */ if (masterPtr->slavePtr == NULL) { @@ -1653,9 +1658,9 @@ ArrangeGrid(clientData) } /* - * Abort any nested call to ArrangeGrid for this window, since - * we'll do everything necessary here, and set up so this call - * can be aborted if necessary. + * Abort any nested call to ArrangeGrid for this window, since we'll do + * everything necessary here, and set up so this call can be aborted if + * necessary. */ if (masterPtr->abortPtr != NULL) { @@ -1699,9 +1704,9 @@ ArrangeGrid(clientData) /* * If the currently requested layout size doesn't match the master's - * window size, then adjust the slot offsets according to the - * weights. If all of the weights are zero, place the layout according - * to the anchor value. + * window size, then adjust the slot offsets according to the weights. If + * all of the weights are zero, place the layout according to the anchor + * value. */ realWidth = Tk_Width(masterPtr->tkwin) - @@ -1718,15 +1723,14 @@ ArrangeGrid(clientData) 0, 0, usedX, usedY, &slotPtr->startX, &slotPtr->startY); /* - * Now adjust the actual size of the slave to its cavity by - * computing the cavity size, and adjusting the widget according - * to its stickyness. + * Now adjust the actual size of the slave to its cavity by computing the + * cavity size, and adjusting the widget according to its stickyness. */ for (slavePtr = masterPtr->slavePtr; slavePtr != NULL && !abort; slavePtr = slavePtr->nextPtr) { - int x, y; /* top left coordinate */ - int width, height; /* slot or slave size */ + int x, y; /* Top left coordinate */ + int width, height; /* Slot or slave size */ int col = slavePtr->column; int row = slavePtr->row; @@ -1742,9 +1746,9 @@ ArrangeGrid(clientData) AdjustForSticky(slavePtr, &x, &y, &width, &height); /* - * Now put the window in the proper spot. (This was taken directly - * from tkPack.c.) If the slave is a child of the master, then - * do this here. Otherwise let Tk_MaintainGeometry do the work. + * Now put the window in the proper spot. (This was taken directly + * from tkPack.c.) If the slave is a child of the master, then do this + * here. Otherwise let Tk_MaintainGeometry do the work. */ if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) { @@ -1762,8 +1766,8 @@ ArrangeGrid(clientData) } /* - * Don't map the slave if the master isn't mapped: wait - * until the master gets mapped later. + * Don't map the slave if the master isn't mapped: wait until + * the master gets mapped later. */ if (Tk_IsMapped(masterPtr->tkwin)) { @@ -1790,9 +1794,9 @@ ArrangeGrid(clientData) * * ResolveConstraints -- * - * Resolve all of the column and row boundaries. Most of - * the calculations are identical for rows and columns, so this procedure - * is called twice, once for rows, and again for columns. + * Resolve all of the column and row boundaries. Most of the calculations + * are identical for rows and columns, so this procedure is called twice, + * once for rows, and again for columns. * * Results: * The offset (in pixels) from the left/top edge of this layout is @@ -1809,16 +1813,16 @@ static int ResolveConstraints(masterPtr, slotType, maxOffset) Gridder *masterPtr; /* The geometry master for this grid. */ int slotType; /* Either ROW or COLUMN. */ - int maxOffset; /* The actual maximum size of this layout - * in pixels, or 0 (not currently used). */ + int maxOffset; /* The actual maximum size of this layout in + * pixels, or 0 (not currently used). */ { register SlotInfo *slotPtr; /* Pointer to row/col constraints. */ register Gridder *slavePtr; /* List of slave windows in this grid. */ int constraintCount; /* Count of rows or columns that have * constraints. */ int slotCount; /* Last occupied row or column. */ - int gridCount; /* The larger of slotCount and constraintCount. - */ + int gridCount; /* The larger of slotCount and + * constraintCount. */ GridLayout *layoutPtr; /* Temporary layout structure. */ int requiredSize; /* The natural size of the grid (pixels). * This is the minimum size needed to @@ -1837,14 +1841,14 @@ ResolveConstraints(masterPtr, slotType, maxOffset) UniformGroup *uniformGroupPtr; /* Uniform groups data. */ int uniformGroups; /* Number of currently used uniform groups. */ - int uniformGroupsAlloced; /* Size of allocated space for uniform groups. - */ + int uniformGroupsAlloced; /* Size of allocated space for uniform + * groups. */ int weight, minSize; int prevGrow, accWeight, grow; /* - * For typical sized tables, we'll use stack space for the layout data - * to avoid the overhead of a malloc and free for every layout. + * For typical sized tables, we'll use stack space for the layout data to + * avoid the overhead of a malloc and free for every layout. */ GridLayout layoutData[TYPICAL_SIZE + 1]; @@ -1852,11 +1856,11 @@ ResolveConstraints(masterPtr, slotType, maxOffset) if (slotType == COLUMN) { constraintCount = masterPtr->masterDataPtr->columnMax; slotCount = masterPtr->masterDataPtr->columnEnd; - slotPtr = masterPtr->masterDataPtr->columnPtr; + slotPtr = masterPtr->masterDataPtr->columnPtr; } else { constraintCount = masterPtr->masterDataPtr->rowMax; slotCount = masterPtr->masterDataPtr->rowEnd; - slotPtr = masterPtr->masterDataPtr->rowPtr; + slotPtr = masterPtr->masterDataPtr->rowPtr; } /* @@ -1871,11 +1875,12 @@ ResolveConstraints(masterPtr, slotType, maxOffset) } /* - * Allocate an extra layout slot to represent the left/top edge of - * the 0th slot to make it easier to calculate slot widths from - * offsets without special case code. - * Initialize the "dummy" slot to the left/top of the table. - * This slot avoids special casing the first slot. + * Allocate an extra layout slot to represent the left/top edge of the 0th + * slot to make it easier to calculate slot widths from offsets without + * special case code. + * + * Initialize the "dummy" slot to the left/top of the table. This slot + * avoids special casing the first slot. */ layoutPtr->minOffset = 0; @@ -1884,8 +1889,8 @@ ResolveConstraints(masterPtr, slotType, maxOffset) /* * Step 1. - * Copy the slot constraints into the layout structure, - * and initialize the rest of the fields. + * Copy the slot constraints into the layout structure, and initialize the + * rest of the fields. */ for (slot=0; slot < constraintCount; slot++) { @@ -1905,52 +1910,55 @@ ResolveConstraints(masterPtr, slotType, maxOffset) /* * Step 2. - * Slaves with a span of 1 are used to determine the minimum size of - * each slot. Slaves whose span is two or more slots don't - * contribute to the minimum size of each slot directly, but can cause - * slots to grow if their size exceeds the the sizes of the slots they - * span. + * Slaves with a span of 1 are used to determine the minimum size of each + * slot. Slaves whose span is two or more slots don't contribute to the + * minimum size of each slot directly, but can cause slots to grow if + * their size exceeds the the sizes of the slots they span. * - * Bin all slaves whose spans are > 1 by their right edges. This - * allows the computation on minimum and maximum possible layout - * sizes at each slot boundary, without the need to re-sort the slaves. + * Bin all slaves whose spans are > 1 by their right edges. This allows + * the computation on minimum and maximum possible layout sizes at each + * slot boundary, without the need to re-sort the slaves. */ switch (slotType) { - case COLUMN: - for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; - slavePtr = slavePtr->nextPtr) { - int rightEdge = slavePtr->column + slavePtr->numCols - 1; - slavePtr->size = Tk_ReqWidth(slavePtr->tkwin) + - slavePtr->padX + slavePtr->iPadX + slavePtr->doubleBw; - if (slavePtr->numCols > 1) { - slavePtr->binNextPtr = layoutPtr[rightEdge].binNextPtr; - layoutPtr[rightEdge].binNextPtr = slavePtr; - } else { - int size = slavePtr->size + layoutPtr[rightEdge].pad; - if (size > layoutPtr[rightEdge].minSize) { - layoutPtr[rightEdge].minSize = size; - } + case COLUMN: + for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; + slavePtr = slavePtr->nextPtr) { + int rightEdge = slavePtr->column + slavePtr->numCols - 1; + + slavePtr->size = Tk_ReqWidth(slavePtr->tkwin) + slavePtr->padX + + slavePtr->iPadX + slavePtr->doubleBw; + if (slavePtr->numCols > 1) { + slavePtr->binNextPtr = layoutPtr[rightEdge].binNextPtr; + layoutPtr[rightEdge].binNextPtr = slavePtr; + } else { + int size = slavePtr->size + layoutPtr[rightEdge].pad; + + if (size > layoutPtr[rightEdge].minSize) { + layoutPtr[rightEdge].minSize = size; } } - break; - case ROW: - for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; - slavePtr = slavePtr->nextPtr) { - int rightEdge = slavePtr->row + slavePtr->numRows - 1; - slavePtr->size = Tk_ReqHeight(slavePtr->tkwin) + - slavePtr->padY + slavePtr->iPadY + slavePtr->doubleBw; - if (slavePtr->numRows > 1) { - slavePtr->binNextPtr = layoutPtr[rightEdge].binNextPtr; - layoutPtr[rightEdge].binNextPtr = slavePtr; - } else { - int size = slavePtr->size + layoutPtr[rightEdge].pad; - if (size > layoutPtr[rightEdge].minSize) { - layoutPtr[rightEdge].minSize = size; - } + } + break; + case ROW: + for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; + slavePtr = slavePtr->nextPtr) { + int rightEdge = slavePtr->row + slavePtr->numRows - 1; + + slavePtr->size = Tk_ReqHeight(slavePtr->tkwin) + slavePtr->padY + + slavePtr->iPadY + slavePtr->doubleBw; + if (slavePtr->numRows > 1) { + slavePtr->binNextPtr = layoutPtr[rightEdge].binNextPtr; + layoutPtr[rightEdge].binNextPtr = slavePtr; + } else { + int size = slavePtr->size + layoutPtr[rightEdge].pad; + + if (size > layoutPtr[rightEdge].minSize) { + layoutPtr[rightEdge].minSize = size; } } - break; + } + break; } /* @@ -1983,13 +1991,14 @@ ResolveConstraints(masterPtr, slotType, maxOffset) * sizeof(UniformGroup); size_t newSize = (uniformGroupsAlloced + UNIFORM_PREALLOC) * sizeof(UniformGroup); - UniformGroup *new = (UniformGroup *) ckalloc(newSize); - UniformGroup *old = uniformGroupPtr; - memcpy((VOID *) new, (VOID *) old, oldSize); - if (old != uniformPre) { - ckfree((char *) old); + UniformGroup *newUG = (UniformGroup *) ckalloc(newSize); + UniformGroup *oldUG = uniformGroupPtr; + + memcpy((VOID *) newUG, (VOID *) oldUG, oldSize); + if (oldUG != uniformPre) { + ckfree((char *) oldUG); } - uniformGroupPtr = new; + uniformGroupPtr = newUG; uniformGroupsAlloced += UNIFORM_PREALLOC; } uniformGroups++; @@ -2032,8 +2041,8 @@ ResolveConstraints(masterPtr, slotType, maxOffset) /* * Step 3. - * Determine the minimum slot offsets going from left to right - * that would fit all of the slaves. This determines the minimum + * Determine the minimum slot offsets going from left to right that would + * fit all of the slaves. This determines the minimum */ for (offset=0,slot=0; slot < gridCount; slot++) { @@ -2043,6 +2052,7 @@ ResolveConstraints(masterPtr, slotType, maxOffset) int span = (slotType == COLUMN) ? slavePtr->numCols : slavePtr->numRows; int required = slavePtr->size + layoutPtr[slot - span].minOffset; + if (required > layoutPtr[slot].minOffset) { layoutPtr[slot].minOffset = required; } @@ -2052,8 +2062,8 @@ ResolveConstraints(masterPtr, slotType, maxOffset) /* * At this point, we know the minimum required size of the entire layout. - * It might be prudent to stop here if our "master" will resize itself - * to this size. + * It might be prudent to stop here if our "master" will resize itself to + * this size. */ requiredSize = offset; @@ -2063,10 +2073,10 @@ ResolveConstraints(masterPtr, slotType, maxOffset) /* * Step 4. - * Determine the minimum slot offsets going from right to left, - * bounding the pixel range of each slot boundary. - * Pre-fill all of the right offsets with the actual size of the table; - * they will be reduced as required. + * Determine the minimum slot offsets going from right to left, bounding + * the pixel range of each slot boundary. Pre-fill all of the right + * offsets with the actual size of the table; they will be reduced as + * required. */ for (slot=0; slot < gridCount; slot++) { @@ -2079,6 +2089,7 @@ ResolveConstraints(masterPtr, slotType, maxOffset) slavePtr->numCols : slavePtr->numRows; int require = offset - slavePtr->size; int startSlot = slot - span; + if (startSlot >=0 && require < layoutPtr[startSlot].maxOffset) { layoutPtr[startSlot].maxOffset = require; } @@ -2094,30 +2105,29 @@ ResolveConstraints(masterPtr, slotType, maxOffset) /* * Step 5. - * At this point, each slot boundary has a range of values that - * will satisfy the overall layout size. - * Make repeated passes over the layout structure looking for - * spans of slot boundaries where the minOffsets are less than - * the maxOffsets, and adjust the offsets according to the slot - * weights. At each pass, at least one slot boundary will have - * its range of possible values fixed at a single value. + * At this point, each slot boundary has a range of values that will + * satisfy the overall layout size. Make repeated passes over the layout + * structure looking for spans of slot boundaries where the minOffsets are + * less than the maxOffsets, and adjust the offsets according to the slot + * weights. At each pass, at least one slot boundary will have its range + * of possible values fixed at a single value. */ for (start = 0; start < gridCount;) { - int totalWeight = 0; /* Sum of the weights for all of the - * slots in this span. */ - int need = 0; /* The minimum space needed to layout - * this span. */ - int have; /* The actual amount of space that will - * be taken up by this span. */ - int weight; /* Cumulative weights of the columns in + int totalWeight = 0; /* Sum of the weights for all of the slots in * this span. */ + int need = 0; /* The minimum space needed to layout this + * span. */ + int have; /* The actual amount of space that will be + * taken up by this span. */ + int weight; /* Cumulative weights of the columns in this + * span. */ int noWeights = 0; /* True if the span has no weights. */ /* - * Find a span by identifying ranges of slots whose edges are - * already constrained at fixed offsets, but whose internal - * slot boundaries have a range of possible positions. + * Find a span by identifying ranges of slots whose edges are already + * constrained at fixed offsets, but whose internal slot boundaries + * have a range of possible positions. */ if (layoutPtr[start].minOffset == layoutPtr[start].maxOffset) { @@ -2132,9 +2142,8 @@ ResolveConstraints(masterPtr, slotType, maxOffset) } /* - * We found a span. Compute the total weight, minumum space required, - * for this span, and the actual amount of space the span should - * use. + * We found a span. Compute the total weight, minumum space required, + * for this span, and the actual amount of space the span should use. */ for (slot = start; slot <= end; slot++) { @@ -2144,8 +2153,8 @@ ResolveConstraints(masterPtr, slotType, maxOffset) have = layoutPtr[end].maxOffset - layoutPtr[start-1].minOffset; /* - * If all the weights in the span are zero, then distribute the - * extra space evenly. + * If all the weights in the span are zero, then distribute the extra + * space evenly. */ if (totalWeight == 0) { @@ -2155,19 +2164,20 @@ ResolveConstraints(masterPtr, slotType, maxOffset) /* * It might not be possible to give the span all of the space - * available on this pass without violating the size constraints - * of one or more of the internal slot boundaries. - * Try to determine the maximum amount of space that when added to - * the entire span, would cause a slot boundary to have its possible - * range reduced to one value, and reduce the amount of extra - * space allocated on this pass accordingly. + * available on this pass without violating the size constraints of + * one or more of the internal slot boundaries. Try to determine the + * maximum amount of space that when added to the entire span, would + * cause a slot boundary to have its possible range reduced to one + * value, and reduce the amount of extra space allocated on this pass + * accordingly. * - * The calculation is done cumulatively to avoid accumulating - * roundoff errors. + * The calculation is done cumulatively to avoid accumulating roundoff + * errors. */ do { int prevMinOffset = layoutPtr[start - 1].minOffset; + prevGrow = 0; accWeight = 0; for (slot = start; slot <= end; slot++) { @@ -2180,10 +2190,11 @@ ResolveConstraints(masterPtr, slotType, maxOffset) ((prevMinOffset + layoutPtr[slot].minSize + grow) > layoutPtr[slot].maxOffset)) { int newHave; + /* - * There is not enough room to grow that much. - * Calculate how much this slot can grow and how much - * "have" that corresponds to. + * There is not enough room to grow that much. Calculate + * how much this slot can grow and how much "have" that + * corresponds to. */ grow = layoutPtr[slot].maxOffset - @@ -2191,36 +2202,43 @@ ResolveConstraints(masterPtr, slotType, maxOffset) newHave = grow * totalWeight / weight; if (newHave > totalWeight) { /* - * By distributing multiples of totalWeight - * we minimize rounding errors since they will - * only happen in the last loop(s). + * By distributing multiples of totalWeight we + * minimize rounding errors since they will only + * happen in the last loop(s). */ newHave = newHave / totalWeight * totalWeight; } if (newHave <= 0) { /* - * We can end up with a "have" of 0 here if - * the previous slots have taken all the space. - * In that case we cannot guess an appropriate - * "have" so we just try some lower "have" that - * is >= 1, to make sure this terminates. + * We can end up with a "have" of 0 here if the + * previous slots have taken all the space. In that + * case we cannot guess an appropriate "have" so we + * just try some lower "have" that is >= 1, to make + * sure this terminates. */ newHave = (have - need) - 1; if (newHave > (3 * totalWeight)) { - /* Go down 25% for large values */ + /* + * Go down 25% for large values. + */ newHave = newHave * 3 / 4; } + if (newHave > totalWeight) { - /* Round down to a multiple of totalWeight. */ + /* + * Round down to a multiple of totalWeight. + */ newHave = newHave / totalWeight * totalWeight; } + if (newHave <= 0) { newHave = 1; } } have = newHave + need; + /* * Restart loop to check if the new "have" will fit. */ @@ -2232,14 +2250,15 @@ ResolveConstraints(masterPtr, slotType, maxOffset) prevMinOffset = layoutPtr[slot].minOffset; } } + /* * Quit the outer loop if the inner loop ran all the way. */ } while (slot <= end); /* - * Now distribute the extra space among the slots by - * adjusting the minSizes and minOffsets. + * Now distribute the extra space among the slots by adjusting the + * minSizes and minOffsets. */ prevGrow = 0; @@ -2257,13 +2276,16 @@ ResolveConstraints(masterPtr, slotType, maxOffset) } /* - * Having pushed the top/left boundaries of the slots to - * take up extra space, the bottom/right space is recalculated - * to propagate the new space allocation. + * Having pushed the top/left boundaries of the slots to take up extra + * space, the bottom/right space is recalculated to propagate the new + * space allocation. */ for (slot = end; slot > start; slot--) { - /* maxOffset may not go up */ + /* + * maxOffset may not go up. + */ + if ((layoutPtr[slot].maxOffset-layoutPtr[slot].minSize) < layoutPtr[slot-1].maxOffset) { layoutPtr[slot-1].maxOffset = @@ -2274,8 +2296,8 @@ ResolveConstraints(masterPtr, slotType, maxOffset) /* * Step 6. - * All of the space has been apportioned; copy the - * layout information back into the master. + * All of the space has been apportioned; copy the layout information back + * into the master. */ for (slot=0; slot < gridCount; slot++) { @@ -2294,24 +2316,24 @@ ResolveConstraints(masterPtr, slotType, maxOffset) * * GetGrid -- * - * This internal procedure is used to locate a Grid structure for - * a given window, creating one if one doesn't exist already. + * This internal procedure is used to locate a Grid structure for a given + * window, creating one if one doesn't exist already. * * Results: - * The return value is a pointer to the Grid structure - * corresponding to tkwin. + * The return value is a pointer to the Grid structure corresponding to + * tkwin. * * Side effects: - * A new grid structure may be created. If so, then a callback - * is set up to clean things up when the window is deleted. + * A new grid structure may be created. If so, then a callback is set up + * to clean things up when the window is deleted. * *---------------------------------------------------------------------- */ static Gridder * GetGrid(tkwin) - Tk_Window tkwin; /* Token for window for which - * grid structure is desired. */ + Tk_Window tkwin; /* Token for window for which grid structure + * is desired. */ { register Gridder *gridPtr; Tcl_HashEntry *hPtr; @@ -2324,8 +2346,8 @@ GetGrid(tkwin) } /* - * See if there's already grid for this window. If not, - * then create a new one. + * See if there's already grid for this window. If not, then create a new + * one. */ hPtr = Tcl_CreateHashEntry(&dispPtr->gridHashTable, (char *) tkwin, &new); @@ -2368,25 +2390,24 @@ GetGrid(tkwin) * * SetGridSize -- * - * This internal procedure sets the size of the grid occupied - * by slaves. + * This internal procedure sets the size of the grid occupied by slaves. * * Results: - * none + * None * * Side effects: - * The width and height arguments are filled in the master data structure. - * Additional space is allocated for the constraints to accomodate - * the offsets. + * The width and height arguments are filled in the master data + * structure. Additional space is allocated for the constraints to + * accomodate the offsets. * *---------------------------------------------------------------------- */ static void SetGridSize(masterPtr) - Gridder *masterPtr; /* The geometry master for this grid. */ + Gridder *masterPtr; /* The geometry master for this grid. */ { - register Gridder *slavePtr; /* Current slave window. */ + register Gridder *slavePtr; /* Current slave window. */ int maxX = 0, maxY = 0; for (slavePtr = masterPtr->slavePtr; slavePtr != NULL; @@ -2405,30 +2426,30 @@ SetGridSize(masterPtr) * * CheckSlotData -- * - * This internal procedure is used to manage the storage for - * row and column (slot) constraints. + * This internal procedure is used to manage the storage for row and + * column (slot) constraints. * * Results: * TRUE if the index is OK, False otherwise. * * Side effects: - * A new master grid structure may be created. If so, then - * it is initialized. In addition, additional storage for - * a row or column constraints may be allocated, and the constraint - * maximums are adjusted. + * A new master grid structure may be created. If so, then it is + * initialized. In addition, additional storage for a row or column + * constraints may be allocated, and the constraint maximums are + * adjusted. * *---------------------------------------------------------------------- */ static int CheckSlotData(masterPtr, slot, slotType, checkOnly) - Gridder *masterPtr; /* the geometry master for this grid */ - int slot; /* which slot to look at */ - int slotType; /* ROW or COLUMN */ - int checkOnly; /* don't allocate new space if true */ + Gridder *masterPtr; /* The geometry master for this grid. */ + int slot; /* Which slot to look at. */ + int slotType; /* ROW or COLUMN. */ + int checkOnly; /* Don't allocate new space if true. */ { - int numSlot; /* number of slots already allocated (Space) */ - int end; /* last used constraint */ + int numSlot; /* Number of slots already allocated (Space) */ + int end; /* Last used constraint. */ /* * If slot is out of bounds, return immediately. @@ -2444,8 +2465,8 @@ CheckSlotData(masterPtr, slot, slotType, checkOnly) /* * If we need to allocate more space, allocate a little extra to avoid - * repeated re-alloc's for large tables. We need enough space to - * hold all of the offsets as well. + * repeated re-alloc's for large tables. We need enough space to hold all + * of the offsets as well. */ InitMasterData(masterPtr); @@ -2457,22 +2478,23 @@ CheckSlotData(masterPtr, slot, slotType, checkOnly) numSlot = (slotType == ROW) ? masterPtr->masterDataPtr->rowSpace : masterPtr->masterDataPtr->columnSpace; if (slot >= numSlot) { - int newNumSlot = slot + PREALLOC ; + int newNumSlot = slot + PREALLOC; size_t oldSize = numSlot * sizeof(SlotInfo); size_t newSize = newNumSlot * sizeof(SlotInfo); - SlotInfo *new = (SlotInfo *) ckalloc(newSize); - SlotInfo *old = (slotType == ROW) ? - masterPtr->masterDataPtr->rowPtr : - masterPtr->masterDataPtr->columnPtr; - memcpy((VOID *) new, (VOID *) old, oldSize ); - memset((VOID *) (new+numSlot), 0, newSize - oldSize ); - ckfree((char *) old); + SlotInfo *newSI = (SlotInfo *) ckalloc(newSize); + SlotInfo *oldSI = (slotType == ROW) + ? masterPtr->masterDataPtr->rowPtr + : masterPtr->masterDataPtr->columnPtr; + + memcpy((VOID *) newSI, (VOID *) oldSI, oldSize); + memset((VOID *) (newSI+numSlot), 0, newSize - oldSize); + ckfree((char *) oldSI); if (slotType == ROW) { - masterPtr->masterDataPtr->rowPtr = new ; - masterPtr->masterDataPtr->rowSpace = newNumSlot ; + masterPtr->masterDataPtr->rowPtr = newSI; + masterPtr->masterDataPtr->rowSpace = newNumSlot; } else { - masterPtr->masterDataPtr->columnPtr = new; - masterPtr->masterDataPtr->columnSpace = newNumSlot ; + masterPtr->masterDataPtr->columnPtr = newSI; + masterPtr->masterDataPtr->columnSpace = newNumSlotSI; } } if (slot >= end && checkOnly != CHECK_SPACE) { @@ -2491,16 +2513,15 @@ CheckSlotData(masterPtr, slot, slotType, checkOnly) * * InitMasterData -- * - * This internal procedure is used to allocate and initialize - * the data for a geometry master, if the data - * doesn't exist already. + * This internal procedure is used to allocate and initialize the data + * for a geometry master, if the data doesn't exist already. * * Results: * none * * Side effects: - * A new master grid structure may be created. If so, then - * it is initialized. + * A new master grid structure may be created. If so, then it is + * initialized. * *---------------------------------------------------------------------- */ @@ -2590,11 +2611,11 @@ Unlink(slavePtr) * * DestroyGrid -- * - * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release - * to clean up the internal structure of a grid at a safe time - * (when no-one is using it anymore). Cleaning up the grid involves - * freeing the main structure for all windows. and the master structure - * for geometry managers. + * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release to + * clean up the internal structure of a grid at a safe time (when no-one + * is using it anymore). Cleaning up the grid involves freeing the main + * structure for all windows and the master structure for geometry + * managers. * * Results: * None. @@ -2628,25 +2649,24 @@ DestroyGrid(memPtr) * * GridStructureProc -- * - * This procedure is invoked by the Tk event dispatcher in response - * to StructureNotify events. + * This procedure is invoked by the Tk event dispatcher in response to + * StructureNotify events. * * Results: * None. * * Side effects: * If a window was just deleted, clean up all its grid-related - * information. If it was just resized, re-configure its slaves, if - * any. + * information. If it was just resized, re-configure its slaves, if any. * *---------------------------------------------------------------------- */ static void GridStructureProc(clientData, eventPtr) - ClientData clientData; /* Our information about window - * referred to by eventPtr. */ - XEvent *eventPtr; /* Describes what just happened. */ + ClientData clientData; /* Our information about window referred to by + * eventPtr. */ + XEvent *eventPtr; /* Describes what just happened. */ { register Gridder *gridPtr = (Gridder *) clientData; TkDisplay *dispPtr = ((TkWindow *) gridPtr->tkwin)->dispPtr; @@ -2657,8 +2677,8 @@ GridStructureProc(clientData, eventPtr) gridPtr->flags |= REQUESTED_RELAYOUT; Tcl_DoWhenIdle(ArrangeGrid, (ClientData) gridPtr); } - if ((gridPtr->masterPtr != NULL) - && (gridPtr->doubleBw != 2*Tk_Changes(gridPtr->tkwin)->border_width)) { + if ((gridPtr->masterPtr != NULL) && + (gridPtr->doubleBw != 2*Tk_Changes(gridPtr->tkwin)->border_width)) { if (!(gridPtr->masterPtr->flags & REQUESTED_RELAYOUT)) { gridPtr->doubleBw = 2*Tk_Changes(gridPtr->tkwin)->border_width; gridPtr->masterPtr->flags |= REQUESTED_RELAYOUT; @@ -2706,15 +2726,14 @@ GridStructureProc(clientData, eventPtr) * * ConfigureSlaves -- * - * This implements the guts of the "grid configure" command. Given - * a list of slaves and configuration options, it arranges for the - * grid to manage the slaves and sets the specified options. - * arguments consist of windows or window shortcuts followed by - * "-option value" pairs. + * This implements the guts of the "grid configure" command. Given a list + * of slaves and configuration options, it arranges for the grid to + * manage the slaves and sets the specified options. Arguments consist + * of windows or window shortcuts followed by "-option value" pairs. * * Results: - * TCL_OK is returned if all went well. Otherwise, TCL_ERROR is - * returned and the interp's result is set to contain an error message. + * TCL_OK is returned if all went well. Otherwise, TCL_ERROR is returned + * and the interp's result is set to contain an error message. * * Side effects: * Slave windows get taken over by the grid. @@ -2726,27 +2745,25 @@ static int ConfigureSlaves(interp, tkwin, objc, objv) Tcl_Interp *interp; /* Interpreter for error reporting. */ Tk_Window tkwin; /* Any window in application containing - * slaves. Used to look up slave names. */ + * slaves. Used to look up slave names. */ int objc; /* Number of elements in argv. */ Tcl_Obj *CONST objv[]; /* Argument objects: contains one or more - * window names followed by any number - * of "option value" pairs. Caller must - * make sure that there is at least one - * window name. */ + * window names followed by any number of + * "option value" pairs. Caller must make sure + * that there is at least one window name. */ { Gridder *masterPtr = NULL; Gridder *slavePtr; Tk_Window other, slave, parent, ancestor; int i, j, tmp; - int length; int numWindows; int width; int defaultRow = -1; - int defaultColumn = 0; /* default column number */ - int defaultColumnSpan = 1; /* default number of columns */ - char *lastWindow; /* use this window to base current - * Row/col on */ - int numSkip; /* number of 'x' found */ + int defaultColumn = 0; /* Default column number */ + int defaultColumnSpan = 1; /* Default number of columns */ + char *lastWindow; /* Use this window to base current row/col + * on */ + int numSkip; /* Number of 'x' found */ static CONST char *optionStrings[] = { "-column", "-columnspan", "-in", "-ipadx", "-ipady", "-padx", "-pady", "-row", "-rowspan", "-sticky", (char *) NULL @@ -2756,7 +2773,7 @@ ConfigureSlaves(interp, tkwin, objc, objv) CONF_PADX, CONF_PADY, CONF_ROW, CONF_ROWSPAN, CONF_STICKY }; int index; char *string; - char firstChar, prevChar; + char firstChar; int positionGiven; /* @@ -2765,8 +2782,10 @@ ConfigureSlaves(interp, tkwin, objc, objv) firstChar = 0; for (numWindows=0, i=0; i < objc; i++) { - prevChar = firstChar; - string = Tcl_GetStringFromObj(objv[i], (int *) &length); + int length; + char prevChar = firstChar; + + string = Tcl_GetStringFromObj(objv[i], &length); firstChar = string[0]; if (firstChar == '.') { @@ -2774,6 +2793,7 @@ ConfigureSlaves(interp, tkwin, objc, objv) * Check that windows are valid, and locate the first slave's * parent window (default for -in). */ + if (TkGetWindowFromObj(interp, tkwin, objv[i], &slave) != TCL_OK) { return TCL_ERROR; } @@ -2828,12 +2848,11 @@ ConfigureSlaves(interp, tkwin, objc, objv) } /* - * Go through all options looking for -in and -row, which are needed to - * be found first to handle the special case where ^ is used on a row - * without windows names, but with an -in option. - * Since all options are checked here, we do not need to handle the - * error case again later. - */ + * Go through all options looking for -in and -row, which are needed to be + * found first to handle the special case where ^ is used on a row without + * windows names, but with an -in option. Since all options are checked + * here, we do not need to handle the error case again later. + */ for (i = numWindows; i < objc; i += 2) { if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0, @@ -2860,7 +2879,10 @@ ConfigureSlaves(interp, tkwin, objc, objv) } } - /* If no -row is given, use the first unoccupied row of the master. */ + /* + * If no -row is given, use the first unoccupied row of the master. + */ + if (defaultRow < 0) { if (masterPtr != NULL && masterPtr->masterDataPtr != NULL) { SetGridSize(masterPtr); @@ -2871,14 +2893,13 @@ ConfigureSlaves(interp, tkwin, objc, objv) } /* - * Iterate over all of the slave windows and short-cuts, parsing - * options for each slave. It's a bit wasteful to re-parse the - * options for each slave, but things get too messy if we try to - * parse the arguments just once at the beginning. For example, - * if a slave already is managed we want to just change a few - * existing values without resetting everything. If there are - * multiple windows, the -in option only gets processed for the - * first window. + * Iterate over all of the slave windows and short-cuts, parsing options + * for each slave. It's a bit wasteful to re-parse the options for each + * slave, but things get too messy if we try to parse the arguments just + * once at the beginning. For example, if a slave already is managed we + * want to just change a few existing values without resetting everything. + * If there are multiple windows, the -in option only gets processed for + * the first window. */ positionGiven = 0; @@ -2887,8 +2908,8 @@ ConfigureSlaves(interp, tkwin, objc, objv) firstChar = string[0]; /* - * '^' and 'x' cause us to skip a column. '-' is processed - * as part of its preceeding slave. + * '^' and 'x' cause us to skip a column. '-' is processed as part of + * its preceeding slave. */ if ((firstChar == REL_VERT) || (firstChar == REL_SKIP)) { @@ -2922,43 +2943,44 @@ ConfigureSlaves(interp, tkwin, objc, objv) * The following statement is taken from tkPack.c: * * "If the slave isn't currently managed, reset all of its - * configuration information to default values (there could - * be old values left from a previous packer)." + * configuration information to default values (there could be old + * values left from a previous packer)." * - * I [D.S.] disagree with this statement. If a slave is disabled (using - * "forget") and then re-enabled, I submit that 90% of the time the - * programmer will want it to retain its old configuration information. - * If the programmer doesn't want this behavior, then the + * I [D.S.] disagree with this statement. If a slave is disabled + * (using "forget") and then re-enabled, I submit that 90% of the time + * the programmer will want it to retain its old configuration + * information. If the programmer doesn't want this behavior, then the * defaults can be reestablished by hand, without having to worry * about keeping track of the old state. */ for (i = numWindows; i < objc; i += 2) { - Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0, + Tcl_GetIndexFromObj(interp, objv[i], optionStrings, "option", 0, &index); - if (index == CONF_COLUMN) { - if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK || - tmp < 0) { - Tcl_ResetResult(interp); + switch ((enum options) index) { + case CONF_COLUMN: + if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK + || tmp < 0) { Tcl_AppendResult(interp, "bad column value \"", Tcl_GetString(objv[i+1]), "\": must be a non-negative integer", (char *)NULL); return TCL_ERROR; } slavePtr->column = tmp; - } else if (index == CONF_COLUMNSPAN) { - if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK || - tmp <= 0) { - Tcl_ResetResult(interp); + break; + case CONF_COLUMNSPAN: + if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK + || tmp <= 0) { Tcl_AppendResult(interp, "bad columnspan value \"", Tcl_GetString(objv[i+1]), "\": must be a positive integer", (char *)NULL); return TCL_ERROR; } slavePtr->numCols = tmp; - } else if (index == CONF_IN) { - if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) != - TCL_OK) { + break; + case CONF_IN: + if (TkGetWindowFromObj(interp, tkwin, objv[i+1], + &other) != TCL_OK) { return TCL_ERROR; } if (other == slave) { @@ -2969,10 +2991,23 @@ ConfigureSlaves(interp, tkwin, objc, objv) positionGiven = 1; masterPtr = GetGrid(other); InitMasterData(masterPtr); - } else if (index == CONF_IPADX) { - if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp) - != TCL_OK) || (tmp < 0)) { - Tcl_ResetResult(interp); + break; + case CONF_STICKY: { + int sticky = StringToSticky(Tcl_GetString(objv[i+1])); + + if (sticky == -1) { + Tcl_AppendResult(interp, "bad stickyness value \"", + Tcl_GetString(objv[i+1]), + "\": must be a string containing n, e, s, and/or w", + (char *)NULL); + return TCL_ERROR; + } + slavePtr->sticky = sticky; + break; + } + case CONF_IPADX: + if ((Tk_GetPixelsFromObj(NULL, slave, objv[i+1], + &tmp) != TCL_OK) || (tmp < 0)) { Tcl_AppendResult(interp, "bad ipadx value \"", Tcl_GetString(objv[i+1]), "\": must be positive screen distance", @@ -2980,10 +3015,10 @@ ConfigureSlaves(interp, tkwin, objc, objv) return TCL_ERROR; } slavePtr->iPadX = tmp*2; - } else if (index == CONF_IPADY) { - if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp) - != TCL_OK) || (tmp < 0)) { - Tcl_ResetResult(interp); + break; + case CONF_IPADY: + if ((Tk_GetPixelsFromObj(NULL, slave, objv[i+1], + &tmp) != TCL_OK) || (tmp < 0)) { Tcl_AppendResult(interp, "bad ipady value \"", Tcl_GetString(objv[i+1]), "\": must be positive screen distance", @@ -2991,52 +3026,46 @@ ConfigureSlaves(interp, tkwin, objc, objv) return TCL_ERROR; } slavePtr->iPadY = tmp*2; - } else if (index == CONF_PADX) { + break; + case CONF_PADX: if (TkParsePadAmount(interp, tkwin, objv[i+1], &slavePtr->padLeft, &slavePtr->padX) != TCL_OK) { return TCL_ERROR; } - } else if (index == CONF_PADY) { + break; + case CONF_PADY: if (TkParsePadAmount(interp, tkwin, objv[i+1], &slavePtr->padTop, &slavePtr->padY) != TCL_OK) { return TCL_ERROR; } - } else if (index == CONF_ROW) { - if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK + break; + case CONF_ROW: + if (Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK || tmp < 0) { - Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad row value \"", Tcl_GetString(objv[i+1]), - "\": must be a non-negative integer", (char *)NULL); + "\": must be a non-negative integer", + (char *) NULL); return TCL_ERROR; } slavePtr->row = tmp; - } else if (index == CONF_ROWSPAN) { - if ((Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) + break; + case CONF_ROWSPAN: + if ((Tcl_GetIntFromObj(NULL, objv[i+1], &tmp) != TCL_OK) || tmp <= 0) { - Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad rowspan value \"", Tcl_GetString(objv[i+1]), - "\": must be a positive integer", (char *)NULL); + "\": must be a positive integer", (char *) NULL); return TCL_ERROR; } slavePtr->numRows = tmp; - } else if (index == CONF_STICKY) { - int sticky = StringToSticky(Tcl_GetString(objv[i+1])); - if (sticky == -1) { - Tcl_AppendResult(interp, "bad stickyness value \"", - Tcl_GetString(objv[i+1]), - "\": must be a string containing n, e, s, and/or w", - (char *)NULL); - return TCL_ERROR; - } - slavePtr->sticky = sticky; + break; } } /* - * If no position was specified via -in and the slave is - * already packed, then leave it in its current location. + * If no position was specified via -in and the slave is already + * packed, then leave it in its current location. */ if (!positionGiven && (slavePtr->masterPtr != NULL)) { @@ -3045,8 +3074,8 @@ ConfigureSlaves(interp, tkwin, objc, objv) } /* - * If the same -in window is passed in again, then just - * leave it in its current location. + * If the same -in window is passed in again, then just leave it in + * its current location. */ if (positionGiven && (masterPtr == slavePtr->masterPtr)) { @@ -3054,7 +3083,7 @@ ConfigureSlaves(interp, tkwin, objc, objv) } /* - * Make sure we have a geometry master. We look at: + * Make sure we have a geometry master. We look at: * 1) the -in flag * 2) the parent of the first slave. */ @@ -3078,9 +3107,9 @@ ConfigureSlaves(interp, tkwin, objc, objv) } /* - * Make sure that the slave's parent is either the master or - * an ancestor of the master, and that the master and slave - * aren't the same. + * Make sure that the slave's parent is either the master or an + * ancestor of the master, and that the master and slave aren't the + * same. */ for (ancestor = masterPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) { @@ -3125,11 +3154,10 @@ ConfigureSlaves(interp, tkwin, objc, objv) defaultColumnSpan = 1; /* - * Arrange for the master to be re-arranged at the first - * idle moment. + * Arrange for the master to be re-arranged at the first idle moment. */ - scheduleLayout: + scheduleLayout: if (masterPtr->abortPtr != NULL) { *masterPtr->abortPtr = 1; } @@ -3139,7 +3167,9 @@ ConfigureSlaves(interp, tkwin, objc, objv) } } - /* Now look for all the "^"'s. */ + /* + * Now look for all the "^"'s. + */ lastWindow = NULL; numSkip = 0; @@ -3168,9 +3198,13 @@ ConfigureSlaves(interp, tkwin, objc, objv) return TCL_ERROR; } - /* Count the number of consecutive ^'s starting from this position */ + /* + * Count the number of consecutive ^'s starting from this position. + */ + for (width = 1; width + j < numWindows; width++) { char *string = Tcl_GetString(objv[j+width]); + if (*string != REL_VERT) { break; } @@ -3229,8 +3263,8 @@ ConfigureSlaves(interp, tkwin, objc, objv) * * StickyToString * - * Converts the internal boolean combination of "sticky" bits onto - * a TCL list element containing zero or mor of n, s, e, or w. + * Converts the internal boolean combination of "sticky" bits onto a Tcl + * list element containing zero or more of n, s, e, or w. * * Results: * A string is placed into the "result" pointer. @@ -3243,8 +3277,8 @@ ConfigureSlaves(interp, tkwin, objc, objv) static void StickyToString(flags, result) - int flags; /* the sticky flags */ - char *result; /* where to put the result */ + int flags; /* The sticky flags. */ + char *result; /* Where to put the result. */ { int count = 0; if (flags&STICK_NORTH) { @@ -3271,12 +3305,12 @@ StickyToString(flags, result) * * StringToSticky -- * - * Converts an ascii string representing a widgets stickyness - * into the boolean result. + * Converts an ascii string representing a widgets stickyness into the + * boolean result. * * Results: - * The boolean combination of the "sticky" bits is retuned. If an - * error occurs, such as an invalid character, -1 is returned instead. + * The boolean combination of the "sticky" bits is retuned. If an error + * occurs, such as an invalid character, -1 is returned instead. * * Side effects: * none @@ -3293,12 +3327,22 @@ StringToSticky(string) while ((c = *string++) != '\0') { switch (c) { - case 'n': case 'N': sticky |= STICK_NORTH; break; - case 'e': case 'E': sticky |= STICK_EAST; break; - case 's': case 'S': sticky |= STICK_SOUTH; break; - case 'w': case 'W': sticky |= STICK_WEST; break; - case ' ': case ',': case '\t': case '\r': case '\n': break; - default: return -1; + case 'n': case 'N': + sticky |= STICK_NORTH; + break; + case 'e': case 'E': + sticky |= STICK_EAST; + break; + case 's': case 'S': + sticky |= STICK_SOUTH; + break; + case 'w': case 'W': + sticky |= STICK_WEST; + break; + case ' ': case ',': case '\t': case '\r': case '\n': + break; + default: + return -1; } } return sticky; @@ -3321,14 +3365,14 @@ StringToSticky(string) */ static Tcl_Obj * -NewPairObj(interp, val1, val2) - Tcl_Interp *interp; /* Current interpreter. */ +NewPairObj(val1, val2) int val1, val2; { - Tcl_Obj *res = Tcl_NewListObj(0, NULL); - Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(val1)); - Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(val2)); - return res; + Tcl_Obj *ary[2]; + + ary[0] = Tcl_NewIntObj(val1); + ary[1] = Tcl_NewIntObj(val2); + return Tcl_NewListObj(2, ary); } /* @@ -3348,14 +3392,22 @@ NewPairObj(interp, val1, val2) */ static Tcl_Obj * -NewQuadObj(interp, val1, val2, val3, val4) - Tcl_Interp *interp; /* Current interpreter. */ +NewQuadObj(val1, val2, val3, val4) int val1, val2, val3, val4; { - Tcl_Obj *res = Tcl_NewListObj(0, NULL); - Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(val1)); - Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(val2)); - Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(val3)); - Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(val4)); - return res; + Tcl_Obj *ary[4]; + + ary[0] = Tcl_NewIntObj(val1); + ary[1] = Tcl_NewIntObj(val2); + ary[2] = Tcl_NewIntObj(val3); + ary[3] = Tcl_NewIntObj(val4); + return Tcl_NewListObj(4, ary); } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkImage.c b/generic/tkImage.c index 476662b..570d39f 100644 --- a/generic/tkImage.c +++ b/generic/tkImage.c @@ -1,17 +1,16 @@ -/* +/* * tkImage.c -- * - * This module implements the image protocol, which allows lots - * of different kinds of images to be used in lots of different - * widgets. + * This module implements the image protocol, which allows lots of + * different kinds of images to be used in lots of different widgets. * * Copyright (c) 1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkImage.c,v 1.22 2003/09/17 23:45:35 dgp Exp $ + * RCS: @(#) $Id: tkImage.c,v 1.23 2005/08/10 22:02:22 dkf Exp $ */ #include "tkInt.h" @@ -27,96 +26,93 @@ typedef struct Image { Tk_Window tkwin; /* Window passed to Tk_GetImage (needed to * "re-get" the image later if the manager * changes). */ - Display *display; /* Display for tkwin. Needed because when - * the image is eventually freed tkwin may - * not exist anymore. */ + Display *display; /* Display for tkwin. Needed because when the + * image is eventually freed tkwin may not + * exist anymore. */ struct ImageMaster *masterPtr; /* Master for this image (identifiers image * manager, for example). */ - ClientData instanceData; - /* One word argument to pass to image manager + ClientData instanceData; /* One word argument to pass to image manager * when dealing with this image instance. */ Tk_ImageChangedProc *changeProc; /* Code in widget to call when image changes * in a way that affects redisplay. */ - ClientData widgetClientData; - /* Argument to pass to changeProc. */ + ClientData widgetClientData;/* Argument to pass to changeProc. */ struct Image *nextPtr; /* Next in list of all image instances * associated with the same name. */ - } Image; /* - * For each image master there is one of the following structures, - * which represents a name in the image table and all of the images - * instantiated from it. Entries in mainPtr->imageTable point to - * these structures. + * For each image master there is one of the following structures, which + * represents a name in the image table and all of the images instantiated + * from it. Entries in mainPtr->imageTable point to these structures. */ typedef struct ImageMaster { - Tk_ImageType *typePtr; /* Information about image type. NULL means - * that no image manager owns this image: the + Tk_ImageType *typePtr; /* Information about image type. NULL means + * that no image manager owns this image: the * image was deleted. */ - ClientData masterData; /* One-word argument to pass to image mgr - * when dealing with the master, as opposed - * to instances. */ + ClientData masterData; /* One-word argument to pass to image mgr when + * dealing with the master, as opposed to + * instances. */ int width, height; /* Last known dimensions for image. */ - Tcl_HashTable *tablePtr; /* Pointer to hash table containing image - * (the imageTable field in some TkMainInfo + Tcl_HashTable *tablePtr; /* Pointer to hash table containing image (the + * imageTable field in some TkMainInfo * structure). */ - Tcl_HashEntry *hPtr; /* Hash entry in mainPtr->imageTable for - * this structure (used to delete the hash + Tcl_HashEntry *hPtr; /* Hash entry in mainPtr->imageTable for this + * structure (used to delete the hash * entry). */ Image *instancePtr; /* Pointer to first in list of instances * derived from this name. */ int deleted; /* Flag set when image is being deleted. */ - TkWindow *winPtr; /* Main window of interpreter (used to - * detect when the world is falling apart.) */ + TkWindow *winPtr; /* Main window of interpreter (used to detect + * when the world is falling apart.) */ } ImageMaster; typedef struct ThreadSpecificData { - Tk_ImageType *imageTypeList;/* First in a list of all known image - * types. */ - Tk_ImageType *oldImageTypeList;/* First in a list of all known old-style image - * types. */ -} ThreadSpecificData; + Tk_ImageType *imageTypeList;/* First in a list of all known image + * types. */ + Tk_ImageType *oldImageTypeList; + /* First in a list of all known old-style + * image types. */ +} ThreadSpecificData; static Tcl_ThreadDataKey dataKey; /* - * Prototypes for local procedures: + * Prototypes for local functions: */ -static void DeleteImage _ANSI_ARGS_((ImageMaster *masterPtr)); -static void EventuallyDeleteImage _ANSI_ARGS_((ImageMaster *masterPtr, - int forgetImageHashNow)); +static void DeleteImage(ImageMaster *masterPtr); +static void EventuallyDeleteImage(ImageMaster *masterPtr, + int forgetImageHashNow); /* *---------------------------------------------------------------------- * * Tk_CreateOldImageType, Tk_CreateImageType -- * - * This procedure is invoked by an image manager to tell Tk about - * a new kind of image and the procedures that manage the new type. - * The procedure is typically invoked during Tcl_AppInit. + * This function is invoked by an image manager to tell Tk about a new + * kind of image and the functions that manage the new type. The function + * is typically invoked during Tcl_AppInit. * * Results: * None. * * Side effects: - * The new image type is entered into a table used in the "image - * create" command. + * The new image type is entered into a table used in the "image create" + * command. * *---------------------------------------------------------------------- */ void Tk_CreateOldImageType(typePtr) - Tk_ImageType *typePtr; /* Structure describing the type. All of - * the fields except "nextPtr" must be filled - * in by caller. Must not have been passed - * to Tk_CreateImageType previously. */ + Tk_ImageType *typePtr; /* Structure describing the type. All of the + * fields except "nextPtr" must be filled in + * by caller. Must not have been passed to + * Tk_CreateImageType previously. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); typePtr->nextPtr = tsdPtr->oldImageTypeList; @@ -125,12 +121,12 @@ Tk_CreateOldImageType(typePtr) void Tk_CreateImageType(typePtr) - Tk_ImageType *typePtr; /* Structure describing the type. All of - * the fields except "nextPtr" must be filled - * in by caller. Must not have been passed - * to Tk_CreateImageType previously. */ + Tk_ImageType *typePtr; /* Structure describing the type. All of the + * fields except "nextPtr" must be filled in + * by caller. Must not have been passed to + * Tk_CreateImageType previously. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); typePtr->nextPtr = tsdPtr->imageTypeList; @@ -142,8 +138,8 @@ Tk_CreateImageType(typePtr) * * Tk_ImageObjCmd -- * - * This procedure is invoked to process the "image" Tcl command. - * See the user documentation for details on what it does. + * This function is invoked to process the "image" Tcl command. See the + * user documentation for details on what it does. * * Results: * A standard Tcl result. @@ -163,7 +159,7 @@ Tk_ImageObjCmd(clientData, interp, objc, objv) { static CONST char *imageOptions[] = { "create", "delete", "height", "inuse", "names", "type", "types", - "width", (char *) NULL + "width", (char *) NULL }; enum options { IMAGE_CREATE, IMAGE_DELETE, IMAGE_HEIGHT, IMAGE_INUSE, IMAGE_NAMES, @@ -178,7 +174,8 @@ Tk_ImageObjCmd(clientData, interp, objc, objv) Tcl_HashSearch search; char idString[16 + TCL_INTEGER_SPACE], *name; TkDisplay *dispPtr = winPtr->dispPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + CONST char *arg; + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (objc < 2) { @@ -191,302 +188,254 @@ Tk_ImageObjCmd(clientData, interp, objc, objv) return TCL_ERROR; } switch ((enum options) index) { - case IMAGE_CREATE: { - char *arg; - Tcl_Obj **args; - int oldimage = 0; - if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "type ?name? ?options?"); - return TCL_ERROR; - } + case IMAGE_CREATE: { + Tcl_Obj **args; + int oldimage = 0; + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "type ?name? ?options?"); + return TCL_ERROR; + } - /* - * Look up the image type. - */ + /* + * Look up the image type. + */ - arg = Tcl_GetString(objv[2]); - for (typePtr = tsdPtr->imageTypeList; typePtr != NULL; - typePtr = typePtr->nextPtr) { + arg = Tcl_GetString(objv[2]); + for (typePtr = tsdPtr->imageTypeList; typePtr != NULL; + typePtr = typePtr->nextPtr) { + if ((*arg == typePtr->name[0]) + && (strcmp(arg, typePtr->name) == 0)) { + break; + } + } + if (typePtr == NULL) { + oldimage = 1; + for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL; + typePtr = typePtr->nextPtr) { if ((*arg == typePtr->name[0]) && (strcmp(arg, typePtr->name) == 0)) { break; } } - if (typePtr == NULL) { - oldimage = 1; - for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL; - typePtr = typePtr->nextPtr) { - if ((*arg == typePtr->name[0]) - && (strcmp(arg, typePtr->name) == 0)) { - break; - } - } - } - if (typePtr == NULL) { - Tcl_AppendResult(interp, "image type \"", arg, - "\" doesn't exist", (char *) NULL); - return TCL_ERROR; - } + } + if (typePtr == NULL) { + Tcl_AppendResult(interp, "image type \"", arg, "\" doesn't exist", + (char *) NULL); + return TCL_ERROR; + } - /* - * Figure out a name to use for the new image. - */ + /* + * Figure out a name to use for the new image. + */ - if ((objc == 3) || (*(arg = Tcl_GetString(objv[3])) == '-')) { - Tcl_CmdInfo dummy; - do { - dispPtr->imageId++; - sprintf(idString, "image%d", dispPtr->imageId); - name = idString; - } while (Tcl_GetCommandInfo(interp, name, &dummy) != 0); - firstOption = 3; - } else { - TkWindow *topWin; - - name = arg; - firstOption = 4; - /* - * Need to check if the _command_ that we are about to - * create is the name of the current master widget - * command (normally "." but could have been renamed) - * and fail in that case before a really nasty and - * hard to stop crash happens. - */ - topWin = (TkWindow *) TkToplevelWindowForCommand(interp, name); - if (topWin != NULL && winPtr->mainPtr->winPtr == topWin) { - Tcl_AppendResult(interp, "images may not be named the ", - "same as the main window", (char *) NULL); - return TCL_ERROR; - } - } + if ((objc == 3) || (*(arg = Tcl_GetString(objv[3])) == '-')) { + Tcl_CmdInfo dummy; + do { + dispPtr->imageId++; + sprintf(idString, "image%d", dispPtr->imageId); + name = idString; + } while (Tcl_GetCommandInfo(interp, name, &dummy) != 0); + firstOption = 3; + } else { + TkWindow *topWin; + + name = arg; + firstOption = 4; /* - * Create the data structure for the new image. + * Need to check if the _command_ that we are about to create is + * the name of the current master widget command (normally "." but + * could have been renamed) and fail in that case before a really + * nasty and hard to stop crash happens. */ - hPtr = Tcl_CreateHashEntry(&winPtr->mainPtr->imageTable, - name, &new); - if (new) { - masterPtr = (ImageMaster *) ckalloc(sizeof(ImageMaster)); - masterPtr->typePtr = NULL; - masterPtr->masterData = NULL; - masterPtr->width = masterPtr->height = 1; - masterPtr->tablePtr = &winPtr->mainPtr->imageTable; - masterPtr->hPtr = hPtr; - masterPtr->instancePtr = NULL; - masterPtr->deleted = 0; - masterPtr->winPtr = winPtr->mainPtr->winPtr; - Tcl_Preserve((ClientData) masterPtr->winPtr); - Tcl_SetHashValue(hPtr, masterPtr); - } else { - /* - * An image already exists by this name. Disconnect the - * instances from the master. - */ - - masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); - if (masterPtr->typePtr != NULL) { - for (imagePtr = masterPtr->instancePtr; imagePtr != NULL; - imagePtr = imagePtr->nextPtr) { - (*masterPtr->typePtr->freeProc)( - imagePtr->instanceData, imagePtr->display); - (*imagePtr->changeProc)(imagePtr->widgetClientData, - 0, 0, masterPtr->width, masterPtr->height, - masterPtr->width, masterPtr->height); - } - (*masterPtr->typePtr->deleteProc)(masterPtr->masterData); - masterPtr->typePtr = NULL; - } - masterPtr->deleted = 0; + topWin = (TkWindow *) TkToplevelWindowForCommand(interp, name); + if (topWin != NULL && winPtr->mainPtr->winPtr == topWin) { + Tcl_AppendResult(interp, "images may not be named the ", + "same as the main window", (char *) NULL); + return TCL_ERROR; } + } + /* + * Create the data structure for the new image. + */ + + hPtr = Tcl_CreateHashEntry(&winPtr->mainPtr->imageTable, name, &new); + if (new) { + masterPtr = (ImageMaster *) ckalloc(sizeof(ImageMaster)); + masterPtr->typePtr = NULL; + masterPtr->masterData = NULL; + masterPtr->width = masterPtr->height = 1; + masterPtr->tablePtr = &winPtr->mainPtr->imageTable; + masterPtr->hPtr = hPtr; + masterPtr->instancePtr = NULL; + masterPtr->deleted = 0; + masterPtr->winPtr = winPtr->mainPtr->winPtr; + Tcl_Preserve((ClientData) masterPtr->winPtr); + Tcl_SetHashValue(hPtr, masterPtr); + } else { /* - * Call the image type manager so that it can perform its own - * initialization, then re-"get" for any existing instances of - * the image. + * An image already exists by this name. Disconnect the instances + * from the master. */ - objv += firstOption; - objc -= firstOption; - args = (Tcl_Obj **) objv; - if (oldimage) { - int i; - args = (Tcl_Obj **) ckalloc((objc+1) * sizeof(char *)); - for (i = 0; i < objc; i++) { - args[i] = (Tcl_Obj *) Tcl_GetString(objv[i]); + masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); + if (masterPtr->typePtr != NULL) { + for (imagePtr = masterPtr->instancePtr; imagePtr != NULL; + imagePtr = imagePtr->nextPtr) { + (*masterPtr->typePtr->freeProc)(imagePtr->instanceData, + imagePtr->display); + (*imagePtr->changeProc)(imagePtr->widgetClientData, + 0, 0, masterPtr->width, masterPtr->height, + masterPtr->width, masterPtr->height); } - args[objc] = NULL; + (*masterPtr->typePtr->deleteProc)(masterPtr->masterData); + masterPtr->typePtr = NULL; } - Tcl_Preserve((ClientData) masterPtr); - if ((*typePtr->createProc)(interp, name, objc, - args, typePtr, (Tk_ImageMaster) masterPtr, - &masterPtr->masterData) != TCL_OK) { - EventuallyDeleteImage(masterPtr, 0); - Tcl_Release((ClientData) masterPtr); - if (oldimage) { - ckfree((char *) args); - } - return TCL_ERROR; + masterPtr->deleted = 0; + } + + /* + * Call the image type manager so that it can perform its own + * initialization, then re-"get" for any existing instances of the + * image. + */ + + objv += firstOption; + objc -= firstOption; + args = (Tcl_Obj **) objv; + if (oldimage) { + int i; + + args = (Tcl_Obj **) ckalloc((objc+1) * sizeof(char *)); + for (i = 0; i < objc; i++) { + args[i] = (Tcl_Obj *) Tcl_GetString(objv[i]); } + args[objc] = NULL; + } + Tcl_Preserve((ClientData) masterPtr); + if ((*typePtr->createProc)(interp, name, objc, args, typePtr, + (Tk_ImageMaster)masterPtr, &masterPtr->masterData) != TCL_OK) { + EventuallyDeleteImage(masterPtr, 0); Tcl_Release((ClientData) masterPtr); if (oldimage) { ckfree((char *) args); } - masterPtr->typePtr = typePtr; - for (imagePtr = masterPtr->instancePtr; imagePtr != NULL; - imagePtr = imagePtr->nextPtr) { - imagePtr->instanceData = (*typePtr->getProc)( - imagePtr->tkwin, masterPtr->masterData); - } - Tcl_SetResult(interp, - Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), - TCL_STATIC); - break; + return TCL_ERROR; } - case IMAGE_DELETE: { - for (i = 2; i < objc; i++) { - char *arg = Tcl_GetString(objv[i]); - hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg); - if (hPtr == NULL) { - deleteAlreadyDeleted: - Tcl_AppendResult(interp, "image \"", arg, - "\" doesn't exist", (char *) NULL); - return TCL_ERROR; - } - masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); - if (masterPtr->deleted) { - goto deleteAlreadyDeleted; - } - DeleteImage(masterPtr); - } - break; + Tcl_Release((ClientData) masterPtr); + if (oldimage) { + ckfree((char *) args); } - case IMAGE_HEIGHT: { - char *arg; - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "name"); - return TCL_ERROR; - } - arg = Tcl_GetString(objv[2]); + masterPtr->typePtr = typePtr; + for (imagePtr = masterPtr->instancePtr; imagePtr != NULL; + imagePtr = imagePtr->nextPtr) { + imagePtr->instanceData = (*typePtr->getProc)(imagePtr->tkwin, + masterPtr->masterData); + } + Tcl_SetResult(interp, + Tcl_GetHashKey(&winPtr->mainPtr->imageTable, hPtr), + TCL_STATIC); + break; + } + case IMAGE_DELETE: + for (i = 2; i < objc; i++) { + arg = Tcl_GetString(objv[i]); hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg); if (hPtr == NULL) { - heightAlreadyDeleted: - Tcl_AppendResult(interp, "image \"", arg, - "\" doesn't exist", (char *) NULL); - return TCL_ERROR; + goto alreadyDeleted; } masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); if (masterPtr->deleted) { - goto heightAlreadyDeleted; + goto alreadyDeleted; } - Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->height); - break; + DeleteImage(masterPtr); } - - case IMAGE_INUSE: { - int count = 0; - char *arg; - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "name"); - return TCL_ERROR; - } - arg = Tcl_GetString(objv[2]); - hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg); - if (hPtr == NULL) { - inuseAlreadyDeleted: - Tcl_AppendResult(interp, "image \"", arg, - "\" doesn't exist", (char *) NULL); - return TCL_ERROR; - } + break; + case IMAGE_NAMES: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, NULL); + return TCL_ERROR; + } + hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search); + for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); if (masterPtr->deleted) { - goto inuseAlreadyDeleted; + continue; } - if (masterPtr->typePtr != NULL && masterPtr->instancePtr != NULL) { - count = 1; - } - Tcl_SetBooleanObj(Tcl_GetObjResult(interp), count); - break; + Tcl_AppendElement(interp, Tcl_GetHashKey( + &winPtr->mainPtr->imageTable, hPtr)); + } + break; + case IMAGE_TYPES: + if (objc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, NULL); + return TCL_ERROR; + } + for (typePtr = tsdPtr->imageTypeList; typePtr != NULL; + typePtr = typePtr->nextPtr) { + Tcl_AppendElement(interp, typePtr->name); + } + for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL; + typePtr = typePtr->nextPtr) { + Tcl_AppendElement(interp, typePtr->name); } + break; - case IMAGE_NAMES: { - if (objc != 2) { - Tcl_WrongNumArgs(interp, 2, objv, NULL); - return TCL_ERROR; - } - hPtr = Tcl_FirstHashEntry(&winPtr->mainPtr->imageTable, &search); - for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); - if (masterPtr->deleted) { - continue; - } - Tcl_AppendElement(interp, Tcl_GetHashKey( - &winPtr->mainPtr->imageTable, hPtr)); - } - break; + case IMAGE_HEIGHT: + case IMAGE_INUSE: + case IMAGE_TYPE: + case IMAGE_WIDTH: + /* + * These operations all parse virtually identically. First check to + * see if three args are given. Then get a non-deleted master from the + * third arg. + */ + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "name"); + return TCL_ERROR; } - - case IMAGE_TYPE: { - char *arg; - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "name"); - return TCL_ERROR; - } - arg = Tcl_GetString(objv[2]); - hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg); - if (hPtr == NULL) { - typeAlreadyDeleted: - Tcl_AppendResult(interp, "image \"", arg, - "\" doesn't exist", (char *) NULL); - return TCL_ERROR; - } - masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); - if (masterPtr->deleted) { - goto typeAlreadyDeleted; - } + + arg = Tcl_GetString(objv[2]); + hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg); + if (hPtr == NULL) { + goto alreadyDeleted; + } + masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); + if (masterPtr->deleted) { + goto alreadyDeleted; + } + + /* + * Now we read off the specific piece of data we were asked for. + */ + + switch ((enum options) index) { + case IMAGE_HEIGHT: + Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->height); + break; + case IMAGE_INUSE: + Tcl_SetBooleanObj(Tcl_GetObjResult(interp), + masterPtr->typePtr!=NULL && masterPtr->instancePtr!=NULL); + break; + case IMAGE_TYPE: if (masterPtr->typePtr != NULL) { Tcl_SetResult(interp, masterPtr->typePtr->name, TCL_STATIC); } break; - } - case IMAGE_TYPES: { - if (objc != 2) { - Tcl_WrongNumArgs(interp, 2, objv, NULL); - return TCL_ERROR; - } - for (typePtr = tsdPtr->imageTypeList; typePtr != NULL; - typePtr = typePtr->nextPtr) { - Tcl_AppendElement(interp, typePtr->name); - } - for (typePtr = tsdPtr->oldImageTypeList; typePtr != NULL; - typePtr = typePtr->nextPtr) { - Tcl_AppendElement(interp, typePtr->name); - } - break; - } - case IMAGE_WIDTH: { - char *arg; - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "name"); - return TCL_ERROR; - } - arg = Tcl_GetString(objv[2]); - hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, arg); - if (hPtr == NULL) { - widthAlreadyDeleted: - Tcl_AppendResult(interp, "image \"", arg, - "\" doesn't exist", (char *) NULL); - return TCL_ERROR; - } - masterPtr = (ImageMaster *) Tcl_GetHashValue(hPtr); - if (masterPtr->deleted) { - goto widthAlreadyDeleted; - } + case IMAGE_WIDTH: Tcl_SetIntObj(Tcl_GetObjResult(interp), masterPtr->width); break; } + break; } return TCL_OK; + + alreadyDeleted: + Tcl_AppendResult(interp, "image \"",arg,"\" doesn't exist", (char *) NULL); + return TCL_ERROR; } /* @@ -494,32 +443,30 @@ Tk_ImageObjCmd(clientData, interp, objc, objv) * * Tk_ImageChanged -- * - * This procedure is called by an image manager whenever something - * has happened that requires the image to be redrawn (some of its - * pixels have changed, or its size has changed). + * This function is called by an image manager whenever something has + * happened that requires the image to be redrawn (some of its pixels + * have changed, or its size has changed). * * Results: * None. * * Side effects: - * Any widgets that display the image are notified so that they - * can redisplay themselves as appropriate. + * Any widgets that display the image are notified so that they can + * redisplay themselves as appropriate. * *---------------------------------------------------------------------- */ void -Tk_ImageChanged(imageMaster, x, y, width, height, imageWidth, - imageHeight) +Tk_ImageChanged(imageMaster, x, y, width, height, imageWidth, imageHeight) Tk_ImageMaster imageMaster; /* Image that needs redisplay. */ - int x, y; /* Coordinates of upper-left pixel of - * region of image that needs to be - * redrawn. */ - int width, height; /* Dimensions (in pixels) of region of - * image to redraw. If either dimension - * is zero then the image doesn't need to - * be redrawn (perhaps all that happened is - * that its size changed). */ + int x, y; /* Coordinates of upper-left pixel of region + * of image that needs to be redrawn. */ + int width, height; /* Dimensions (in pixels) of region of image + * to redraw. If either dimension is zero then + * the image doesn't need to be redrawn + * (perhaps all that happened is that its size + * changed). */ int imageWidth, imageHeight;/* New dimensions of image. */ { ImageMaster *masterPtr = (ImageMaster *) imageMaster; @@ -528,7 +475,7 @@ Tk_ImageChanged(imageMaster, x, y, width, height, imageWidth, masterPtr->width = imageWidth; masterPtr->height = imageHeight; for (imagePtr = masterPtr->instancePtr; imagePtr != NULL; - imagePtr = imagePtr->nextPtr) { + imagePtr = imagePtr->nextPtr) { (*imagePtr->changeProc)(imagePtr->widgetClientData, x, y, width, height, imageWidth, imageHeight); } @@ -539,8 +486,8 @@ Tk_ImageChanged(imageMaster, x, y, width, height, imageWidth, * * Tk_NameOfImage -- * - * Given a token for an image master, this procedure returns - * the name of the image. + * Given a token for an image master, this function returns the name of + * the image. * * Results: * The return value is the string name for imageMaster. @@ -553,7 +500,7 @@ Tk_ImageChanged(imageMaster, x, y, width, height, imageWidth, CONST char * Tk_NameOfImage(imageMaster) - Tk_ImageMaster imageMaster; /* Token for image. */ + Tk_ImageMaster imageMaster; /* Token for image. */ { ImageMaster *masterPtr = (ImageMaster *) imageMaster; @@ -568,35 +515,33 @@ Tk_NameOfImage(imageMaster) * * Tk_GetImage -- * - * This procedure is invoked by a widget when it wants to use - * a particular image in a particular window. + * This function is invoked by a widget when it wants to use a particular + * image in a particular window. * * Results: - * The return value is a token for the image. If there is no image - * by the given name, then NULL is returned and an error message is - * left in the interp's result. + * The return value is a token for the image. If there is no image by the + * given name, then NULL is returned and an error message is left in the + * interp's result. * * Side effects: - * Tk records the fact that the widget is using the image, and - * it will invoke changeProc later if the widget needs redisplay - * (i.e. its size changes or some of its pixels change). The - * caller must eventually invoke Tk_FreeImage when it no longer - * needs the image. + * Tk records the fact that the widget is using the image, and it will + * invoke changeProc later if the widget needs redisplay (i.e. its size + * changes or some of its pixels change). The caller must eventually + * invoke Tk_FreeImage when it no longer needs the image. * *---------------------------------------------------------------------- */ Tk_Image Tk_GetImage(interp, tkwin, name, changeProc, clientData) - Tcl_Interp *interp; /* Place to leave error message if image - * can't be found. */ - Tk_Window tkwin; /* Token for window in which image will - * be used. */ + Tcl_Interp *interp; /* Place to leave error message if image can't + * be found. */ + Tk_Window tkwin; /* Token for window in which image will be + * used. */ CONST char *name; /* Name of desired image. */ Tk_ImageChangedProc *changeProc; - /* Procedure to invoke when redisplay is - * needed because image's pixels or size - * changed. */ + /* Function to invoke when redisplay is needed + * because image's pixels or size changed. */ ClientData clientData; /* One-word argument to pass to damageProc. */ { Tcl_HashEntry *hPtr; @@ -626,7 +571,7 @@ Tk_GetImage(interp, tkwin, name, changeProc, clientData) masterPtr->instancePtr = imagePtr; return (Tk_Image) imagePtr; - noSuchImage: + noSuchImage: Tcl_AppendResult(interp, "image \"", name, "\" doesn't exist", (char *) NULL); return NULL; @@ -637,9 +582,9 @@ Tk_GetImage(interp, tkwin, name, changeProc, clientData) * * Tk_FreeImage -- * - * This procedure is invoked by a widget when it no longer needs - * an image acquired by a previous call to Tk_GetImage. For each - * call to Tk_GetImage there must be exactly one call to Tk_FreeImage. + * This function is invoked by a widget when it no longer needs an image + * acquired by a previous call to Tk_GetImage. For each call to + * Tk_GetImage there must be exactly one call to Tk_FreeImage. * * Results: * None. @@ -652,8 +597,8 @@ Tk_GetImage(interp, tkwin, name, changeProc, clientData) void Tk_FreeImage(image) - Tk_Image image; /* Token for image that is no longer - * needed by a widget. */ + Tk_Image image; /* Token for image that is no longer needed by + * a widget. */ { Image *imagePtr = (Image *) image; ImageMaster *masterPtr = imagePtr->masterPtr; @@ -678,9 +623,9 @@ Tk_FreeImage(image) } ckfree((char *) imagePtr); - /* - * If there are no more instances left for the master, and if the - * master image has been deleted, then delete the master too. + /* + * If there are no more instances left for the master, and if the master + * image has been deleted, then delete the master too. */ if ((masterPtr->typePtr == NULL) && (masterPtr->instancePtr == NULL)) { @@ -697,15 +642,15 @@ Tk_FreeImage(image) * * Tk_PostscriptImage -- * - * This procedure is called by widgets that contain images in order - * to redisplay an image on the screen or an off-screen pixmap. + * This function is called by widgets that contain images in order to + * redisplay an image on the screen or an off-screen pixmap. * * Results: * None. * * Side effects: - * The image's manager is notified, and it redraws the desired - * portion of the image before returning. + * The image's manager is notified, and it redraws the desired portion of + * the image before returning. * *---------------------------------------------------------------------- */ @@ -732,12 +677,13 @@ Tk_PostscriptImage(image, interp, tkwin, psinfo, x, y, width, height, prepass) /* * No master for image, so nothing to display on postscript. */ + return TCL_OK; } /* - * Check if an image specific postscript-generation function - * exists; otherwise go on with generic code. + * Check if an image specific postscript-generation function exists; + * otherwise go on with generic code. */ if (imagePtr->masterPtr->typePtr->postscriptProc != NULL) { @@ -752,12 +698,12 @@ Tk_PostscriptImage(image, interp, tkwin, psinfo, x, y, width, height, prepass) /* * Create a Pixmap, tell the image to redraw itself there, and then - * generate an XImage from the Pixmap. We can then read pixel - * values out of the XImage. + * generate an XImage from the Pixmap. We can then read pixel values out + * of the XImage. */ - pmap = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin), - width, height, Tk_Depth(tkwin)); + pmap = Tk_GetPixmap(Tk_Display(tkwin), Tk_WindowId(tkwin), width, height, + Tk_Depth(tkwin)); gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin)); newGC = Tk_GetGC(tkwin, GCForeground, &gcValues); @@ -773,11 +719,13 @@ Tk_PostscriptImage(image, interp, tkwin, psinfo, x, y, width, height, prepass) (unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap); Tk_FreePixmap(Tk_Display(tkwin), pmap); - + if (ximage == NULL) { - /* The XGetImage() function is apparently not - * implemented on this system. Just ignore it. + /* + * The XGetImage() function is apparently not implemented on this + * system. Just ignore it. */ + return TCL_OK; } result = TkPostscriptImage(interp, tkwin, psinfo, ximage, x, y, @@ -792,15 +740,15 @@ Tk_PostscriptImage(image, interp, tkwin, psinfo, x, y, width, height, prepass) * * Tk_RedrawImage -- * - * This procedure is called by widgets that contain images in order - * to redisplay an image on the screen or an off-screen pixmap. + * This function is called by widgets that contain images in order to + * redisplay an image on the screen or an off-screen pixmap. * * Results: * None. * * Side effects: - * The image's manager is notified, and it redraws the desired - * portion of the image before returning. + * The image's manager is notified, and it redraws the desired portion of + * the image before returning. * *---------------------------------------------------------------------- */ @@ -812,13 +760,12 @@ Tk_RedrawImage(image, imageX, imageY, width, height, drawable, int imageX, imageY; /* Upper-left pixel of region in image that * needs to be redisplayed. */ int width, height; /* Dimensions of region to redraw. */ - Drawable drawable; /* Drawable in which to display image - * (window or pixmap). If this is a pixmap, - * it must have the same depth as the window - * used in the Tk_GetImage call for the - * image. */ - int drawableX, drawableY; /* Coordinates in drawable that correspond - * to imageX and imageY. */ + Drawable drawable; /* Drawable in which to display image (window + * or pixmap). If this is a pixmap, it must + * have the same depth as the window used in + * the Tk_GetImage call for the image. */ + int drawableX, drawableY; /* Coordinates in drawable that correspond to + * imageX and imageY. */ { Image *imagePtr = (Image *) image; @@ -860,11 +807,11 @@ Tk_RedrawImage(image, imageX, imageY, width, height, drawable, * * Tk_SizeOfImage -- * - * This procedure returns the current dimensions of an image. + * This function returns the current dimensions of an image. * * Results: - * The width and height of the image are returned in *widthPtr - * and *heightPtr. + * The width and height of the image are returned in *widthPtr and + * *heightPtr. * * Side effects: * None. @@ -889,16 +836,14 @@ Tk_SizeOfImage(image, widthPtr, heightPtr) * * Tk_DeleteImage -- * - * Given the name of an image, this procedure destroys the - * image. + * Given the name of an image, this function destroys the image. * * Results: * None. * * Side effects: - * The image is destroyed; existing instances will display as - * blank areas. If no such image exists then the procedure does - * nothing. + * The image is destroyed; existing instances will display as blank + * areas. If no such image exists then the function does nothing. * *---------------------------------------------------------------------- */ @@ -928,15 +873,15 @@ Tk_DeleteImage(interp, name) * * DeleteImage -- * - * This procedure is responsible for deleting an image. + * This function is responsible for deleting an image. * * Results: * None. * * Side effects: - * The connection is dropped between instances of this image and - * an image master. Image instances will redisplay themselves - * as empty areas, but existing instances will not be deleted. + * The connection is dropped between instances of this image and an image + * master. Image instances will redisplay themselves as empty areas, but + * existing instances will not be deleted. * *---------------------------------------------------------------------- */ @@ -983,9 +928,9 @@ DeleteImage(masterPtr) * None. * * Side effects: - * Image will get freed, though not until it is no longer - * Tcl_Preserve()d by anything. May be called multiple times on - * the same image without ill effects. + * Image will get freed, though not until it is no longer Tcl_Preserve()d + * by anything. May be called multiple times on the same image without + * ill effects. * *---------------------------------------------------------------------- */ @@ -993,8 +938,8 @@ DeleteImage(masterPtr) static void EventuallyDeleteImage(masterPtr, forgetImageHashNow) ImageMaster *masterPtr; /* Pointer to main data structure for image. */ - int forgetImageHashNow; /* Flag to say whether the hash table is - * about to vanish. */ + int forgetImageHashNow; /* Flag to say whether the hash table is about + * to vanish. */ { if (forgetImageHashNow) { masterPtr->hPtr = NULL; @@ -1011,10 +956,9 @@ EventuallyDeleteImage(masterPtr, forgetImageHashNow) * * TkDeleteAllImages -- * - * This procedure is called when an application is deleted. It - * calls back all of the managers for all images so that they - * can cleanup, then it deletes all of Tk's internal information - * about images. + * This function is called when an application is deleted. It calls back + * all of the managers for all images so that they can cleanup, then it + * deletes all of Tk's internal information about images. * * Results: * None. @@ -1045,15 +989,14 @@ TkDeleteAllImages(mainPtr) * * Tk_GetImageMasterData -- * - * Given the name of an image, this procedure returns the type - * of the image and the clientData associated with its master. + * Given the name of an image, this function returns the type of the + * image and the clientData associated with its master. * * Results: - * If there is no image by the given name, then NULL is returned - * and a NULL value is stored at *typePtrPtr. Otherwise the return - * value is the clientData returned by the createProc when the - * image was created and a pointer to the type structure for the - * image is stored at *typePtrPtr. + * If there is no image by the given name, then NULL is returned and a + * NULL value is stored at *typePtrPtr. Otherwise the return value is the + * clientData returned by the createProc when the image was created and a + * pointer to the type structure for the image is stored at *typePtrPtr. * * Side effects: * None. @@ -1066,8 +1009,8 @@ Tk_GetImageMasterData(interp, name, typePtrPtr) Tcl_Interp *interp; /* Interpreter in which the image was * created. */ CONST char *name; /* Name of image. */ - Tk_ImageType **typePtrPtr; /* Points to location to fill in with - * pointer to type information for image. */ + Tk_ImageType **typePtrPtr; /* Points to location to fill in with pointer + * to type information for image. */ { Tcl_HashEntry *hPtr; TkWindow *winPtr; @@ -1093,21 +1036,22 @@ Tk_GetImageMasterData(interp, name, typePtrPtr) * * Tk_SetTSOrigin -- * - * Set the pattern origin of the tile to a common point (i.e. the - * origin (0,0) of the top level window) so that tiles from two - * different widgets will match up. This done by setting the - * GCTileStipOrigin field is set to the translated origin of the - * toplevel window in the hierarchy. + * Set the pattern origin of the tile to a common point (i.e. the origin + * (0,0) of the top level window) so that tiles from two different + * widgets will match up. This done by setting the GCTileStipOrigin field + * is set to the translated origin of the toplevel window in the + * hierarchy. * * Results: * None. * * Side Effects: - * The GCTileStipOrigin is reset in the GC. This will cause the - * tile origin to change when the GC is used for drawing. + * The GCTileStipOrigin is reset in the GC. This will cause the tile + * origin to change when the GC is used for drawing. * *---------------------------------------------------------------------- */ + /*ARGSUSED*/ void Tk_SetTSOrigin(tkwin, gc, x, y) @@ -1122,4 +1066,11 @@ Tk_SetTSOrigin(tkwin, gc, x, y) } XSetTSOrigin(Tk_Display(tkwin), gc, x, y); } - + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkImgGIF.c b/generic/tkImgGIF.c index 69aa02f..1c58769 100644 --- a/generic/tkImgGIF.c +++ b/generic/tkImgGIF.c @@ -5,7 +5,7 @@ * At present, there only is a file write function. GIF images may be * read using the -data option of the photo image. The data may be given * as a binary string in a Tcl_Obj or by representing the data as BASE64 - * encoded ascii. Derived from the giftoppm code found in the pbmplus + * encoded ascii. Derived from the giftoppm code found in the pbmplus * package and tkImgFmtPPM.c in the tk4.0b2 distribution. * * Copyright (c) Reed Wade (wade@cs.utk.edu), University of Tennessee @@ -25,22 +25,22 @@ * | and its documentation for any purpose and without fee is hereby | * | granted, provided that the above copyright notice appear in all | * | copies and that both that copyright notice and this permission | - * | notice appear in supporting documentation. This software is | + * | notice appear in supporting documentation. This software is | * | provided "as is" without express or implied warranty. | * +--------------------------------------------------------------------+ * * This file also contains code from miGIF. See lower down in file for the * applicable copyright notice for that portion. * - * RCS: @(#) $Id: tkImgGIF.c,v 1.28 2005/06/19 21:54:16 dkf Exp $ + * RCS: @(#) $Id: tkImgGIF.c,v 1.29 2005/08/10 22:02:22 dkf Exp $ */ /* - * GIF's are represented as data in either binary or base64 format. base64 - * strings consist of 4 6-bit characters -> 3 8 bit bytes. A-Z, a-z, 0-9, + - * and / represent the 64 values (in order). '=' is a trailing padding char - * when the un-encoded data is not a multiple of 3 bytes. We'll ignore white - * space when encountered. Any other invalid character is treated as an EOF + * GIF's are represented as data in either binary or base64 format. base64 + * strings consist of 4 6-bit characters -> 3 8 bit bytes. A-Z, a-z, 0-9, + + * and / represent the 64 values (in order). '=' is a trailing padding char + * when the un-encoded data is not a multiple of 3 bytes. We'll ignore white + * space when encountered. Any other invalid character is treated as an EOF */ #define GIF_SPECIAL (256) @@ -50,8 +50,8 @@ #define GIF_DONE (GIF_SPECIAL+4) /* - * structure to "mimic" FILE for Mread, so we can look like fread. The - * decoder state keeps track of which byte we are about to read, or EOF. + * structure to "mimic" FILE for Mread, so we can look like fread. The decoder + * state keeps track of which byte we are about to read, or EOF. */ typedef struct mFile { @@ -88,7 +88,7 @@ static CONST char GIF89a[] = { /* ASCII GIF89a */ #define INLINE_DATA_BASE64 ((const char *) 0x02) /* - * HACK ALERT!! HACK ALERT!! HACK ALERT!! + * HACK ALERT!! HACK ALERT!! HACK ALERT!! * This code is hard-wired for reading from files. In order to read from a * data stream, we'll trick fread so we can reuse the same code. 0==from file; * 1==from base64 encoded data; 2==from binary data @@ -110,25 +110,23 @@ typedef struct { * The format record for the GIF file format: */ -static int FileMatchGIF _ANSI_ARGS_((Tcl_Channel chan, CONST char *fileName, - Tcl_Obj *format, int *widthPtr, int *heightPtr, - Tcl_Interp *interp)); -static int FileReadGIF _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Channel chan, - CONST char *fileName, Tcl_Obj *format, - Tk_PhotoHandle imageHandle, int destX, int destY, - int width, int height, int srcX, int srcY)); -static int StringMatchGIF _ANSI_ARGS_(( Tcl_Obj *dataObj, Tcl_Obj *format, - int *widthPtr, int *heightPtr, Tcl_Interp *interp)); -static int StringReadGIF _ANSI_ARGS_((Tcl_Interp *interp, Tcl_Obj *dataObj, - Tcl_Obj *format, Tk_PhotoHandle imageHandle, - int destX, int destY, int width, int height, - int srcX, int srcY)); -static int FileWriteGIF _ANSI_ARGS_((Tcl_Interp *interp, - CONST char *filename, Tcl_Obj *format, - Tk_PhotoImageBlock *blockPtr)); -static int CommonWriteGIF _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Channel handle, Tcl_Obj *format, - Tk_PhotoImageBlock *blockPtr)); +static int FileMatchGIF(Tcl_Channel chan, CONST char *fileName, + Tcl_Obj *format, int *widthPtr, int *heightPtr, + Tcl_Interp *interp); +static int FileReadGIF(Tcl_Interp *interp, Tcl_Channel chan, + CONST char *fileName, Tcl_Obj *format, + Tk_PhotoHandle imageHandle, int destX, int destY, + int width, int height, int srcX, int srcY); +static int StringMatchGIF(Tcl_Obj *dataObj, Tcl_Obj *format, + int *widthPtr, int *heightPtr, Tcl_Interp *interp); +static int StringReadGIF(Tcl_Interp *interp, Tcl_Obj *dataObj, + Tcl_Obj *format, Tk_PhotoHandle imageHandle, + int destX, int destY, int width, int height, + int srcX, int srcY); +static int FileWriteGIF(Tcl_Interp *interp, CONST char *filename, + Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr); +static int CommonWriteGIF(Tcl_Interp *interp, Tcl_Channel handle, + Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr); Tk_PhotoImageFormat tkImgFmtGIF = { "gif", /* name */ @@ -152,47 +150,47 @@ Tk_PhotoImageFormat tkImgFmtGIF = { #define LM_to_uint(a,b) (((b)<<8)|(a)) /* - * Prototypes for local procedures defined in this file: + * Prototypes for local functions defined in this file: */ -static int DoExtension _ANSI_ARGS_((GIFImageConfig *gifConfPtr, - Tcl_Channel chan, int label, unsigned char *buffer, - int *transparent)); -static int GetCode _ANSI_ARGS_((Tcl_Channel chan, int code_size, int flag, - GIFImageConfig *gifConfPtr)); -static int GetDataBlock _ANSI_ARGS_((GIFImageConfig *gifConfPtr, - Tcl_Channel chan, unsigned char *buf)); -static int ReadColorMap _ANSI_ARGS_((GIFImageConfig *gifConfPtr, - Tcl_Channel chan, int number, - unsigned char buffer[MAXCOLORMAPSIZE][4])); -static int ReadGIFHeader _ANSI_ARGS_((GIFImageConfig *gifConfPtr, - Tcl_Channel chan, int *widthPtr, int *heightPtr)); -static int ReadImage _ANSI_ARGS_((GIFImageConfig *gifConfPtr, - Tcl_Interp *interp, char *imagePtr, Tcl_Channel chan, - int len, int rows, unsigned char cmap[MAXCOLORMAPSIZE][4], - int width, int height, int srcX, int srcY, int interlace, - int transparent)); +static int DoExtension(GIFImageConfig *gifConfPtr, + Tcl_Channel chan, int label, unsigned char *buffer, + int *transparent); +static int GetCode(Tcl_Channel chan, int code_size, int flag, + GIFImageConfig *gifConfPtr); +static int GetDataBlock(GIFImageConfig *gifConfPtr, + Tcl_Channel chan, unsigned char *buf); +static int ReadColorMap(GIFImageConfig *gifConfPtr, + Tcl_Channel chan, int number, + unsigned char buffer[MAXCOLORMAPSIZE][4]); +static int ReadGIFHeader(GIFImageConfig *gifConfPtr, + Tcl_Channel chan, int *widthPtr, int *heightPtr); +static int ReadImage(GIFImageConfig *gifConfPtr, + Tcl_Interp *interp, char *imagePtr, + Tcl_Channel chan, int len, int rows, + unsigned char cmap[MAXCOLORMAPSIZE][4], + int width, int height, int srcX, int srcY, + int interlace, int transparent); /* * these are for the BASE64 image reader code only */ -static int Fread _ANSI_ARGS_((GIFImageConfig *gifConfPtr, - unsigned char *dst, size_t size, size_t count, - Tcl_Channel chan)); -static int Mread _ANSI_ARGS_((unsigned char *dst, size_t size, - size_t count, MFile *handle)); -static int Mgetc _ANSI_ARGS_((MFile *handle)); -static int char64 _ANSI_ARGS_((int c)); -static void mInit _ANSI_ARGS_((unsigned char *string, MFile *handle, - int length)); +static int Fread(GIFImageConfig *gifConfPtr, unsigned char *dst, + size_t size, size_t count, Tcl_Channel chan); +static int Mread(unsigned char *dst, size_t size, size_t count, + MFile *handle); +static int Mgetc(MFile *handle); +static int char64(int c); +static void mInit(unsigned char *string, MFile *handle, + int length); /* *---------------------------------------------------------------------- * * FileMatchGIF -- * - * This procedure is invoked by the photo image type to see if a file + * This function is invoked by the photo image type to see if a file * contains image data in GIF format. * * Results: @@ -225,12 +223,12 @@ FileMatchGIF(chan, fileName, format, widthPtr, heightPtr, interp) * * FileReadGIF -- * - * This procedure is called by the photo image type to read GIF format + * This function is called by the photo image type to read GIF format * data from a file and write it into a given photo image. * * Results: - * A standard TCL completion code. If TCL_ERROR is returned then an - * error message is left in the interp's result. + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. * * Side effects: * The access position in file f is changed, and new data is added to the @@ -298,7 +296,7 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY, } } if (!ReadGIFHeader(gifConfPtr, chan, &fileWidth, &fileHeight)) { - Tcl_AppendResult(interp, "couldn't read GIF header from file \"", + Tcl_AppendResult(interp, "couldn't read GIF header from file \"", fileName, "\"", NULL); return TCL_ERROR; } @@ -393,6 +391,7 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY, /* * Not a valid start character; ignore it. */ + continue; } @@ -412,6 +411,7 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY, /* * This is not the image we want to read: skip it. */ + if (BitSet(buf[8], LOCALCOLORMAP)) { if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) { Tcl_AppendResult(interp, @@ -423,13 +423,14 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY, /* * If we've not yet allocated a trash buffer, do so now. */ + if (trashBuffer == NULL) { nBytes = fileWidth * fileHeight * 3; trashBuffer = (unsigned char *) ckalloc((unsigned int) nBytes); } /* - * Slurp! Process the data for this image and stuff it in a trash + * Slurp! Process the data for this image and stuff it in a trash * buffer. * * Yes, it might be more efficient here to *not* store the data @@ -455,7 +456,7 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY, if (BitSet(buf[8], LOCALCOLORMAP)) { if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) { - Tcl_AppendResult(interp, "error reading color map", + Tcl_AppendResult(interp, "error reading color map", (char *) NULL); goto error; } @@ -512,6 +513,7 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY, /* * If a trash buffer has been allocated, free it now. */ + if (trashBuffer != NULL) { ckfree((char *)trashBuffer); } @@ -525,6 +527,7 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY, /* * If a trash buffer has been allocated, free it now. */ + if (trashBuffer != NULL) { ckfree((char *)trashBuffer); } @@ -539,7 +542,7 @@ FileReadGIF(interp, chan, fileName, format, imageHandle, destX, destY, * * StringMatchGIF -- * - * This procedure is invoked by the photo image type to see if an object + * This function is invoked by the photo image type to see if an object * contains image data in GIF format. * * Results: @@ -569,6 +572,7 @@ StringMatchGIF(dataObj, format, widthPtr, heightPtr, interp) /* * Header is a minimum of 10 bytes. */ + if (length < 10) { return 0; } @@ -577,15 +581,16 @@ StringMatchGIF(dataObj, format, widthPtr, heightPtr, interp) * Check whether the data is Base64 encoded. */ - if ((strncmp(GIF87a, (char *) data, 6) != 0) && + if ((strncmp(GIF87a, (char *) data, 6) != 0) && (strncmp(GIF89a, (char *) data, 6) != 0)) { /* * Try interpreting the data as Base64 encoded */ + mInit((unsigned char *) data, &handle, length); got = Mread(header, 10, 1, &handle); - if (got != 10 - || ((strncmp(GIF87a, (char *) header, 6) != 0) + if (got != 10 || + ((strncmp(GIF87a, (char *) header, 6) != 0) && (strncmp(GIF89a, (char *) header, 6) != 0))) { return 0; } @@ -602,16 +607,16 @@ StringMatchGIF(dataObj, format, widthPtr, heightPtr, interp) * * StringReadGIF -- * - * This procedure is called by the photo image type to read GIF format + * This function is called by the photo image type to read GIF format * data from an object, optionally base64 encoded, and give it to the * photo image. * * Results: - * A standard TCL completion code. If TCL_ERROR is returned then an - * error message is left in the interp's result. + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. * * Side effects: - * New data is added to the image given by imageHandle. This procedure + * New data is added to the image given by imageHandle. This function * calls FileReadGIF by redefining the operation of fprintf temporarily. * *---------------------------------------------------------------------- @@ -655,12 +660,12 @@ StringReadGIF(interp, dataObj, format, imageHandle, * * ReadGIFHeader -- * - * This procedure reads the GIF header from the beginning of a GIF file + * This function reads the GIF header from the beginning of a GIF file * and returns the dimensions of the image. * * Results: * The return value is 1 if file "f" appears to start with a valid GIF - * header, 0 otherwise. If the header is valid, then *widthPtr and + * header, 0 otherwise. If the header is valid, then *widthPtr and * *heightPtr are modified to hold the dimensions of the image. * * Side effects: @@ -845,6 +850,7 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, /* * Initialize the decoder */ + if (Fread(gifConfPtr, &initialCodeSize, 1, 1, chan) <= 0) { Tcl_AppendResult(interp, "error reading GIF image: ", Tcl_PosixError(interp), (char *) NULL); @@ -868,13 +874,14 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, * code size size of the next code to retrieve * max code next available table position */ + clearCode = 1 << (int) initialCodeSize; endCode = clearCode + 1; codeSize = (int) initialCodeSize + 1; maxCode = clearCode + 2; oldCode = -1; firstCode = -1; - + memset((void *)prefix, 0, (1 << MAX_LWZ_BITS) * sizeof(short)); memset((void *)append, 0, (1 << MAX_LWZ_BITS) * sizeof(char)); for (i = 0; i < clearCode; i++) { @@ -887,13 +894,15 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, /* * Read until we finish the image */ + for (i = 0, ypos = 0; i < rows; i++) { for (xpos = 0; xpos < len; ) { if (top == stack) { /* - * Bummer -- our stack is empty. Now we have to work! + * Bummer - our stack is empty. Now we have to work! */ + code = GetCode(chan, codeSize, 0, gifConfPtr); if (code < 0) { return TCL_OK; @@ -902,12 +911,13 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, if (code > maxCode || code == endCode) { /* * If we're doing things right, we should never receive a - * code that is greater than our current maximum code. If + * code that is greater than our current maximum code. If * we do, bail, because our decoder does not yet have that * code set up. * * If the code is the magic endCode value, quit. */ + return TCL_OK; } @@ -915,12 +925,13 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, /* * Reset the decoder. */ + codeSize = initialCodeSize + 1; maxCode = clearCode + 2; oldCode = -1; continue; } - + if (oldCode == -1) { /* * Last pass reset the decoder, so the first code we see @@ -930,12 +941,13 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, * clearCode test above, because at that point we have not * yet read the next code. */ + *top++ = append[code]; oldCode = code; firstCode = code; continue; } - + inCode = code; if (code == maxCode) { @@ -944,6 +956,7 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, * code. If the code we see is equal to maxCode, then we * are about to add a new string to the table. ??? */ + *top++ = firstCode; code = oldCode; } @@ -953,6 +966,7 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, * Populate the stack by tracing the string in the string * table from its tail to its head */ + *top++ = append[code]; code = prefix[code]; } @@ -962,6 +976,7 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, * If there's no more room in our string table, quit. * Otherwise, add a new string to the table */ + if (maxCode >= (1 << MAX_LWZ_BITS)) { return TCL_OK; } @@ -969,11 +984,13 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, /* * Push the head of the string onto the stack. */ + *top++ = firstCode; /* * Add a new string to the string table */ + prefix[maxCode] = oldCode; append[maxCode] = firstCode; maxCode++; @@ -1001,7 +1018,7 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, return TCL_OK; } - /* + /* * If pixelPtr is null, we're skipping this image (presumably * there are more in the file and we will be called to read one of * them later) @@ -1018,8 +1035,9 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, } /* - * If interlacing, the next ypos is not just +1 + * If interlacing, the next ypos is not just +1. */ + if (interlace) { ypos += interlaceStep[pass]; while (ypos >= height) { @@ -1042,7 +1060,7 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, * * GetCode -- * - * Extract the next compression code from the file. In GIF's, the + * Extract the next compression code from the file. In GIF's, the * compression codes are between 3 and 12 bits long and are then packed * into 8 bit bytes, left to right, for example: * bbbaaaaa @@ -1050,7 +1068,7 @@ ReadImage(gifConfPtr, interp, imagePtr, chan, len, rows, cmap, * eeeedddd * ... * We use a byte buffer read from the file and a sliding window to unpack - * the bytes. Thanks to ImageMagick for the sliding window idea. + * the bytes. Thanks to ImageMagick for the sliding window idea. * args: chan the channel to read from * code_size size of the code to extract * flag boolean indicating whether the extractor should be @@ -1073,11 +1091,12 @@ GetCode(chan, code_size, flag, gifConfPtr) GIFImageConfig *gifConfPtr; { int ret; - + if (flag) { /* * Initialize the decoder. */ + gifConfPtr->reader.bitsInWindow = 0; gifConfPtr->reader.bytes = 0; gifConfPtr->reader.window = 0; @@ -1090,6 +1109,7 @@ GetCode(chan, code_size, flag, gifConfPtr) /* * Not enough bits in our window to cover the request. */ + if (gifConfPtr->reader.done) { return -1; } @@ -1097,6 +1117,7 @@ GetCode(chan, code_size, flag, gifConfPtr) /* * Not enough bytes in our buffer to add to the window. */ + gifConfPtr->reader.bytes = GetDataBlock(gifConfPtr, chan, gifConfPtr->workingBuffer); gifConfPtr->reader.c = gifConfPtr->workingBuffer; @@ -1105,9 +1126,11 @@ GetCode(chan, code_size, flag, gifConfPtr) break; } } + /* * Tack another byte onto the window, see if that's enough. */ + gifConfPtr->reader.window += (*gifConfPtr->reader.c) << gifConfPtr->reader.bitsInWindow; gifConfPtr->reader.c++; @@ -1118,11 +1141,13 @@ GetCode(chan, code_size, flag, gifConfPtr) /* * The next code will always be the last code_size bits of the window. */ + ret = gifConfPtr->reader.window & ((1 << code_size) - 1); - + /* * Shift data in the window to put the next code at the end. */ + gifConfPtr->reader.window >>= code_size; gifConfPtr->reader.bitsInWindow -= code_size; return ret; @@ -1133,7 +1158,7 @@ GetCode(chan, code_size, flag, gifConfPtr) * * Minit -- -- * - * This procedure initializes a base64 decoder handle + * This function initializes a base64 decoder handle * * Results: * None @@ -1161,7 +1186,7 @@ mInit(string, handle, length) * * Mread -- * - * This procedure is invoked by the GIF file reader as a temporary + * This function is invoked by the GIF file reader as a temporary * replacement for "fread", to get GIF data out of a string (using * Mgetc). * @@ -1175,7 +1200,7 @@ mInit(string, handle, length) */ static int -Mread(dst, chunkSize, numChunks, handle) +Mread(dst, chunkSize, numChunks, handle) unsigned char *dst; /* where to put the result */ size_t chunkSize; /* size of each transfer */ size_t numChunks; /* number of chunks */ @@ -1189,19 +1214,14 @@ Mread(dst, chunkSize, numChunks, handle) } return i; } - -/* - * Get the next decoded character from an mmencode handle. - * This causes at least 1 character to be "read" from the encoded string - */ /* *---------------------------------------------------------------------- * * Mgetc -- * - * This procedure decodes and returns the next byte from a base64 encoded - * string. + * This function gets the next decoded character from an mmencode handle. + * This causes at least 1 character to be "read" from the encoded string. * * Results: * The next byte (or GIF_DONE) is returned. @@ -1263,9 +1283,9 @@ Mgetc(handle) * * char64 -- * - * This procedure converts a base64 ascii character into its binary - * equivalent. This code is a slightly modified version of the char64 - * proc in N. Borenstein's metamail decoder. + * This function converts a base64 ascii character into its binary + * equivalent. This code is a slightly modified version of the char64 + * function in N. Borenstein's metamail decoder. * * Results: * The binary value, or an error code. @@ -1320,7 +1340,7 @@ char64(c) * * Fread -- * - * This procedure calls either fread or Mread to read data from a file or + * This function calls either fread or Mread to read data from a file or * a base64 encoded string. * * Results: - same as POSIX fread() or Tcl Tcl_Read() @@ -1354,6 +1374,7 @@ Fread(gifConfPtr, dst, hunk, count, chan) /* * Otherwise we've got a real file to read. */ + return Tcl_Read(chan, (char *) dst, (int) (hunk * count)); } @@ -1361,8 +1382,8 @@ Fread(gifConfPtr, dst, hunk, count, chan) * ChanWriteGIF - writes a image in GIF format. *------------------------------------------------------------------------- * Author: Lolo - * Engeneering Projects Area - * Department of Mining + * Engeneering Projects Area + * Department of Mining * University of Oviedo * e-mail zz11425958@zeus.etsimo.uniovi.es * lolo@pcsig22.etsimo.uniovi.es @@ -1374,12 +1395,12 @@ Fread(gifConfPtr, dst, hunk, count, chan) *---------------------------------------------------------------------- * FileWriteGIF- * - * This procedure is called by the photo image type to write GIF format + * This function is called by the photo image type to write GIF format * data from a photo image into a given file * * Results: - * A standard TCL completion code. If TCL_ERROR is returned then an - * error message is left in interp->result. + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in interp->result. * *---------------------------------------------------------------------- */ @@ -1388,13 +1409,13 @@ Fread(gifConfPtr, dst, hunk, count, chan) * Types, defines and variables needed to write and compress a GIF. */ -typedef int (* ifunptr) _ANSI_ARGS_((ClientData clientData)); +typedef int (* ifunptr) (ClientData clientData); -#define LSB(a) ((unsigned char) (((short)(a)) & 0x00FF)) -#define MSB(a) ((unsigned char) (((short)(a)) >> 8)) +#define LSB(a) ((unsigned char) (((short)(a)) & 0x00FF)) +#define MSB(a) ((unsigned char) (((short)(a)) >> 8)) -#define GIFBITS 12 -#define HSIZE 5003 /* 80% occupancy */ +#define GIFBITS 12 +#define HSIZE 5003 /* 80% occupancy */ typedef struct { int ssize; @@ -1414,18 +1435,18 @@ typedef struct { * Definition of new functions to write GIFs */ -static int color _ANSI_ARGS_((GifWriterState *statePtr, - int red, int green, int blue, - unsigned char mapa[MAXCOLORMAPSIZE][3])); -static void compress _ANSI_ARGS_((int initBits, Tcl_Channel handle, - ifunptr readValue, ClientData clientData)); -static int nuevo _ANSI_ARGS_((GifWriterState *statePtr, - int red, int green, int blue, - unsigned char mapa[MAXCOLORMAPSIZE][3])); -static void savemap _ANSI_ARGS_((GifWriterState *statePtr, - Tk_PhotoImageBlock *blockPtr, - unsigned char mapa[MAXCOLORMAPSIZE][3])); -static int ReadValue _ANSI_ARGS_((ClientData clientData)); +static int color(GifWriterState *statePtr, + int red, int green, int blue, + unsigned char mapa[MAXCOLORMAPSIZE][3]); +static void compress(int initBits, Tcl_Channel handle, + ifunptr readValue, ClientData clientData); +static int nuevo(GifWriterState *statePtr, + int red, int green, int blue, + unsigned char mapa[MAXCOLORMAPSIZE][3]); +static void savemap(GifWriterState *statePtr, + Tk_PhotoImageBlock *blockPtr, + unsigned char mapa[MAXCOLORMAPSIZE][3]); +static int ReadValue(ClientData clientData); static int FileWriteGIF(interp, filename, format, blockPtr) @@ -1526,14 +1547,14 @@ CommonWriteGIF(interp, handle, format, blockPtr) statePtr->num = 1 << resolution; /* - * background color + * Background color */ c = 0; Tcl_Write(handle, (char *) &c, 1); /* - * zero for future expansion. + * Zero for future expansion. */ Tcl_Write(handle, (char *) &c, 1); @@ -1587,12 +1608,12 @@ CommonWriteGIF(interp, handle, format, blockPtr) statePtr->csize = blockPtr->height; compress(resolution+1, handle, ReadValue, (ClientData) statePtr); - c = 0; + c = 0; Tcl_Write(handle, (char *) &c, 1); c = GIF_TERMINATOR; Tcl_Write(handle, (char *) &c, 1); - return TCL_OK; + return TCL_OK; } static int @@ -1719,7 +1740,7 @@ ReadValue(clientData) * including but not limited to implied warranties of merchantability and * fitness for a particular purpose, with respect to this code and * accompanying documentation. - * + * * The miGIF compression routines do not, strictly speaking, generate files * conforming to the GIF spec, since the image data is not LZW-compressed * (this is the point: in order to avoid transgression of the Unisys patent on @@ -1782,8 +1803,8 @@ typedef struct { static int verboseSet = 0; static int verbose; -#define MIGIF_VERBOSE (verboseSet?verbose:setVerbose()) -#define DEBUGMSG(printfArgs) if (MIGIF_VERBOSE) { printf printfArgs; } +#define MIGIF_VERBOSE (verboseSet?verbose:setVerbose()) +#define DEBUGMSG(printfArgs) if (MIGIF_VERBOSE) { printf printfArgs; } static int setVerbose(void) @@ -2142,16 +2163,18 @@ compress(initBits, handle, readValue, clientData) statePtr->codeEOF = statePtr->codeClear + 1; statePtr->runlengthBaseCode = statePtr->codeEOF + 1; statePtr->outputBumpInit = (1 << (initBits - 1)) - 1; + /* * For images with a lot of runs, making outputClearInit larger will give * better compression. */ + statePtr->outputClearInit = (initBits <= 3) ? 9 : (statePtr->outputBumpInit-1); #ifdef MIGIF_DEBUGGING_ENVARS { - const char *ocienv; - ocienv = getenv("MIGIF_OUT_CLEAR_INIT"); + const char *ocienv = getenv("MIGIF_OUT_CLEAR_INIT"); + if (ocienv) { statePtr->outputClearInit = atoi(ocienv); DEBUGMSG(("[overriding outputClearInit to %d]\n", @@ -2187,7 +2210,15 @@ compress(initBits, handle, readValue, clientData) /* *----------------------------------------------------------------------- * - * End of miGIF section - See copyright notice at start of section. + * End of miGIF section - See copyright notice at start of section. * *----------------------------------------------------------------------- */ + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkImgPPM.c b/generic/tkImgPPM.c index ac989db..73f4844 100644 --- a/generic/tkImgPPM.c +++ b/generic/tkImgPPM.c @@ -6,22 +6,22 @@ * Copyright (c) 1994 The Australian National University. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * * Author: Paul Mackerras (paulus@cs.anu.edu.au), * Department of Computer Science, * Australian National University. * - * RCS: @(#) $Id: tkImgPPM.c,v 1.14 2004/03/27 00:12:22 dkf Exp $ + * RCS: @(#) $Id: tkImgPPM.c,v 1.15 2005/08/10 22:02:22 dkf Exp $ */ #include "tkInt.h" #include "tkPort.h" /* - * The maximum amount of memory to allocate for data read from the - * file. If we need more than this, we do it in pieces. + * The maximum amount of memory to allocate for data read from the file. If we + * need more than this, we do it in pieces. */ #define MAX_MEMORY 10000 /* don't allocate > 10KB */ @@ -37,27 +37,23 @@ * The format record for the PPM file format: */ -static int FileMatchPPM _ANSI_ARGS_((Tcl_Channel chan, +static int FileMatchPPM(Tcl_Channel chan, CONST char *fileName, + Tcl_Obj *format, int *widthPtr, int *heightPtr, + Tcl_Interp *interp); +static int FileReadPPM(Tcl_Interp *interp, Tcl_Channel chan, CONST char *fileName, Tcl_Obj *format, - int *widthPtr, int *heightPtr, - Tcl_Interp *interp)); -static int FileReadPPM _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Channel chan, CONST char *fileName, + Tk_PhotoHandle imageHandle, int destX, int destY, + int width, int height, int srcX, int srcY); +static int FileWritePPM(Tcl_Interp *interp, CONST char *fileName, + Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr); +static int StringWritePPM(Tcl_Interp *interp, Tcl_Obj *format, + Tk_PhotoImageBlock *blockPtr); +static int StringMatchPPM(Tcl_Obj *dataObj, Tcl_Obj *format, + int *widthPtr, int *heightPtr, Tcl_Interp *interp); +static int StringReadPPM(Tcl_Interp *interp, Tcl_Obj *dataObj, Tcl_Obj *format, Tk_PhotoHandle imageHandle, int destX, int destY, int width, int height, - int srcX, int srcY)); -static int FileWritePPM _ANSI_ARGS_((Tcl_Interp *interp, - CONST char *fileName, Tcl_Obj *format, - Tk_PhotoImageBlock *blockPtr)); -static int StringWritePPM _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr)); -static int StringMatchPPM _ANSI_ARGS_((Tcl_Obj *dataObj, - Tcl_Obj *format, int *widthPtr, int *heightPtr, - Tcl_Interp *interp)); -static int StringReadPPM _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *dataObj, Tcl_Obj *format, - Tk_PhotoHandle imageHandle, int destX, int destY, - int width, int height, int srcX, int srcY)); + int srcX, int srcY); Tk_PhotoImageFormat tkImgFmtPPM = { @@ -71,28 +67,26 @@ Tk_PhotoImageFormat tkImgFmtPPM = { }; /* - * Prototypes for local procedures defined in this file: + * Prototypes for local functions defined in this file: */ -static int ReadPPMFileHeader _ANSI_ARGS_((Tcl_Channel chan, - int *widthPtr, int *heightPtr, - int *maxIntensityPtr)); -static int ReadPPMStringHeader _ANSI_ARGS_((Tcl_Obj *dataObj, - int *widthPtr, int *heightPtr, - int *maxIntensityPtr, - unsigned char **dataBufferPtr, int *dataSizePtr)); +static int ReadPPMFileHeader(Tcl_Channel chan, int *widthPtr, + int *heightPtr, int *maxIntensityPtr); +static int ReadPPMStringHeader(Tcl_Obj *dataObj, int *widthPtr, + int *heightPtr, int *maxIntensityPtr, + unsigned char **dataBufferPtr, int *dataSizePtr); /* *---------------------------------------------------------------------- * * FileMatchPPM -- * - * This procedure is invoked by the photo image type to see if - * a file contains image data in PPM format. + * This function is invoked by the photo image type to see if a file + * contains image data in PPM format. * * Results: - * The return value is >0 if the first characters in file "f" look - * like PPM data, and 0 otherwise. + * The return value is >0 if the first characters in file "f" look like + * PPM data, and 0 otherwise. * * Side effects: * The access position in f may change. @@ -105,9 +99,9 @@ FileMatchPPM(chan, fileName, format, widthPtr, heightPtr, interp) Tcl_Channel chan; /* The image file, open for reading. */ CONST char *fileName; /* The name of the image file. */ Tcl_Obj *format; /* User-specified format string, or NULL. */ - int *widthPtr, *heightPtr; /* The dimensions of the image are - * returned here if the file is a valid - * raw PPM file. */ + int *widthPtr, *heightPtr; /* The dimensions of the image are returned + * here if the file is a valid raw PPM + * file. */ Tcl_Interp *interp; /* unused */ { int dummy; @@ -120,17 +114,16 @@ FileMatchPPM(chan, fileName, format, widthPtr, heightPtr, interp) * * FileReadPPM -- * - * This procedure is called by the photo image type to read - * PPM format data from a file and write it into a given - * photo image. + * This function is called by the photo image type to read PPM format + * data from a file and write it into a given photo image. * * Results: - * A standard TCL completion code. If TCL_ERROR is returned - * then an error message is left in the interp's result. + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. * * Side effects: - * The access position in file f is changed, and new data is - * added to the image given by imageHandle. + * The access position in file f is changed, and new data is added to the + * image given by imageHandle. * *---------------------------------------------------------------------- */ @@ -143,12 +136,12 @@ FileReadPPM(interp, chan, fileName, format, imageHandle, destX, destY, CONST char *fileName; /* The name of the image file. */ Tcl_Obj *format; /* User-specified format string, or NULL. */ Tk_PhotoHandle imageHandle; /* The photo image to write into. */ - int destX, destY; /* Coordinates of top-left pixel in - * photo image to be written to. */ - int width, height; /* Dimensions of block of photo image to - * be written to. */ - int srcX, srcY; /* Coordinates of top-left pixel to be used - * in image being read. */ + int destX, destY; /* Coordinates of top-left pixel in photo + * image to be written to. */ + int width, height; /* Dimensions of block of photo image to be + * written to. */ + int srcX, srcY; /* Coordinates of top-left pixel to be used in + * image being read. */ { int fileWidth, fileHeight, maxIntensity; int nLines, nBytes, h, type, count; @@ -191,8 +184,7 @@ FileReadPPM(interp, chan, fileName, format, imageHandle, destX, destY, block.offset[0] = 0; block.offset[1] = 0; block.offset[2] = 0; - } - else { + } else { block.pixelSize = 3; block.offset[0] = 0; block.offset[1] = 1; @@ -261,12 +253,12 @@ FileReadPPM(interp, chan, fileName, format, imageHandle, destX, destY, * * FileWritePPM -- * - * This procedure is invoked to write image data to a file in PPM - * format. + * This function is invoked to write image data to a file in PPM format + * (although we can read PGM files, we never write them). * * Results: - * A standard TCL completion code. If TCL_ERROR is returned - * then an error message is left in the interp's result. + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. * * Side effects: * Data is written to the file given by "fileName". @@ -302,10 +294,10 @@ FileWritePPM(interp, fileName, format, blockPtr) Tcl_Close(NULL, chan); return TCL_ERROR; } - + sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height); Tcl_Write(chan, header, -1); - + pixLinePtr = blockPtr->pixelPtr + blockPtr->offset[0]; greenOffset = blockPtr->offset[1] - blockPtr->offset[0]; blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; @@ -320,9 +312,9 @@ FileWritePPM(interp, fileName, format, blockPtr) for (h = blockPtr->height; h > 0; h--) { pixelPtr = pixLinePtr; for (w = blockPtr->width; w > 0; w--) { - if ((Tcl_Write(chan, (char *) &pixelPtr[0], 1) == -1) - || (Tcl_Write(chan, (char *) &pixelPtr[greenOffset], 1) == -1) - || (Tcl_Write(chan, (char *) &pixelPtr[blueOffset], 1) == -1)) { + if ( Tcl_Write(chan,(char *)&pixelPtr[0], 1) == -1 || + Tcl_Write(chan,(char *)&pixelPtr[greenOffset],1)==-1 || + Tcl_Write(chan,(char *)&pixelPtr[blueOffset],1) ==-1) { goto writeerror; } pixelPtr += blockPtr->pixelSize; @@ -336,7 +328,7 @@ FileWritePPM(interp, fileName, format, blockPtr) } chan = NULL; - writeerror: + writeerror: Tcl_AppendResult(interp, "error writing \"", fileName, "\": ", Tcl_PosixError(interp), NULL); if (chan != NULL) { @@ -350,12 +342,12 @@ FileWritePPM(interp, fileName, format, blockPtr) * * StringWritePPM -- * - * This procedure is invoked to write image data to a string in PPM + * This function is invoked to write image data to a string in PPM * format. * * Results: - * A standard TCL completion code. If TCL_ERROR is returned - * then an error message is left in the interp's result. + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. * * Side effects: * None. @@ -375,10 +367,12 @@ StringWritePPM(interp, format, blockPtr) Tcl_Obj *byteArrayObj; sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height); + /* * Construct a byte array of the right size with the header and * get a pointer to the data part of it. */ + size = strlen(header); byteArrayObj = Tcl_NewByteArrayObj((unsigned char *)header, size); byteArray = Tcl_SetByteArrayLength(byteArrayObj, @@ -392,6 +386,7 @@ StringWritePPM(interp, format, blockPtr) /* * Check if we can do the data move in single action. */ + if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3) && (blockPtr->pitch == (blockPtr->width * 3))) { memcpy(byteArray, pixLinePtr, @@ -413,6 +408,7 @@ StringWritePPM(interp, format, blockPtr) /* * Return the object in the interpreter result. */ + Tcl_SetObjResult(interp, byteArrayObj); return TCL_OK; } @@ -422,12 +418,12 @@ StringWritePPM(interp, format, blockPtr) * * StringMatchPPM -- * - * This procedure is invoked by the photo image type to see if - * a string contains image data in PPM format. + * This function is invoked by the photo image type to see if a string + * contains image data in PPM format. * * Results: - * The return value is >0 if the first characters in file "f" look - * like PPM data, and 0 otherwise. + * The return value is >0 if the first characters in file "f" look like + * PPM data, and 0 otherwise. * * Side effects: * The access position in f may change. @@ -439,9 +435,9 @@ static int StringMatchPPM(dataObj, format, widthPtr, heightPtr, interp) Tcl_Obj *dataObj; /* The image data. */ Tcl_Obj *format; /* User-specified format string, or NULL. */ - int *widthPtr, *heightPtr; /* The dimensions of the image are - * returned here if the file is a valid - * raw PPM file. */ + int *widthPtr, *heightPtr; /* The dimensions of the image are returned + * here if the file is a valid raw PPM + * file. */ Tcl_Interp *interp; /* unused */ { int dummy; @@ -455,13 +451,12 @@ StringMatchPPM(dataObj, format, widthPtr, heightPtr, interp) * * StringReadPPM -- * - * This procedure is called by the photo image type to read - * PPM format data from a string and write it into a given - * photo image. + * This function is called by the photo image type to read PPM format + * data from a string and write it into a given photo image. * * Results: - * A standard TCL completion code. If TCL_ERROR is returned - * then an error message is left in the interp's result. + * A standard TCL completion code. If TCL_ERROR is returned then an error + * message is left in the interp's result. * * Side effects: * New data is added to the image given by imageHandle. @@ -476,12 +471,12 @@ StringReadPPM(interp, dataObj, format, imageHandle, destX, destY, Tcl_Obj *dataObj; /* The image data. */ Tcl_Obj *format; /* User-specified format string, or NULL. */ Tk_PhotoHandle imageHandle; /* The photo image to write into. */ - int destX, destY; /* Coordinates of top-left pixel in - * photo image to be written to. */ - int width, height; /* Dimensions of block of photo image to - * be written to. */ - int srcX, srcY; /* Coordinates of top-left pixel to be used - * in image being read. */ + int destX, destY; /* Coordinates of top-left pixel in photo + * image to be written to. */ + int width, height; /* Dimensions of block of photo image to be + * written to. */ + int srcX, srcY; /* Coordinates of top-left pixel to be used in + * image being read. */ { int fileWidth, fileHeight, maxIntensity; int nLines, nBytes, h, type, count, dataSize; @@ -543,9 +538,9 @@ StringReadPPM(interp, dataObj, format, imageHandle, destX, destY, if (maxIntensity == 255) { /* - * We have all the data in memory, so write everything in one - * go. + * We have all the data in memory, so write everything in one go. */ + if (block.pitch*height < dataSize) { Tcl_AppendResult(interp, "truncated PPM data", NULL); return TCL_ERROR; @@ -606,16 +601,15 @@ StringReadPPM(interp, dataObj, format, imageHandle, destX, destY, * * ReadPPMFileHeader -- * - * This procedure reads the PPM header from the beginning of a - * PPM file and returns information from the header. + * This function reads the PPM header from the beginning of a PPM file + * and returns information from the header. * * Results: - * The return value is PGM if file "f" appears to start with - * a valid PGM header, PPM if "f" appears to start with a valid - * PPM header, and 0 otherwise. If the header is valid, - * then *widthPtr and *heightPtr are modified to hold the - * dimensions of the image and *maxIntensityPtr is modified to - * hold the value of a "fully on" intensity value. + * The return value is PGM if file "f" appears to start with a valid PGM + * header, PPM if "f" appears to start with a valid PPM header, and 0 + * otherwise. If the header is valid, then *widthPtr and *heightPtr are + * modified to hold the dimensions of the image and *maxIntensityPtr is + * modified to hold the value of a "fully on" intensity value. * * Side effects: * The access position in f advances. @@ -625,11 +619,11 @@ StringReadPPM(interp, dataObj, format, imageHandle, destX, destY, static int ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr) - Tcl_Channel chan; /* Image file to read the header from */ - int *widthPtr, *heightPtr; /* The dimensions of the image are - * returned here. */ - int *maxIntensityPtr; /* The maximum intensity value for - * the image is stored here. */ + Tcl_Channel chan; /* Image file to read the header from. */ + int *widthPtr, *heightPtr; /* The dimensions of the image are returned + * here. */ + int *maxIntensityPtr; /* The maximum intensity value for the image + * is stored here. */ { #define BUFFER_SIZE 1000 char buffer[BUFFER_SIZE]; @@ -638,8 +632,8 @@ ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr) char c; /* - * Read 4 space-separated fields from the file, ignoring - * comments (any line that starts with "#"). + * Read 4 space-separated fields from the file, ignoring comments (any + * line that starts with "#"). */ if (Tcl_Read(chan, &c, 1) != 1) { @@ -685,7 +679,8 @@ ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr) i++; } } - done: + + done: buffer[i] = 0; /* @@ -711,16 +706,16 @@ ReadPPMFileHeader(chan, widthPtr, heightPtr, maxIntensityPtr) * * ReadPPMStringHeader -- * - * This procedure reads the PPM header from the beginning of a - * PPM-format string and returns information from the header. + * This function reads the PPM header from the beginning of a PPM-format + * string and returns information from the header. * * Results: - * The return value is PGM if the string appears to start with - * a valid PGM header, PPM if the string appears to start with - * a valid PPM header, and 0 otherwise. If the header is valid, - * then *widthPtr and *heightPtr are modified to hold the - * dimensions of the image and *maxIntensityPtr is modified to - * hold the value of a "fully on" intensity value. + * The return value is PGM if the string appears to start with a valid + * PGM header, PPM if the string appears to start with a valid PPM + * header, and 0 otherwise. If the header is valid, then *widthPtr and + * *heightPtr are modified to hold the dimensions of the image and + * *maxIntensityPtr is modified to hold the value of a "fully on" + * intensity value. * * Side effects: * None @@ -732,10 +727,10 @@ static int ReadPPMStringHeader(dataPtr, widthPtr, heightPtr, maxIntensityPtr, dataBufferPtr, dataSizePtr) Tcl_Obj *dataPtr; /* Object to read the header from. */ - int *widthPtr, *heightPtr; /* The dimensions of the image are - * returned here. */ - int *maxIntensityPtr; /* The maximum intensity value for - * the image is stored here. */ + int *widthPtr, *heightPtr; /* The dimensions of the image are returned + * here. */ + int *maxIntensityPtr; /* The maximum intensity value for the image + * is stored here. */ unsigned char **dataBufferPtr; int *dataSizePtr; { @@ -749,8 +744,8 @@ ReadPPMStringHeader(dataPtr, widthPtr, heightPtr, maxIntensityPtr, dataBuffer = Tcl_GetByteArrayFromObj(dataPtr, &dataSize); /* - * Read 4 space-separated fields from the string, ignoring - * comments (any line that starts with "#"). + * Read 4 space-separated fields from the string, ignoring comments (any + * line that starts with "#"). */ if (dataSize-- < 1) { @@ -800,7 +795,8 @@ ReadPPMStringHeader(dataPtr, widthPtr, heightPtr, maxIntensityPtr, i++; } } - done: + + done: buffer[i] = 0; /* @@ -824,3 +820,11 @@ ReadPPMStringHeader(dataPtr, widthPtr, heightPtr, maxIntensityPtr, } return type; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkImgPhoto.c b/generic/tkImgPhoto.c index 7745db1..2cfe7ff 100644 --- a/generic/tkImgPhoto.c +++ b/generic/tkImgPhoto.c @@ -1,23 +1,23 @@ /* * tkImgPhoto.c -- * - * Implements images of type "photo" for Tk. Photo images are - * stored in full color (32 bits per pixel including alpha channel) - * and displayed using dithering if necessary. + * Implements images of type "photo" for Tk. Photo images are stored in + * full color (32 bits per pixel including alpha channel) and displayed + * using dithering if necessary. * * Copyright (c) 1994 The Australian National University. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright (c) 2002-2003 Donal K. Fellows * Copyright (c) 2003 ActiveState Corporation. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * * Author: Paul Mackerras (paulus@cs.anu.edu.au), * Department of Computer Science, * Australian National University. * - * RCS: @(#) $Id: tkImgPhoto.c,v 1.55 2005/01/31 16:22:14 dkf Exp $ + * RCS: @(#) $Id: tkImgPhoto.c,v 1.56 2005/08/10 22:02:22 dkf Exp $ */ #include "tkInt.h" @@ -32,12 +32,12 @@ * Declaration for internal Xlib function used here: */ -extern int _XInitImageFuncPtrs _ANSI_ARGS_((XImage *image)); +extern int _XInitImageFuncPtrs(XImage *image); /* - * A signed 8-bit integral type. If chars are unsigned and the compiler - * isn't an ANSI one, then we have to use short instead (which wastes - * space) to get signed behavior. + * A signed 8-bit integral type. If chars are unsigned and the compiler isn't + * an ANSI one, then we have to use short instead (which wastes space) to get + * signed behavior. */ #if defined(__STDC__) || defined(_AIX) @@ -51,16 +51,15 @@ extern int _XInitImageFuncPtrs _ANSI_ARGS_((XImage *image)); #endif /* - * An unsigned 32-bit integral type, used for pixel values. - * We use int rather than long here to accommodate those systems - * where longs are 64 bits. + * An unsigned 32-bit integral type, used for pixel values. We use int rather + * than long here to accommodate those systems where longs are 64 bits. */ typedef unsigned int pixel; /* - * The maximum number of pixels to transmit to the server in a - * single XPutImage call. + * The maximum number of pixels to transmit to the server in a single + * XPutImage call. */ #define MAX_PIXELS 65536 @@ -68,16 +67,15 @@ typedef unsigned int pixel; /* * The set of colors required to display a photo image in a window depends on: * - the visual used by the window - * - the palette, which specifies how many levels of each primary - * color to use, and + * - the palette, which specifies how many levels of each primary color to + * use, and * - the gamma value for the image. * - * Pixel values allocated for specific colors are valid only for the - * colormap in which they were allocated. Sets of pixel values - * allocated for displaying photos are re-used in other windows if - * possible, that is, if the display, colormap, palette and gamma - * values match. A hash table is used to locate these sets of pixel - * values, using the following data structure as key: + * Pixel values allocated for specific colors are valid only for the colormap + * in which they were allocated. Sets of pixel values allocated for displaying + * photos are re-used in other windows if possible, that is, if the display, + * colormap, palette and gamma values match. A hash table is used to locate + * these sets of pixel values, using the following data structure as key: */ typedef struct { @@ -89,33 +87,33 @@ typedef struct { } ColorTableId; /* - * For a particular (display, colormap, palette, gamma) combination, - * a data structure of the following type is used to store the allocated - * pixel values and other information: + * For a particular (display, colormap, palette, gamma) combination, a data + * structure of the following type is used to store the allocated pixel values + * and other information: */ typedef struct ColorTable { - ColorTableId id; /* Information used in selecting this - * color table. */ + ColorTableId id; /* Information used in selecting this color + * table. */ int flags; /* See below. */ int refCount; /* Number of instances using this map. */ - int liveRefCount; /* Number of instances which are actually - * in use, using this map. */ + int liveRefCount; /* Number of instances which are actually in + * use, using this map. */ int numColors; /* Number of colors allocated for this map. */ XVisualInfo visualInfo; /* Information about the visual for windows * using this color table. */ - pixel redValues[256]; /* Maps 8-bit values of red intensity - * to a pixel value or index in pixelMap. */ + pixel redValues[256]; /* Maps 8-bit values of red intensity to a + * pixel value or index in pixelMap. */ pixel greenValues[256]; /* Ditto for green intensity */ pixel blueValues[256]; /* Ditto for blue intensity */ unsigned long *pixelMap; /* Actual pixel values allocated. */ unsigned char colorQuant[3][256]; /* Maps 8-bit intensities to quantized - * intensities. The first index is 0 for - * red, 1 for green, 2 for blue. */ + * intensities. The first index is 0 for red, + * 1 for green, 2 for blue. */ } ColorTable; /* @@ -124,12 +122,13 @@ typedef struct ColorTable { * available. * COLOR_WINDOW: 1 means a full 3-D color cube has been * allocated. - * DISPOSE_PENDING: 1 means a call to DisposeColorTable has - * been scheduled as an idle handler, but it - * hasn't been invoked yet. - * MAP_COLORS: 1 means pixel values should be mapped - * through pixelMap. + * DISPOSE_PENDING: 1 means a call to DisposeColorTable has been + * scheduled as an idle handler, but it hasn't + * been invoked yet. + * MAP_COLORS: 1 means pixel values should be mapped through + * pixelMap. */ + #ifdef COLOR_WINDOW #undef COLOR_WINDOW #endif @@ -144,14 +143,13 @@ typedef struct ColorTable { */ typedef struct PhotoMaster { - Tk_ImageMaster tkMaster; /* Tk's token for image master. NULL means - * the image is being deleted. */ - Tcl_Interp *interp; /* Interpreter associated with the - * application using this 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. */ + Tk_ImageMaster tkMaster; /* Tk's token for image master. NULL means the + * image is being deleted. */ + Tcl_Interp *interp; /* Interpreter associated with the application + * using this 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. */ int flags; /* Sundry flags, defined below. */ int width, height; /* Dimensions of image. */ int userWidth, userHeight; /* User-declared image dimensions. */ @@ -160,26 +158,27 @@ typedef struct PhotoMaster { double gamma; /* Display gamma value to correct for. */ char *fileString; /* Name of file to read into image. */ Tcl_Obj *dataString; /* Object to use as contents of image. */ - Tcl_Obj *format; /* User-specified format of data in image - * file or string value. */ + Tcl_Obj *format; /* User-specified format of data in image file + * or string value. */ unsigned char *pix32; /* Local storage for 32-bit image. */ - int ditherX, ditherY; /* Location of first incorrectly - * dithered pixel in image. */ - TkRegion validRegion; /* Tk region indicating which parts of - * the image have valid image data. */ + int ditherX, ditherY; /* Location of first incorrectly dithered + * pixel in image. */ + TkRegion validRegion; /* Tk region indicating which parts of the + * image have valid image data. */ struct PhotoInstance *instancePtr; - /* First in the list of instances - * associated with this master. */ + /* First in the list of instances associated + * with this master. */ } PhotoMaster; /* * Bit definitions for the flags field of a PhotoMaster. * COLOR_IMAGE: 1 means that the image has different color * components. - * IMAGE_CHANGED: 1 means that the instances of this image - * need to be redithered. - * COMPLEX_ALPHA: 1 means that the instances of this image - * have alpha values that aren't 0 or 255. + * IMAGE_CHANGED: 1 means that the instances of this image need + * to be redithered. + * COMPLEX_ALPHA: 1 means that the instances of this image have + * alpha values that aren't 0 or 255, and so need + * the copy-merge-replace renderer . */ #define COLOR_IMAGE 1 @@ -187,9 +186,8 @@ typedef struct PhotoMaster { #define COMPLEX_ALPHA 4 /* - * The following data structure represents all of the instances of - * a photo image in windows on a given screen that are using the - * same colormap. + * The following data structure represents all of the instances of a photo + * image in windows on a given screen that are using the same colormap. */ typedef struct PhotoInstance { @@ -198,34 +196,34 @@ typedef struct PhotoInstance { Colormap colormap; /* The image may only be used in windows with * this particular colormap. */ struct PhotoInstance *nextPtr; - /* Pointer to the next instance in the list - * of instances associated with this master. */ + /* Pointer to the next instance in the list of + * instances associated with this master. */ int refCount; /* Number of instances using this structure. */ Tk_Uid palette; /* Palette for these particular instances. */ double gamma; /* Gamma value for these instances. */ - Tk_Uid defaultPalette; /* Default palette to use if a palette - * is not specified for the master. */ + Tk_Uid defaultPalette; /* Default palette to use if a palette is not + * specified for the master. */ ColorTable *colorTablePtr; /* Pointer to information about colors - * allocated for image display in windows - * like this one. */ + * allocated for image display in windows like + * this one. */ Pixmap pixels; /* X pixmap containing dithered image. */ int width, height; /* Dimensions of the pixmap. */ schar *error; /* Error image, used in dithering. */ XImage *imagePtr; /* Image structure for converted pixels. */ XVisualInfo visualInfo; /* Information about the visual that these * windows are using. */ - GC gc; /* Graphics context for writing images - * to the pixmap. */ + GC gc; /* Graphics context for writing images to the + * pixmap. */ } PhotoInstance; /* - * The following data structure is used to return information - * from ParseSubcommandOptions: + * The following data structure is used to return information from + * ParseSubcommandOptions: */ struct SubcommandOptions { - int options; /* Individual bits indicate which - * options were specified - see below. */ + int options; /* Individual bits indicate which options were + * specified - see below. */ Tcl_Obj *name; /* Name specified without an option. */ int fromX, fromY; /* Values specified for -from option. */ int fromX2, fromY2; /* Second coordinate pair for -from option. */ @@ -239,11 +237,11 @@ struct SubcommandOptions { }; /* - * Bit definitions for use with ParseSubcommandOptions: - * Each bit is set in the allowedOptions parameter on a call to - * ParseSubcommandOptions if that option is allowed for the current - * photo image subcommand. On return, the bit is set in the options - * field of the SubcommandOptions structure if that option was specified. + * Bit definitions for use with ParseSubcommandOptions: each bit is set in the + * allowedOptions parameter on a call to ParseSubcommandOptions if that option + * is allowed for the current photo image subcommand. On return, the bit is + * set in the options field of the SubcommandOptions structure if that option + * was specified. * * OPT_BACKGROUND: Set if -format option allowed/specified. * OPT_COMPOSITE: Set if -compositingrule option allowed/spec'd. @@ -267,8 +265,8 @@ struct SubcommandOptions { #define OPT_ZOOM 0x100 /* - * List of option names. The order here must match the order of - * declarations of the OPT_* constants above. + * List of option names. The order here must match the order of declarations + * of the OPT_* constants above. */ static char *optionNames[] = { @@ -285,9 +283,10 @@ static char *optionNames[] = { }; /* - * Message to generate when an attempt to resize an image fails due - * to memory problems. + * Message to generate when an attempt to resize an image fails due to memory + * problems. */ + #define TK_PHOTO_ALLOC_FAILURE_MESSAGE \ "not enough free memory for image buffer" @@ -295,23 +294,21 @@ static char *optionNames[] = { * Functions used in the type record for photo images. */ -static int ImgPhotoCreate _ANSI_ARGS_((Tcl_Interp *interp, - char *name, int objc, Tcl_Obj *CONST objv[], +static int ImgPhotoCreate(Tcl_Interp *interp, char *name, + int objc, Tcl_Obj *CONST objv[], Tk_ImageType *typePtr, Tk_ImageMaster master, - ClientData *clientDataPtr)); -static ClientData ImgPhotoGet _ANSI_ARGS_((Tk_Window tkwin, - ClientData clientData)); -static void ImgPhotoDisplay _ANSI_ARGS_((ClientData clientData, + ClientData *clientDataPtr); +static ClientData ImgPhotoGet(Tk_Window tkwin, ClientData clientData); +static void ImgPhotoDisplay(ClientData clientData, Display *display, Drawable drawable, int imageX, int imageY, int width, int height, - int drawableX, int drawableY)); -static void ImgPhotoFree _ANSI_ARGS_((ClientData clientData, - Display *display)); -static void ImgPhotoDelete _ANSI_ARGS_((ClientData clientData)); -static int ImgPhotoPostscript _ANSI_ARGS_((ClientData clientData, + int drawableX, int drawableY); +static void ImgPhotoFree(ClientData clientData, Display *display); +static void ImgPhotoDelete(ClientData clientData); +static int ImgPhotoPostscript(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, Tk_PostscriptInfo psInfo, int x, int y, int width, - int height, int prepass)); + int height, int prepass); /* * The type record itself for photo images: @@ -329,11 +326,14 @@ Tk_ImageType tkPhotoImageType = { }; typedef struct ThreadSpecificData { - Tk_PhotoImageFormat *formatList; /* Pointer to the first in the - * list of known photo image formats.*/ - Tk_PhotoImageFormat *oldFormatList; /* Pointer to the first in the - * list of known photo image formats.*/ - int initialized; /* set to 1 if we've initialized the strucuture */ + Tk_PhotoImageFormat *formatList; + /* Pointer to the first in the list of known + * photo image formats.*/ + Tk_PhotoImageFormat *oldFormatList; + /* Pointer to the first in the list of known + * photo image formats.*/ + int initialized; /* Set to 1 if we've initialized the + * strucuture. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; @@ -349,6 +349,7 @@ static Tcl_ThreadDataKey dataKey; /* * Information used for parsing configuration specifications: */ + static Tk_ConfigSpec configSpecs[] = { {TK_CONFIG_STRING, "-file", (char *) NULL, (char *) NULL, (char *) NULL, Tk_Offset(PhotoMaster, fileString), TK_CONFIG_NULL_OK}, @@ -365,8 +366,8 @@ static Tk_ConfigSpec configSpecs[] = { }; /* - * Hash table used to hash from (display, colormap, palette, gamma) - * to ColorTable address. + * Hash table used to hash from (display, colormap, palette, gamma) to + * ColorTable address. */ static Tcl_HashTable imgPhotoColorHash; @@ -386,61 +387,53 @@ static int imgPhotoColorHashInitialized; * Forward declarations */ -static void PhotoFormatThreadExitProc _ANSI_ARGS_(( - ClientData clientData)); -static int ImgPhotoCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[])); -static int ParseSubcommandOptions _ANSI_ARGS_(( +static void PhotoFormatThreadExitProc(ClientData clientData); +static int ImgPhotoCmd(ClientData clientData, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); +static int ParseSubcommandOptions( struct SubcommandOptions *optPtr, Tcl_Interp *interp, int allowedOptions, - int *indexPtr, int objc, Tcl_Obj *CONST objv[])); -static void ImgPhotoCmdDeletedProc _ANSI_ARGS_(( - ClientData clientData)); -static int ImgPhotoConfigureMaster _ANSI_ARGS_(( - Tcl_Interp *interp, PhotoMaster *masterPtr, - int objc, Tcl_Obj *CONST objv[], int flags)); -static void ImgPhotoConfigureInstance _ANSI_ARGS_(( - PhotoInstance *instancePtr)); -static int ToggleComplexAlphaIfNeeded _ANSI_ARGS_(( - PhotoMaster *mPtr)); -static void ImgPhotoBlendComplexAlpha _ANSI_ARGS_(( - XImage *bgImg, PhotoInstance *iPtr, - int xOffset, int yOffset, int width, int height)); -static int ImgPhotoSetSize _ANSI_ARGS_((PhotoMaster *masterPtr, - int width, int height)); -static void ImgPhotoInstanceSetSize _ANSI_ARGS_(( - PhotoInstance *instancePtr)); -static int ImgStringWrite _ANSI_ARGS_((Tcl_Interp *interp, + int *indexPtr, int objc, Tcl_Obj *CONST objv[]); +static void ImgPhotoCmdDeletedProc(ClientData clientData); +static int ImgPhotoConfigureMaster(Tcl_Interp *interp, + PhotoMaster *masterPtr, int objc, + Tcl_Obj *CONST objv[], int flags); +static void ImgPhotoConfigureInstance(PhotoInstance *instancePtr); +static int ToggleComplexAlphaIfNeeded(PhotoMaster *mPtr); +static void ImgPhotoBlendComplexAlpha(XImage *bgImg, + PhotoInstance *iPtr, int xOffset, int yOffset, + int width, int height); +static int ImgPhotoSetSize(PhotoMaster *masterPtr, int width, + int height); +static void ImgPhotoInstanceSetSize(PhotoInstance *instancePtr); +static int ImgStringWrite(Tcl_Interp *interp, Tcl_Obj *formatString, - Tk_PhotoImageBlock *blockPtr)); -static char * ImgGetPhoto _ANSI_ARGS_((PhotoMaster *masterPtr, + Tk_PhotoImageBlock *blockPtr); +static char * ImgGetPhoto(PhotoMaster *masterPtr, Tk_PhotoImageBlock *blockPtr, - struct SubcommandOptions *optPtr)); -static int IsValidPalette _ANSI_ARGS_((PhotoInstance *instancePtr, - CONST char *palette)); -static int CountBits _ANSI_ARGS_((pixel mask)); -static void GetColorTable _ANSI_ARGS_((PhotoInstance *instancePtr)); -static void FreeColorTable _ANSI_ARGS_((ColorTable *colorPtr, - int force)); -static void AllocateColors _ANSI_ARGS_((ColorTable *colorPtr)); -static void DisposeColorTable _ANSI_ARGS_((ClientData clientData)); -static void DisposeInstance _ANSI_ARGS_((ClientData clientData)); -static int ReclaimColors _ANSI_ARGS_((ColorTableId *id, - int numColors)); -static int MatchFileFormat _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Channel chan, char *fileName, Tcl_Obj *formatString, + struct SubcommandOptions *optPtr); +static int IsValidPalette(PhotoInstance *instancePtr, + CONST char *palette); +static int CountBits(pixel mask); +static void GetColorTable(PhotoInstance *instancePtr); +static void FreeColorTable(ColorTable *colorPtr, int force); +static void AllocateColors(ColorTable *colorPtr); +static void DisposeColorTable(ClientData clientData); +static void DisposeInstance(ClientData clientData); +static int ReclaimColors(ColorTableId *id, int numColors); +static int MatchFileFormat(Tcl_Interp *interp, Tcl_Channel chan, + char *fileName, Tcl_Obj *formatString, Tk_PhotoImageFormat **imageFormatPtr, - int *widthPtr, int *heightPtr, int *oldformat)); -static int MatchStringFormat _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *data, Tcl_Obj *formatString, + int *widthPtr, int *heightPtr, int *oldformat); +static int MatchStringFormat(Tcl_Interp *interp, Tcl_Obj *data, + Tcl_Obj *formatString, Tk_PhotoImageFormat **imageFormatPtr, - int *widthPtr, int *heightPtr, int *oldformat)); -static Tcl_ObjCmdProc * PhotoOptionFind _ANSI_ARGS_((Tcl_Interp * interp, - Tcl_Obj *obj)); -static void DitherInstance _ANSI_ARGS_((PhotoInstance *instancePtr, - int x, int y, int width, int height)); -static void PhotoOptionCleanupProc _ANSI_ARGS_(( - ClientData clientData, Tcl_Interp *interp)); + int *widthPtr, int *heightPtr, int *oldformat); +static Tcl_ObjCmdProc * PhotoOptionFind(Tcl_Interp *interp, Tcl_Obj *obj); +static void DitherInstance(PhotoInstance *instancePtr, int x, + int y, int width, int height); +static void PhotoOptionCleanupProc(ClientData clientData, + Tcl_Interp *interp); #undef MIN #define MIN(a, b) ((a) < (b)? (a): (b)) @@ -468,7 +461,7 @@ PhotoFormatThreadExitProc(clientData) ClientData clientData; /* not used */ { Tk_PhotoImageFormat *freePtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); while (tsdPtr->oldFormatList != NULL) { @@ -490,30 +483,29 @@ PhotoFormatThreadExitProc(clientData) * * Tk_CreateOldPhotoImageFormat, Tk_CreatePhotoImageFormat -- * - * This procedure is invoked by an image file handler to register - * a new photo image format and the procedures that handle the - * new format. The procedure is typically invoked during - * Tcl_AppInit. + * This function is invoked by an image file handler to register a new + * photo image format and the functions that handle the new format. The + * function is typically invoked during Tcl_AppInit. * * Results: * None. * * Side effects: - * The new image file format is entered into a table used in the - * photo image "read" and "write" subcommands. + * The new image file format is entered into a table used in the photo + * image "read" and "write" subcommands. * *---------------------------------------------------------------------- */ void Tk_CreateOldPhotoImageFormat(formatPtr) Tk_PhotoImageFormat *formatPtr; - /* Structure describing the format. All of - * the fields except "nextPtr" must be filled - * in by caller. Must not have been passed - * to Tk_CreatePhotoImageFormat previously. */ + /* Structure describing the format. All of the + * fields except "nextPtr" must be filled in + * by caller. Must not have been passed to + * Tk_CreatePhotoImageFormat previously. */ { Tk_PhotoImageFormat *copyPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!tsdPtr->initialized) { @@ -531,13 +523,13 @@ Tk_CreateOldPhotoImageFormat(formatPtr) void Tk_CreatePhotoImageFormat(formatPtr) Tk_PhotoImageFormat *formatPtr; - /* Structure describing the format. All of - * the fields except "nextPtr" must be filled - * in by caller. Must not have been passed - * to Tk_CreatePhotoImageFormat previously. */ + /* Structure describing the format. All of the + * fields except "nextPtr" must be filled in + * by caller. Must not have been passed to + * Tk_CreatePhotoImageFormat previously. */ { Tk_PhotoImageFormat *copyPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (!tsdPtr->initialized) { @@ -562,15 +554,14 @@ Tk_CreatePhotoImageFormat(formatPtr) * * ImgPhotoCreate -- * - * This procedure is called by the Tk image code to create - * a new photo image. + * This function is called by the Tk image code to create a new photo + * image. * * Results: * A standard Tcl result. * * Side effects: - * The data structure for a new photo image is allocated and - * initialized. + * The data structure for a new photo image is allocated and initialized. * *---------------------------------------------------------------------- */ @@ -584,10 +575,10 @@ ImgPhotoCreate(interp, name, objc, objv, typePtr, master, clientDataPtr) Tcl_Obj *CONST objv[]; /* Argument objects for options (doesn't * include image name or type). */ Tk_ImageType *typePtr; /* Pointer to our type record (not used). */ - Tk_ImageMaster master; /* Token for image, to be used by us in - * later callbacks. */ - ClientData *clientDataPtr; /* Store manager's token for image here; - * it will be returned in later callbacks. */ + Tk_ImageMaster master; /* Token for image, to be used by us in later + * callbacks. */ + ClientData *clientDataPtr; /* Store manager's token for image here; it + * will be returned in later callbacks. */ { PhotoMaster *masterPtr; @@ -624,9 +615,9 @@ ImgPhotoCreate(interp, name, objc, objv, typePtr, master, clientDataPtr) * * ImgPhotoCmd -- * - * This procedure is invoked to process the Tcl command that - * corresponds to a photo image. See the user documentation - * for details on what it does. + * This function is invoked to process the Tcl command that corresponds + * to a photo image. See the user documentation for details on what it + * does. * * Results: * A standard Tcl result. @@ -667,11 +658,10 @@ ImgPhotoCmd(clientData, interp, objc, objv) Tk_Window tkwin; Tk_PhotoImageFormat *imageFormat; int imageWidth, imageHeight; - int matched; + int matched, length; Tcl_Channel chan; Tk_PhotoHandle srcHandle; - size_t length; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (objc < 2) { @@ -710,12 +700,12 @@ ImgPhotoCmd(clientData, interp, objc, objv) Tcl_WrongNumArgs(interp, 2, objv, "option"); return TCL_ERROR; } - arg = Tcl_GetStringFromObj(objv[2], (int *) &length); - if (strncmp(arg,"-data", length) == 0) { + arg = Tcl_GetStringFromObj(objv[2], &length); + if (strncmp(arg,"-data", (unsigned) length) == 0) { if (masterPtr->dataString) { Tcl_SetObjResult(interp, masterPtr->dataString); } - } else if (strncmp(arg,"-format", length) == 0) { + } else if (strncmp(arg,"-format", (unsigned) length) == 0) { if (masterPtr->format) { Tcl_SetObjResult(interp, masterPtr->format); } @@ -733,6 +723,7 @@ ImgPhotoCmd(clientData, interp, objc, objv) if (objc == 2) { Tcl_Obj *obj, *subobj; + result = Tk_ConfigureInfo(interp, Tk_MainWindow(interp), configSpecs, (char *) masterPtr, (char *) NULL, 0); if (result != TCL_OK) { @@ -741,14 +732,14 @@ ImgPhotoCmd(clientData, interp, objc, objv) obj = Tcl_NewObj(); subobj = Tcl_NewStringObj("-data {} {} {}", 14); if (masterPtr->dataString) { - Tcl_ListObjAppendElement(interp, subobj, masterPtr->dataString); + Tcl_ListObjAppendElement(NULL, subobj, masterPtr->dataString); } else { Tcl_AppendStringsToObj(subobj, " {}", (char *) NULL); } Tcl_ListObjAppendElement(interp, obj, subobj); subobj = Tcl_NewStringObj("-format {} {} {}", 16); if (masterPtr->format) { - Tcl_ListObjAppendElement(interp, subobj, masterPtr->format); + Tcl_ListObjAppendElement(NULL, subobj, masterPtr->format); } else { Tcl_AppendStringsToObj(subobj, " {}", (char *) NULL); } @@ -756,10 +747,11 @@ ImgPhotoCmd(clientData, interp, objc, objv) Tcl_ListObjAppendList(interp, obj, Tcl_GetObjResult(interp)); Tcl_SetObjResult(interp, obj); return TCL_OK; - } - if (objc == 3) { - char *arg = Tcl_GetStringFromObj(objv[2], (int *) &length); - if (!strncmp(arg, "-data", length)) { + + } else if (objc == 3) { + char *arg = Tcl_GetStringFromObj(objv[2], &length); + + if (length > 1 && !strncmp(arg, "-data", (unsigned) length)) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "-data {} {} {}", (char *) NULL); if (masterPtr->dataString) { @@ -770,7 +762,8 @@ ImgPhotoCmd(clientData, interp, objc, objv) " {}", (char *) NULL); } return TCL_OK; - } else if (!strncmp(arg, "-format", length)) { + } else if (length > 1 && + !strncmp(arg, "-format", (unsigned) length)) { Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "-format {} {} {}", (char *) NULL); if (masterPtr->format) { @@ -898,6 +891,7 @@ ImgPhotoCmd(clientData, interp, objc, objv) /* * photo data command - first parse and check any options given. */ + Tk_ImageStringWriteProc *stringWriteProc = NULL; index = 2; @@ -977,30 +971,32 @@ ImgPhotoCmd(clientData, interp, objc, objv) } /* - * Call the handler's string write procedure to write out - * the image. + * Call the handler's string write function to write out the image. */ data = ImgGetPhoto(masterPtr, &block, &options); if (oldformat) { + typedef (int (*oldStringWriterProc) (Tcl_Interp *interp, + Tcl_DString *dataPtr, char *formatString, + Tk_PhotoImageBlock *blockPtr)); Tcl_DString buffer; Tcl_DStringInit(&buffer); - result = ((int (*) _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_DString *dataPtr, char *formatString, - Tk_PhotoImageBlock *blockPtr))) stringWriteProc) - (interp, &buffer, Tcl_GetString(options.format), &block); + result = ((oldStringWriterProc) stringWriteProc) (interp, &buffer, + Tcl_GetString(options.format), &block); if (result == TCL_OK) { Tcl_DStringResult(interp, &buffer); } else { Tcl_DStringFree(&buffer); } } else { - result = ((int (*) _ANSI_ARGS_((Tcl_Interp *interp, + typedef (int (*newStringWriterProc) (Tcl_Interp *interp, Tcl_Obj *formatString, Tk_PhotoImageBlock *blockPtr, - VOID *dummy))) stringWriteProc) - (interp, options.format, &block, (VOID *) NULL); + VOID *dummy)); + + result = ((newStringWriterProc) stringWriteProc) (interp, + options.format, &block, (VOID *) NULL); } if (options.background) { Tk_FreeColor(options.background); @@ -1061,7 +1057,7 @@ ImgPhotoCmd(clientData, interp, objc, objv) return TCL_ERROR; } - if (MatchStringFormat(interp, options.name ? objv[2]:NULL, + if (MatchStringFormat(interp, options.name ? objv[2]:NULL, options.format, &imageFormat, &imageWidth, &imageHeight, &oldformat) == TCL_OK) { Tcl_Obj *format, *data; @@ -1110,11 +1106,13 @@ ImgPhotoCmd(clientData, interp, objc, objv) &listObjc, &listObjv) != TCL_OK) { break; } + if (y == 0) { if (listObjc == 0) { /* * Lines must be non-empty... */ + break; } dataWidth = listObjc; @@ -1126,14 +1124,15 @@ ImgPhotoCmd(clientData, interp, objc, objv) " have the same number of elements", (char *) NULL); break; } + for (x = 0; x < dataWidth; ++x) { char *colorString = Tcl_GetString(listObjv[x]); XColor color; int tmpr, tmpg, tmpb; /* - * We do not use Tk_GetColorFromObj() because we - * absolutely do not want to invoke the fallback code. + * We do not use Tk_GetColorFromObj() because we absolutely do + * not want to invoke the fallback code. */ if (colorString[0] == '#') { @@ -1188,8 +1187,8 @@ ImgPhotoCmd(clientData, interp, objc, objv) } /* - * Fill in default values for the -to option, then - * copy the block in using Tk_PhotoPutBlock. + * Fill in default values for the -to option, then copy the block in + * using Tk_PhotoPutBlock. */ if (!(options.options & OPT_TO) || (options.toX2 < 0)) { @@ -1241,7 +1240,7 @@ ImgPhotoCmd(clientData, interp, objc, objv) " safe interpreter", (char *) NULL); return TCL_ERROR; } - + /* * Open the image file and look for a handler for it. */ @@ -1261,7 +1260,7 @@ ImgPhotoCmd(clientData, interp, objc, objv) Tcl_Close(NULL, chan); return TCL_ERROR; } - + if (MatchFileFormat(interp, chan, Tcl_GetString(options.name), options.format, &imageFormat, &imageWidth, &imageHeight, &oldformat) != TCL_OK) { @@ -1304,8 +1303,8 @@ ImgPhotoCmd(clientData, interp, objc, objv) } /* - * Call the handler's file read procedure to read the data - * into the image. + * Call the handler's file read function to read the data into the + * image. */ format = options.format; @@ -1329,8 +1328,8 @@ ImgPhotoCmd(clientData, interp, objc, objv) } /* - * Call Dither if any part of the image is not correctly - * dithered at present. + * Call Dither if any part of the image is not correctly dithered at + * present. */ x = masterPtr->ditherX; @@ -1490,7 +1489,7 @@ ImgPhotoCmd(clientData, interp, objc, objv) " safe interpreter", (char *) NULL); return TCL_ERROR; } - + /* * photo write command - first parse and check any options given. */ @@ -1527,8 +1526,8 @@ ImgPhotoCmd(clientData, interp, objc, objv) } /* - * Search for an appropriate image file format handler, - * and give an error if none is found. + * Search for an appropriate image file format handler, and give an + * error if none is found. */ matched = 0; @@ -1575,8 +1574,7 @@ ImgPhotoCmd(clientData, interp, objc, objv) } /* - * Call the handler's file write procedure to write out - * the image. + * Call the handler's file write function to write out the image. */ data = ImgGetPhoto(masterPtr, &block, &options); @@ -1605,10 +1603,9 @@ ImgPhotoCmd(clientData, interp, objc, objv) * * ParseSubcommandOptions -- * - * This procedure is invoked to process one of the options - * which may be specified for the photo image subcommands, - * namely, -from, -to, -zoom, -subsample, -format, -shrink, - * and -compositingrule. + * This function is invoked to process one of the options which may be + * specified for the photo image subcommands, namely, -from, -to, -zoom, + * -subsample, -format, -shrink, and -compositingrule. * * Results: * A standard Tcl result. @@ -1622,14 +1619,14 @@ ImgPhotoCmd(clientData, interp, objc, objv) static int ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv) struct SubcommandOptions *optPtr; - /* Information about the options specified - * and the values given is returned here. */ + /* Information about the options specified and + * the values given is returned here. */ Tcl_Interp *interp; /* Interpreter to use for reporting errors. */ - int allowedOptions; /* Indicates which options are valid for - * the current command. */ - int *optIndexPtr; /* Points to a variable containing the - * current index in objv; this variable is - * updated by this procedure. */ + int allowedOptions; /* Indicates which options are valid for the + * current command. */ + int *optIndexPtr; /* Points to a variable containing the current + * index in objv; this variable is updated by + * this function. */ int objc; /* Number of arguments in objv[]. */ Tcl_Obj *CONST objv[]; /* Arguments to be parsed. */ { @@ -1641,8 +1638,8 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv) for (index = *optIndexPtr; index < objc; *optIndexPtr = ++index) { /* - * We can have one value specified without an option; - * it goes into optPtr->name. + * We can have one value specified without an option; it goes into + * optPtr->name. */ option = Tcl_GetStringFromObj(objv[index], &length); @@ -1674,8 +1671,8 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv) } /* - * If this option is not recognized and allowed, put - * an error message in the interpreter and return. + * If this option is not recognized and allowed, put an error message + * in the interpreter and return. */ if ((allowedOptions & bit) == 0) { @@ -1699,9 +1696,8 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv) } /* - * For the -from, -to, -zoom and -subsample options, - * parse the values given. Report an error if too few - * or too many values are given. + * For the -from, -to, -zoom and -subsample options, parse the values + * given. Report an error if too few or too many values are given. */ if (bit == OPT_BACKGROUND) { @@ -1723,9 +1719,8 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv) } } else if (bit == OPT_FORMAT) { /* - * The -format option takes a single string value. Note - * that parsing this is outside the scope of this - * function. + * The -format option takes a single string value. Note that + * parsing this is outside the scope of this function. */ if (index + 1 < objc) { @@ -1738,8 +1733,8 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv) } } else if (bit == OPT_COMPOSITE) { /* - * The -compositingrule option takes a single value from - * a well-known set. + * The -compositingrule option takes a single value from a + * well-known set. */ if (index + 1 < objc) { @@ -1747,6 +1742,7 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv) * Note that these must match the TK_PHOTO_COMPOSITE_* * constants. */ + static CONST char *compositingRules[] = { "overlay", "set", NULL @@ -1805,62 +1801,62 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv) } /* - * Check the values given and put them in the appropriate - * field of the SubcommandOptions structure. + * Check the values given and put them in the appropriate field of + * the SubcommandOptions structure. */ switch (bit) { - case OPT_FROM: - if ((values[0] < 0) || (values[1] < 0) || ((numValues > 2) - && ((values[2] < 0) || (values[3] < 0)))) { - Tcl_AppendResult(interp, "value(s) for the -from", - " option must be non-negative", (char *) NULL); - return TCL_ERROR; - } - if (numValues <= 2) { - optPtr->fromX = values[0]; - optPtr->fromY = values[1]; - optPtr->fromX2 = -1; - optPtr->fromY2 = -1; - } else { - optPtr->fromX = MIN(values[0], values[2]); - optPtr->fromY = MIN(values[1], values[3]); - optPtr->fromX2 = MAX(values[0], values[2]); - optPtr->fromY2 = MAX(values[1], values[3]); - } - break; - case OPT_SUBSAMPLE: - optPtr->subsampleX = values[0]; - optPtr->subsampleY = values[1]; - break; - case OPT_TO: - if ((values[0] < 0) || (values[1] < 0) || ((numValues > 2) - && ((values[2] < 0) || (values[3] < 0)))) { - Tcl_AppendResult(interp, "value(s) for the -to", - " option must be non-negative", (char *) NULL); - return TCL_ERROR; - } - if (numValues <= 2) { - optPtr->toX = values[0]; - optPtr->toY = values[1]; - optPtr->toX2 = -1; - optPtr->toY2 = -1; - } else { - optPtr->toX = MIN(values[0], values[2]); - optPtr->toY = MIN(values[1], values[3]); - optPtr->toX2 = MAX(values[0], values[2]); - optPtr->toY2 = MAX(values[1], values[3]); - } - break; - case OPT_ZOOM: - if ((values[0] <= 0) || (values[1] <= 0)) { - Tcl_AppendResult(interp, "value(s) for the -zoom", - " option must be positive", (char *) NULL); - return TCL_ERROR; - } - optPtr->zoomX = values[0]; - optPtr->zoomY = values[1]; - break; + case OPT_FROM: + if ((values[0] < 0) || (values[1] < 0) || ((numValues > 2) + && ((values[2] < 0) || (values[3] < 0)))) { + Tcl_AppendResult(interp, "value(s) for the -from", + " option must be non-negative", (char *) NULL); + return TCL_ERROR; + } + if (numValues <= 2) { + optPtr->fromX = values[0]; + optPtr->fromY = values[1]; + optPtr->fromX2 = -1; + optPtr->fromY2 = -1; + } else { + optPtr->fromX = MIN(values[0], values[2]); + optPtr->fromY = MIN(values[1], values[3]); + optPtr->fromX2 = MAX(values[0], values[2]); + optPtr->fromY2 = MAX(values[1], values[3]); + } + break; + case OPT_SUBSAMPLE: + optPtr->subsampleX = values[0]; + optPtr->subsampleY = values[1]; + break; + case OPT_TO: + if ((values[0] < 0) || (values[1] < 0) || ((numValues > 2) + && ((values[2] < 0) || (values[3] < 0)))) { + Tcl_AppendResult(interp, "value(s) for the -to", + " option must be non-negative", (char *) NULL); + return TCL_ERROR; + } + if (numValues <= 2) { + optPtr->toX = values[0]; + optPtr->toY = values[1]; + optPtr->toX2 = -1; + optPtr->toY2 = -1; + } else { + optPtr->toX = MIN(values[0], values[2]); + optPtr->toY = MIN(values[1], values[3]); + optPtr->toX2 = MAX(values[0], values[2]); + optPtr->toY2 = MAX(values[1], values[3]); + } + break; + case OPT_ZOOM: + if ((values[0] <= 0) || (values[1] <= 0)) { + Tcl_AppendResult(interp, "value(s) for the -zoom", + " option must be positive", (char *) NULL); + return TCL_ERROR; + } + optPtr->zoomX = values[0]; + optPtr->zoomY = values[1]; + break; } } @@ -1879,17 +1875,17 @@ ParseSubcommandOptions(optPtr, interp, allowedOptions, optIndexPtr, objc, objv) * * ImgPhotoConfigureMaster -- * - * This procedure is called when a photo image is created or - * reconfigured. It processes configuration options and resets - * any instances of the image. + * This function is called when a photo image is created or reconfigured. + * It processes configuration options and resets any instances of the + * image. * * Results: - * A standard Tcl return value. If TCL_ERROR is returned then - * an error message is left in the masterPtr->interp's result. + * A standard Tcl return value. If TCL_ERROR is returned then an error + * message is left in the masterPtr->interp's result. * * Side effects: - * Existing instances of the image will be redisplayed to match - * the new configuration options. + * Existing instances of the image will be redisplayed to match the new + * configuration options. * *---------------------------------------------------------------------- */ @@ -1901,8 +1897,8 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags) * overall photo image to (re)configure. */ int objc; /* Number of entries in objv. */ Tcl_Obj *CONST objv[]; /* Pairs of configuration options for image. */ - int flags; /* Flags to pass to Tk_ConfigureWidget, - * such as TK_CONFIG_ARGV_ONLY. */ + int flags; /* Flags to pass to Tk_ConfigureWidget, such + * as TK_CONFIG_ARGV_ONLY. */ { PhotoInstance *instancePtr; CONST char *oldFileString, *oldPaletteString; @@ -1946,12 +1942,10 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags) } /* - * Save the current values for fileString and dataString, so we - * can tell if the user specifies them anew. - * IMPORTANT: if the format changes we have to interpret - * "-file" and "-data" again as well!!!!!!! It might be - * that the format string influences how "-data" or "-file" - * is interpreted. + * Save the current values for fileString and dataString, so we can tell + * if the user specifies them anew. IMPORTANT: if the format changes we + * have to interpret "-file" and "-data" again as well! It might be that + * the format string influences how "-data" or "-file" is interpreted. */ oldFileString = masterPtr->fileString; @@ -1982,8 +1976,7 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags) ckfree((char *) args); /* - * Regard the empty string for -file, -data or -format as the null - * value. + * Regard the empty string for -file, -data or -format as the null value. */ if ((masterPtr->fileString != NULL) && (masterPtr->fileString[0] == 0)) { @@ -1992,9 +1985,10 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags) } if (data) { /* - * Force into ByteArray format, which most (all) image handlers - * will use anyway. Empty length means ignore the -data option. + * Force into ByteArray format, which most (all) image handlers will + * use anyway. Empty length means ignore the -data option. */ + (void) Tcl_GetByteArrayFromObj(data, &length); if (length) { Tcl_IncrRefCount(data); @@ -2008,9 +2002,10 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags) } if (format) { /* - * Stringify to ignore -format "". It may come in as a list or - * other object. + * Stringify to ignore -format "". It may come in as a list or other + * object. */ + (void) Tcl_GetStringFromObj(format, &length); if (length) { Tcl_IncrRefCount(format); @@ -2023,8 +2018,8 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags) masterPtr->format = format; } /* - * Set the image to the user-requested size, if any, - * and make sure storage is correctly allocated for this image. + * Set the image to the user-requested size, if any, and make sure storage + * is correctly allocated for this image. */ if (ImgPhotoSetSize(masterPtr, masterPtr->width, @@ -2036,8 +2031,8 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags) } /* - * Read in the image from the file or string if the user has - * specified the -file or -data option. + * Read in the image from the file or string if the user has specified the + * -file or -data option. */ if ((masterPtr->fileString != NULL) @@ -2055,7 +2050,7 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags) (char *) NULL); goto errorExit; } - + chan = Tcl_OpenFileChannel(interp, masterPtr->fileString, "r", 0); if (chan == NULL) { goto errorExit; @@ -2084,9 +2079,8 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags) tempformat = (Tcl_Obj *) Tcl_GetString(tempformat); } result = (*imageFormat->fileReadProc)(interp, chan, - masterPtr->fileString, tempformat, - (Tk_PhotoHandle) masterPtr, 0, 0, - imageWidth, imageHeight, 0, 0); + masterPtr->fileString, tempformat, (Tk_PhotoHandle) masterPtr, + 0, 0, imageWidth, imageHeight, 0, 0); Tcl_Close(NULL, chan); if (result != TCL_OK) { goto errorExit; @@ -2143,9 +2137,9 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags) } /* - * Cycle through all of the instances of this image, regenerating - * the information for each instance. Then force the image to be - * redisplayed everywhere that it is used. + * Cycle through all of the instances of this image, regenerating the + * information for each instance. Then force the image to be redisplayed + * everywhere that it is used. */ for (instancePtr = masterPtr->instancePtr; instancePtr != NULL; @@ -2154,8 +2148,7 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags) } /* - * Inform the generic image code that the image - * has (potentially) changed. + * Inform the generic image code that the image has (potentially) changed. */ Tk_ImageChanged(masterPtr->tkMaster, 0, 0, masterPtr->width, @@ -2188,17 +2181,17 @@ ImgPhotoConfigureMaster(interp, masterPtr, objc, objv, flags) * * ImgPhotoConfigureInstance -- * - * This procedure is called to create displaying information for - * a photo image instance based on the configuration information - * in the master. It is invoked both when new instances are - * created and when the master is reconfigured. + * This function is called to create displaying information for a photo + * image instance based on the configuration information in the master. + * It is invoked both when new instances are created and when the master + * is reconfigured. * * Results: * None. * * Side effects: - * Generates errors via Tcl_BackgroundError if there are problems - * in setting up the instance. + * Generates errors via Tcl_BackgroundError if there are problems in + * setting up the instance. * *---------------------------------------------------------------------- */ @@ -2214,10 +2207,9 @@ ImgPhotoConfigureInstance(instancePtr) XRectangle validBox; /* - * If the -palette configuration option has been set for the master, - * use the value specified for our palette, but only if it is - * a valid palette for our windows. Use the gamma value specified - * the master. + * If the -palette configuration option has been set for the master, use + * the value specified for our palette, but only if it is a valid palette + * for our windows. Use the gamma value specified the master. */ if ((masterPtr->palette && masterPtr->palette[0]) @@ -2229,9 +2221,9 @@ ImgPhotoConfigureInstance(instancePtr) instancePtr->gamma = masterPtr->gamma; /* - * If we don't currently have a color table, or if the one we - * have no longer applies (e.g. because our palette or gamma - * has changed), get a new one. + * If we don't currently have a color table, or if the one we have no + * longer applies (e.g. because our palette or gamma has changed), get a + * new one. */ colorTablePtr = instancePtr->colorTablePtr; @@ -2250,8 +2242,8 @@ ImgPhotoConfigureInstance(instancePtr) GetColorTable(instancePtr); /* - * Create a new XImage structure for sending data to - * the X server, if necessary. + * Create a new XImage structure for sending data to the X server, if + * necessary. */ if (instancePtr->colorTablePtr->flags & BLACK_AND_WHITE) { @@ -2272,12 +2264,11 @@ ImgPhotoConfigureInstance(instancePtr) instancePtr->imagePtr = imagePtr; /* - * Determine the endianness of this machine. - * We create images using the local host's endianness, rather - * than the endianness of the server; otherwise we would have - * to byte-swap any 16 or 32 bit values that we store in the - * image in those situations where the server's endianness - * is different from ours. + * Determine the endianness of this machine. We create images + * using the local host's endianness, rather than the endianness + * of the server; otherwise we would have to byte-swap any 16 or + * 32 bit values that we store in the image in those situations + * where the server's endianness is different from ours. * * FIXME: use autoconf to figure this out. */ @@ -2298,11 +2289,10 @@ ImgPhotoConfigureInstance(instancePtr) } /* - * If the user has specified a width and/or height for the master - * which is different from our current width/height, set the size - * to the values specified by the user. If we have no pixmap, we - * do this also, since it has the side effect of allocating a - * pixmap for us. + * If the user has specified a width and/or height for the master which is + * different from our current width/height, set the size to the values + * specified by the user. If we have no pixmap, we do this also, since it + * has the side effect of allocating a pixmap for us. */ if ((instancePtr->pixels == None) || (instancePtr->error == NULL) @@ -2330,16 +2320,15 @@ ImgPhotoConfigureInstance(instancePtr) * * ImgPhotoGet -- * - * This procedure is called for each use of a photo image in a - * widget. + * This function is called for each use of a photo image in a widget. * * Results: - * The return value is a token for the instance, which is passed - * back to us in calls to ImgPhotoDisplay and ImgPhotoFree. + * The return value is a token for the instance, which is passed back to + * us in calls to ImgPhotoDisplay and ImgPhotoFree. * * Side effects: - * A data structure is set up for the instance (or, an existing - * instance is re-used for the new one). + * A data structure is set up for the instance (or, an existing instance + * is re-used for the new one). * *---------------------------------------------------------------------- */ @@ -2362,30 +2351,30 @@ ImgPhotoGet(tkwin, masterData) XGCValues gcValues; /* - * Table of "best" choices for palette for PseudoColor displays - * with between 3 and 15 bits/pixel. + * Table of "best" choices for palette for PseudoColor displays with + * between 3 and 15 bits/pixel. */ static int paletteChoice[13][3] = { /* #red, #green, #blue */ - {2, 2, 2, /* 3 bits, 8 colors */}, - {2, 3, 2, /* 4 bits, 12 colors */}, - {3, 4, 2, /* 5 bits, 24 colors */}, - {4, 5, 3, /* 6 bits, 60 colors */}, - {5, 6, 4, /* 7 bits, 120 colors */}, - {7, 7, 4, /* 8 bits, 198 colors */}, - {8, 10, 6, /* 9 bits, 480 colors */}, - {10, 12, 8, /* 10 bits, 960 colors */}, - {14, 15, 9, /* 11 bits, 1890 colors */}, - {16, 20, 12, /* 12 bits, 3840 colors */}, - {20, 24, 16, /* 13 bits, 7680 colors */}, - {26, 30, 20, /* 14 bits, 15600 colors */}, - {32, 32, 30, /* 15 bits, 30720 colors */} + {2, 2, 2, /* 3 bits, 8 colors */}, + {2, 3, 2, /* 4 bits, 12 colors */}, + {3, 4, 2, /* 5 bits, 24 colors */}, + {4, 5, 3, /* 6 bits, 60 colors */}, + {5, 6, 4, /* 7 bits, 120 colors */}, + {7, 7, 4, /* 8 bits, 198 colors */}, + {8, 10, 6, /* 9 bits, 480 colors */}, + {10, 12, 8, /* 10 bits, 960 colors */}, + {14, 15, 9, /* 11 bits, 1890 colors */}, + {16, 20, 12, /* 12 bits, 3840 colors */}, + {20, 24, 16, /* 13 bits, 7680 colors */}, + {26, 30, 20, /* 14 bits, 15600 colors */}, + {32, 32, 30, /* 15 bits, 30720 colors */} }; /* - * See if there is already an instance for windows using - * the same colormap. If so then just re-use it. + * See if there is already an instance for windows using the same + * colormap. If so then just re-use it. */ colormap = Tk_Colormap(tkwin); @@ -2393,7 +2382,6 @@ ImgPhotoGet(tkwin, masterData) instancePtr = instancePtr->nextPtr) { if ((colormap == instancePtr->colormap) && (Tk_Display(tkwin) == instancePtr->display)) { - /* * Re-use this instance. */ @@ -2435,8 +2423,7 @@ ImgPhotoGet(tkwin, masterData) masterPtr->instancePtr = instancePtr; /* - * Obtain information about the visual and decide on the - * default palette. + * Obtain information about the visual and decide on the default palette. */ visualInfo.screen = Tk_ScreenNumber(tkwin); @@ -2449,33 +2436,33 @@ ImgPhotoGet(tkwin, masterData) if (visInfoPtr != NULL) { instancePtr->visualInfo = *visInfoPtr; switch (visInfoPtr->class) { - case DirectColor: - case TrueColor: - nRed = 1 << CountBits(visInfoPtr->red_mask); - nGreen = 1 << CountBits(visInfoPtr->green_mask); - nBlue = 1 << CountBits(visInfoPtr->blue_mask); + case DirectColor: + case TrueColor: + nRed = 1 << CountBits(visInfoPtr->red_mask); + nGreen = 1 << CountBits(visInfoPtr->green_mask); + nBlue = 1 << CountBits(visInfoPtr->blue_mask); + mono = 0; + break; + case PseudoColor: + case StaticColor: + if (visInfoPtr->depth > 15) { + nRed = 32; + nGreen = 32; + nBlue = 32; mono = 0; - break; - case PseudoColor: - case StaticColor: - if (visInfoPtr->depth > 15) { - nRed = 32; - nGreen = 32; - nBlue = 32; - mono = 0; - } else if (visInfoPtr->depth >= 3) { - int *ip = paletteChoice[visInfoPtr->depth - 3]; - - nRed = ip[0]; - nGreen = ip[1]; - nBlue = ip[2]; - mono = 0; - } - break; - case GrayScale: - case StaticGray: - nRed = 1 << visInfoPtr->depth; - break; + } else if (visInfoPtr->depth >= 3) { + int *ip = paletteChoice[visInfoPtr->depth - 3]; + + nRed = ip[0]; + nGreen = ip[1]; + nBlue = ip[2]; + mono = 0; + } + break; + case GrayScale: + case StaticGray: + nRed = 1 << visInfoPtr->depth; + break; } XFree((char *) visInfoPtr); @@ -2501,8 +2488,8 @@ ImgPhotoGet(tkwin, masterData) GCForeground|GCBackground|GCGraphicsExposures, &gcValues); /* - * Set configuration options and finish the initialization of the instance. - * This will also dither the image if necessary. + * Set configuration options and finish the initialization of the + * instance. This will also dither the image if necessary. */ ImgPhotoConfigureInstance(instancePtr); @@ -2524,9 +2511,9 @@ ImgPhotoGet(tkwin, masterData) * * ToggleComplexAlphaIfNeeded -- * - * This procedure is called when an image is modified to - * check if any partially transparent pixels exist, which - * requires blending instead of straight copy. + * This function is called when an image is modified to check if any + * partially transparent pixels exist, which requires blending instead of + * straight copy. * * Results: * None. @@ -2551,7 +2538,7 @@ ToggleComplexAlphaIfNeeded(PhotoMaster *mPtr) */ mPtr->flags &= ~COMPLEX_ALPHA; - c += 3; /* start at first alpha byte */ + c += 3; /* start at first alpha byte */ for (; c < end; c += 4) { if (*c && *c != 255) { mPtr->flags |= COMPLEX_ALPHA; @@ -2566,8 +2553,13 @@ ToggleComplexAlphaIfNeeded(PhotoMaster *mPtr) * * ImgPhotoBlendComplexAlpha -- * - * This procedure is called when an image with partially - * transparent pixels must be drawn over another image. + * This function is called when an image with partially transparent + * pixels must be drawn over another image. It blends the photo data onto + * a local copy of the surface that we are drawing on, *including* the + * pixels drawn by everything that should be drawn underneath the image. + * + * Much of this code has hard-coded values in for speed because this + * routine is performance critical for complex image drawing. * * Results: * None. @@ -2580,19 +2572,25 @@ ToggleComplexAlphaIfNeeded(PhotoMaster *mPtr) /* * This should work on all platforms that set mask and shift data properly - * from the visualInfo. - * RGB is really only a 24+ bpp version whereas RGB15 is the correct version - * and works for 15bpp+, but it slower, so it's only used for 15bpp+. + * from the visualInfo. RGB is really only a 24+ bpp version whereas RGB15 is + * the correct version and works for 15bpp+, but it slower, so it's only used + * for 15bpp+. * * Note that Win32 pre-defines those operations that we really need. */ #ifndef __WIN32__ -#define GetRValue(rgb) (UCHAR((rgb & red_mask) >> red_shift)) -#define GetGValue(rgb) (UCHAR((rgb & green_mask) >> green_shift)) -#define GetBValue(rgb) (UCHAR((rgb & blue_mask) >> blue_shift)) -#define RGB(r,g,b) ((unsigned)((UCHAR(r)<<red_shift)|(UCHAR(g)<<green_shift)|(UCHAR(b)<<blue_shift))) -#define RGB15(r,g,b) ((unsigned)(((r*red_mask/255)&red_mask)|((g*green_mask/255)&green_mask)|((b*blue_mask/255)&blue_mask))) +#define GetRValue(rgb) (UCHAR(((rgb) & red_mask) >> red_shift)) +#define GetGValue(rgb) (UCHAR(((rgb) & green_mask) >> green_shift)) +#define GetBValue(rgb) (UCHAR(((rgb) & blue_mask) >> blue_shift)) +#define RGB(r, g, b) ((unsigned)( \ + (UCHAR(r) << red_shift) | \ + (UCHAR(g) << green_shift) | \ + (UCHAR(b) << blue_shift) )) +#define RGB15(r, g, b) ((unsigned)( \ + (((r) * red_mask / 255) & red_mask) | \ + (((g) * green_mask / 255) & green_mask) | \ + (((b) * blue_mask / 255) & blue_mask) )) #endif /* !__WIN32__ */ static void @@ -2609,19 +2607,19 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height) unsigned char *masterPtr; /* - * This blending is an integer version of the Source-Over - * compositing rule (see Porter&Duff, "Compositing Digital - * Images", proceedings of SIGGRAPH 1984) that has been hard-coded - * (for speed) to work with targetting a solid surface. + * This blending is an integer version of the Source-Over compositing rule + * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH + * 1984) that has been hard-coded (for speed) to work with targetting a + * solid surface. */ #define ALPHA_BLEND(bgPix, imgPix, alpha, unalpha) \ ((bgPix * unalpha + imgPix * alpha) / 255) /* - * We have to get the mask and shift info from the visual on - * non-Win32 so that the macros Get*Value(), RGB() and RGB15() - * work correctly. This might be cached for better performance. + * We have to get the mask and shift info from the visual on non-Win32 so + * that the macros Get*Value(), RGB() and RGB15() work correctly. This + * might be cached for better performance. */ #ifndef __WIN32__ @@ -2647,9 +2645,9 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height) #endif /* !__WIN32__ */ /* - * Only unix requires the special case for <24bpp. It varies with - * 3 extra shifts and uses RGB15. The 24+bpp version could also - * then be further optimized. + * Only unix requires the special case for <24bpp. It varies with 3 extra + * shifts and uses RGB15. The 24+bpp version could also then be further + * optimized. */ #if !(defined(__WIN32__) || defined(MAC_OSX_TK)) @@ -2664,14 +2662,17 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height) for (x = 0; x < width; x++) { masterPtr = alphaAr + ((line + x + xOffset) * 4); alpha = masterPtr[3]; + /* * Ignore pixels that are fully transparent */ + if (alpha) { /* * We could perhaps be more efficient than XGetPixel for * 24 and 32 bit displays, but this seems "fast enough". */ + r = masterPtr[0]; g = masterPtr[1]; b = masterPtr[2]; @@ -2679,13 +2680,14 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height) /* * Only blend pixels that have some transparency */ + unsigned char ra, ga, ba; pixel = XGetPixel(bgImg, x, y); ra = GetRValue(pixel) << red_mlen; ga = GetGValue(pixel) << green_mlen; ba = GetBValue(pixel) << blue_mlen; - unalpha = 255 - alpha; + unalpha = 255 - alpha; /* calculate once */ r = ALPHA_BLEND(ra, r, alpha, unalpha); g = ALPHA_BLEND(ga, g, alpha, unalpha); b = ALPHA_BLEND(ba, b, alpha, unalpha); @@ -2703,14 +2705,17 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height) for (x = 0; x < width; x++) { masterPtr = alphaAr + ((line + x + xOffset) * 4); alpha = masterPtr[3]; + /* * Ignore pixels that are fully transparent */ + if (alpha) { /* - * We could perhaps be more efficient than XGetPixel for - * 24 and 32 bit displays, but this seems "fast enough". + * We could perhaps be more efficient than XGetPixel for 24 + * and 32 bit displays, but this seems "fast enough". */ + r = masterPtr[0]; g = masterPtr[1]; b = masterPtr[2]; @@ -2718,13 +2723,14 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height) /* * Only blend pixels that have some transparency */ + unsigned char ra, ga, ba; pixel = XGetPixel(bgImg, x, y); ra = GetRValue(pixel); ga = GetGValue(pixel); ba = GetBValue(pixel); - unalpha = 255 - alpha; + unalpha = 255 - alpha; /* calculate once */ r = ALPHA_BLEND(ra, r, alpha, unalpha); g = ALPHA_BLEND(ga, g, alpha, unalpha); b = ALPHA_BLEND(ba, b, alpha, unalpha); @@ -2733,7 +2739,6 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height) } } } - #undef ALPHA_BLEND } @@ -2742,7 +2747,7 @@ ImgPhotoBlendComplexAlpha(bgImg, iPtr, xOffset, yOffset, width, height) * * ImgPhotoDisplay -- * - * This procedure is invoked to draw a photo image. + * This function is invoked to draw a photo image. * * Results: * None. @@ -2757,21 +2762,22 @@ static void ImgPhotoDisplay(clientData, display, drawable, imageX, imageY, width, height, drawableX, drawableY) ClientData clientData; /* Pointer to PhotoInstance structure for - * for instance to be displayed. */ + * instance to be displayed. */ Display *display; /* Display on which to draw image. */ Drawable drawable; /* Pixmap or window in which to draw image. */ - int imageX, imageY; /* Upper-left corner of region within image - * to draw. */ - int width, height; /* Dimensions of region within image to draw. */ - int drawableX, drawableY; /* Coordinates within drawable that - * correspond to imageX and imageY. */ + int imageX, imageY; /* Upper-left corner of region within image to + * draw. */ + int width, height; /* Dimensions of region within image to + * draw. */ + int drawableX, drawableY; /* Coordinates within drawable that correspond + * to imageX and imageY. */ { PhotoInstance *instancePtr = (PhotoInstance *) clientData; XVisualInfo visInfo = instancePtr->visualInfo; /* - * If there's no pixmap, it means that an error occurred - * while creating the image instance so it can't be displayed. + * If there's no pixmap, it means that an error occurred while creating + * the image instance so it can't be displayed. */ if (instancePtr->pixels == None) { @@ -2788,11 +2794,14 @@ ImgPhotoDisplay(clientData, display, drawable, imageX, imageY, width, * Create an error handler to suppress the case where the input was * not properly constrained, which can cause an X error. [Bug 979239] */ + handler = Tk_CreateErrorHandler(display, -1, -1, -1, (Tk_ErrorProc *) NULL, (ClientData) NULL); + /* * Pull the current background from the display to blend with */ + bgImg = XGetImage(display, drawable, drawableX, drawableY, (unsigned int)width, (unsigned int)height, AllPlanes, ZPixmap); if (bgImg == NULL) { @@ -2800,13 +2809,14 @@ ImgPhotoDisplay(clientData, display, drawable, imageX, imageY, width, return; } - ImgPhotoBlendComplexAlpha(bgImg, instancePtr, - imageX, imageY, width, height); + ImgPhotoBlendComplexAlpha(bgImg, instancePtr, imageX, imageY, width, + height); /* - * Color info is unimportant as we only do this operation for - * depth >= 15. + * Color info is unimportant as we only do this operation for depth >= + * 15. */ + TkPutImage(NULL, 0, display, drawable, instancePtr->gc, bgImg, 0, 0, drawableX, drawableY, (unsigned int) width, (unsigned int) height); @@ -2814,21 +2824,22 @@ ImgPhotoDisplay(clientData, display, drawable, imageX, imageY, width, Tk_DeleteErrorHandler(handler); } else { /* - * masterPtr->region describes which parts of the image contain - * valid data. We set this region as the clip mask for the gc, - * setting its origin appropriately, and use it when drawing the - * image. + * masterPtr->region describes which parts of the image contain valid + * data. We set this region as the clip mask for the gc, setting its + * origin appropriately, and use it when drawing the image. */ - TkSetRegion(display, instancePtr->gc, instancePtr->masterPtr->validRegion); + + TkSetRegion(display, instancePtr->gc, + instancePtr->masterPtr->validRegion); XSetClipOrigin(display, instancePtr->gc, drawableX - imageX, - drawableY - imageY); + drawableY - imageY); XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc, - imageX, imageY, (unsigned) width, (unsigned) height, - drawableX, drawableY); + imageX, imageY, (unsigned) width, (unsigned) height, + drawableX, drawableY); XSetClipMask(display, instancePtr->gc, None); XSetClipOrigin(display, instancePtr->gc, 0, 0); } - XFlush (display); + XFlush(display); } /* @@ -2836,10 +2847,9 @@ ImgPhotoDisplay(clientData, display, drawable, imageX, imageY, width, * * ImgPhotoFree -- * - * This procedure is called when a widget ceases to use a - * particular instance of an image. We don't actually get - * rid of the instance until later because we may be about - * to get this instance again. + * This function is called when a widget ceases to use a particular + * instance of an image. We don't actually get rid of the instance until + * later because we may be about to get this instance again. * * Results: * None. @@ -2853,8 +2863,9 @@ ImgPhotoDisplay(clientData, display, drawable, imageX, imageY, width, static void ImgPhotoFree(clientData, display) ClientData clientData; /* Pointer to PhotoInstance structure for - * for instance to be displayed. */ - Display *display; /* Display containing window that used image. */ + * instance to be displayed. */ + Display *display; /* Display containing window that used + * image. */ { PhotoInstance *instancePtr = (PhotoInstance *) clientData; ColorTable *colorPtr; @@ -2865,17 +2876,17 @@ ImgPhotoFree(clientData, display) } /* - * There are no more uses of the image within this widget. - * Decrement the count of live uses of its color table, so - * that its colors can be reclaimed if necessary, and - * set up an idle call to free the instance structure. + * There are no more uses of the image within this widget. Decrement the + * count of live uses of its color table, so that its colors can be + * reclaimed if necessary, and set up an idle call to free the instance + * structure. */ colorPtr = instancePtr->colorTablePtr; if (colorPtr != NULL) { colorPtr->liveRefCount -= 1; } - + Tcl_DoWhenIdle(DisposeInstance, (ClientData) instancePtr); } @@ -2884,8 +2895,8 @@ ImgPhotoFree(clientData, display) * * ImgPhotoDelete -- * - * This procedure is called by the image code to delete the - * master structure for an image. + * This function is called by the image code to delete the master + * structure for an image. * * Results: * None. @@ -2898,8 +2909,8 @@ ImgPhotoFree(clientData, display) static void ImgPhotoDelete(masterData) - ClientData masterData; /* Pointer to PhotoMaster structure for - * image. Must not have any more instances. */ + ClientData masterData; /* Pointer to PhotoMaster structure for image. + * Must not have any more instances. */ { PhotoMaster *masterPtr = (PhotoMaster *) masterData; PhotoInstance *instancePtr; @@ -2936,8 +2947,8 @@ ImgPhotoDelete(masterData) * * ImgPhotoCmdDeletedProc -- * - * This procedure is invoked when the image command for an image - * is deleted. It deletes the image. + * This function is invoked when the image command for an image is + * deleted. It deletes the image. * * Results: * None. @@ -2966,13 +2977,13 @@ ImgPhotoCmdDeletedProc(clientData) * * ImgPhotoSetSize -- * - * This procedure reallocates the image storage and instance - * pixmaps for a photo image, as necessary, to change the - * image's size to `width' x `height' pixels. + * This function reallocates the image storage and instance pixmaps for a + * photo image, as necessary, to change the image's size to `width' x + * `height' pixels. * * Results: - * TCL_OK if successful, TCL_ERROR if failure occurred (currently - * just with memory allocation.) + * TCL_OK if successful, TCL_ERROR if failure occurred (currently just + * with memory allocation.) * * Side effects: * Storage gets reallocated, for the master and all its instances. @@ -3002,19 +3013,22 @@ ImgPhotoSetSize(masterPtr, width, height) pitch = width * 4; /* - * Test if we're going to (re)allocate the main buffer now, so - * that any failures will leave the photo unchanged. + * Test if we're going to (re)allocate the main buffer now, so that any + * failures will leave the photo unchanged. */ + if ((width != masterPtr->width) || (height != masterPtr->height) || (masterPtr->pix32 == NULL)) { /* * Not a u-long, but should be one. */ + unsigned /*long*/ newPixSize = (unsigned /*long*/) (height * pitch); /* * Some mallocs() really hate allocating zero bytes. [Bug 619544] */ + if (newPixSize == 0) { newPix32 = NULL; } else { @@ -3026,8 +3040,8 @@ ImgPhotoSetSize(masterPtr, width, height) } /* - * We have to trim the valid region if it is currently - * larger than the new image size. + * We have to trim the valid region if it is currently larger than the new + * image size. */ TkClipBox(masterPtr->validRegion, &validBox); @@ -3046,15 +3060,16 @@ ImgPhotoSetSize(masterPtr, width, height) } /* - * Use the reallocated storage (allocation above) for the 32-bit - * image and copy over valid regions. Note that this test is true - * precisely when the allocation has already been done. + * Use the reallocated storage (allocation above) for the 32-bit image and + * copy over valid regions. Note that this test is true precisely when the + * allocation has already been done. */ + if (newPix32 != NULL) { /* - * Zero the new array. The dithering code shouldn't read the - * areas outside validBox, but they might be copied to another - * photo image or written to a file. + * Zero the new array. The dithering code shouldn't read the areas + * outside validBox, but they might be copied to another photo image + * or written to a file. */ if ((masterPtr->pix32 != NULL) @@ -3072,10 +3087,9 @@ ImgPhotoSetSize(masterPtr, width, height) } if (masterPtr->pix32 != NULL) { - /* - * Copy the common area over to the new array array and - * free the old array. + * Copy the common area over to the new array array and free the + * old array. */ if (width == masterPtr->width) { @@ -3090,7 +3104,6 @@ ImgPhotoSetSize(masterPtr, width, height) (size_t) (validBox.height * pitch)); } else if ((validBox.width > 0) && (validBox.height > 0)) { - /* * Area to be copied is not contiguous - copy line by line. */ @@ -3114,8 +3127,8 @@ ImgPhotoSetSize(masterPtr, width, height) masterPtr->height = height; /* - * Dithering will be correct up to the end of the last - * pre-existing complete scanline. + * Dithering will be correct up to the end of the last pre-existing + * complete scanline. */ if ((validBox.x > 0) || (validBox.y > 0)) { @@ -3152,9 +3165,9 @@ ImgPhotoSetSize(masterPtr, width, height) * * ImgPhotoInstanceSetSize -- * - * This procedure reallocates the instance pixmap and dithering - * error array for a photo instance, as necessary, to change the - * image's size to `width' x `height' pixels. + * This function reallocates the instance pixmap and dithering error + * array for a photo instance, as necessary, to change the image's size + * to `width' x `height' pixels. * * Results: * None. @@ -3167,8 +3180,7 @@ ImgPhotoSetSize(masterPtr, width, height) static void ImgPhotoInstanceSetSize(instancePtr) - PhotoInstance *instancePtr; /* Instance whose size is to be - * changed. */ + PhotoInstance *instancePtr; /* Instance whose size is to be changed. */ { PhotoMaster *masterPtr; schar *newError; @@ -3185,7 +3197,7 @@ ImgPhotoInstanceSetSize(instancePtr) || (instancePtr->pixels == None)) { newPixmap = Tk_GetPixmap(instancePtr->display, RootWindow(instancePtr->display, - instancePtr->visualInfo.screen), + instancePtr->visualInfo.screen), (masterPtr->width > 0) ? masterPtr->width: 1, (masterPtr->height > 0) ? masterPtr->height: 1, instancePtr->visualInfo.depth); @@ -3196,11 +3208,11 @@ ImgPhotoInstanceSetSize(instancePtr) /* * The following is a gross hack needed to properly support colormaps - * under Windows. Before the pixels can be copied to the pixmap, - * the relevent colormap must be associated with the drawable. - * Normally we can infer this association from the window that - * was used to create the pixmap. However, in this case we're - * using the root window, so we have to be more explicit. + * under Windows. Before the pixels can be copied to the pixmap, the + * relevent colormap must be associated with the drawable. Normally we + * can infer this association from the window that was used to create + * the pixmap. However, in this case we're using the root window, so + * we have to be more explicit. */ TkSetPixmapColormap(newPixmap, instancePtr->colormap); @@ -3209,6 +3221,7 @@ ImgPhotoInstanceSetSize(instancePtr) /* * Copy any common pixels from the old pixmap and free it. */ + XCopyArea(instancePtr->display, instancePtr->pixels, newPixmap, instancePtr->gc, validBox.x, validBox.y, validBox.width, validBox.height, validBox.x, validBox.y); @@ -3226,8 +3239,8 @@ ImgPhotoInstanceSetSize(instancePtr) masterPtr->height * masterPtr->width * 3 * sizeof(schar)); /* - * Zero the new array so that we don't get bogus error - * values propagating into areas we dither later. + * Zero the new array so that we don't get bogus error values + * propagating into areas we dither later. */ if ((instancePtr->error != NULL) @@ -3245,21 +3258,19 @@ ImgPhotoInstanceSetSize(instancePtr) } } else { memset((VOID *) newError, 0, (size_t) - masterPtr->height * masterPtr->width * 3 * sizeof(schar)); + masterPtr->height * masterPtr->width *3*sizeof(schar)); } } else { newError = NULL; } if (instancePtr->error != NULL) { - /* - * Copy the common area over to the new array - * and free the old array. + * Copy the common area over to the new array and free the old + * array. */ if (masterPtr->width == instancePtr->width) { - offset = validBox.y * masterPtr->width * 3; memcpy((VOID *) (newError + offset), (VOID *) (instancePtr->error + offset), @@ -3267,11 +3278,11 @@ ImgPhotoInstanceSetSize(instancePtr) * masterPtr->width * 3 * sizeof(schar))); } else if (validBox.width > 0 && validBox.height > 0) { + errDestPtr = newError + + (validBox.y * masterPtr->width + validBox.x) * 3; + errSrcPtr = instancePtr->error + + (validBox.y * instancePtr->width + validBox.x) * 3; - errDestPtr = newError - + (validBox.y * masterPtr->width + validBox.x) * 3; - errSrcPtr = instancePtr->error - + (validBox.y * instancePtr->width + validBox.x) * 3; for (h = validBox.height; h > 0; --h) { memcpy((VOID *) errDestPtr, (VOID *) errSrcPtr, validBox.width * 3 * sizeof(schar)); @@ -3294,9 +3305,8 @@ ImgPhotoInstanceSetSize(instancePtr) * * IsValidPalette -- * - * This procedure is called to check whether a value given for - * the -palette option is valid for a particular instance - * of a photo image. + * This function is called to check whether a value given for the + * -palette option is valid for a particular instance of a photo image. * * Results: * A boolean value: 1 if the palette is acceptable, 0 otherwise. @@ -3309,16 +3319,15 @@ ImgPhotoInstanceSetSize(instancePtr) static int IsValidPalette(instancePtr, palette) - PhotoInstance *instancePtr; /* Instance to which the palette - * specification is to be applied. */ - CONST char *palette; /* Palette specification string. */ + PhotoInstance *instancePtr; /* Instance to which the palette specification + * is to be applied. */ + CONST char *palette; /* Palette specification string. */ { int nRed, nGreen, nBlue, mono, numColors; char *endp; /* - * First parse the specification: it must be of the form - * %d or %d/%d/%d. + * First parse the specification: it must be of the form %d or %d/%d/%d. */ nRed = strtol(palette, &endp, 10); @@ -3347,32 +3356,30 @@ IsValidPalette(instancePtr, palette) } switch (instancePtr->visualInfo.class) { - case DirectColor: - case TrueColor: - if ((nRed > (1 << CountBits(instancePtr->visualInfo.red_mask))) - || (nGreen > (1 - << CountBits(instancePtr->visualInfo.green_mask))) - || (nBlue > (1 - << CountBits(instancePtr->visualInfo.blue_mask)))) { - return 0; - } - break; - case PseudoColor: - case StaticColor: - numColors = nRed; - if (!mono) { - numColors *= nGreen*nBlue; - } - if (numColors > (1 << instancePtr->visualInfo.depth)) { - return 0; - } - break; - case GrayScale: - case StaticGray: - if (!mono || (nRed > (1 << instancePtr->visualInfo.depth))) { - return 0; - } - break; + case DirectColor: + case TrueColor: + if ((nRed > (1 << CountBits(instancePtr->visualInfo.red_mask))) + || (nGreen>(1<<CountBits(instancePtr->visualInfo.green_mask))) + || (nBlue>(1<<CountBits(instancePtr->visualInfo.blue_mask)))) { + return 0; + } + break; + case PseudoColor: + case StaticColor: + numColors = nRed; + if (!mono) { + numColors *= nGreen*nBlue; + } + if (numColors > (1 << instancePtr->visualInfo.depth)) { + return 0; + } + break; + case GrayScale: + case StaticGray: + if (!mono || (nRed > (1 << instancePtr->visualInfo.depth))) { + return 0; + } + break; } return 1; @@ -3383,7 +3390,7 @@ IsValidPalette(instancePtr, palette) * * CountBits -- * - * This procedure counts how many bits are set to 1 in `mask'. + * This function counts how many bits are set to 1 in `mask'. * * Results: * The integer number of bits. @@ -3400,8 +3407,9 @@ CountBits(mask) { int n; - for( n = 0; mask != 0; mask &= mask - 1 ) + for (n=0 ; mask!=0 ; mask&=mask-1) { n++; + } return n; } @@ -3410,28 +3418,27 @@ CountBits(mask) * * GetColorTable -- * - * This procedure is called to allocate a table of colormap - * information for an instance of a photo image. Only one such - * table is allocated for all photo instances using the same - * display, colormap, palette and gamma values, so that the - * application need only request a set of colors from the X - * server once for all such photo widgets. This procedure - * maintains a hash table to find previously-allocated + * This function is called to allocate a table of colormap information + * for an instance of a photo image. Only one such table is allocated for + * all photo instances using the same display, colormap, palette and + * gamma values, so that the application need only request a set of + * colors from the X server once for all such photo widgets. This + * function maintains a hash table to find previously-allocated * ColorTables. * * Results: * None. * * Side effects: - * A new ColorTable may be allocated and placed in the hash - * table, and have colors allocated for it. + * A new ColorTable may be allocated and placed in the hash table, and + * have colors allocated for it. * *---------------------------------------------------------------------- */ static void GetColorTable(instancePtr) - PhotoInstance *instancePtr; /* Instance needing a color table. */ + PhotoInstance *instancePtr; /* Instance needing a color table. */ { ColorTable *colorPtr; Tcl_HashEntry *entry; @@ -3468,13 +3475,12 @@ GetColorTable(instancePtr) colorPtr = (ColorTable *) ckalloc(sizeof(ColorTable)); /* - * The following line of code should not normally be needed due - * to the assignment in the following line. However, it compensates - * for bugs in some compilers (HP, for example) where - * sizeof(ColorTable) is 24 but the assignment only copies 20 bytes, - * leaving 4 bytes uninitialized; these cause problems when using - * the id for lookups in imgPhotoColorHash, and can result in - * core dumps. + * The following line of code should not normally be needed due to the + * assignment in the following line. However, it compensates for bugs + * in some compilers (HP, for example) where sizeof(ColorTable) is 24 + * but the assignment only copies 20 bytes, leaving 4 bytes + * uninitialized; these cause problems when using the id for lookups + * in imgPhotoColorHash, and can result in core dumps. */ memset((VOID *) &colorPtr->id, 0, sizeof(ColorTableId)); @@ -3512,24 +3518,23 @@ GetColorTable(instancePtr) * * FreeColorTable -- * - * This procedure is called when an instance ceases using a - * color table. + * This function is called when an instance ceases using a color table. * * Results: * None. * * Side effects: - * If no other instances are using this color table, a when-idle - * handler is registered to free up the color table and the colors - * allocated for it. + * If no other instances are using this color table, a when-idle handler + * is registered to free up the color table and the colors allocated for + * it. * *---------------------------------------------------------------------- */ static void FreeColorTable(colorPtr, force) - ColorTable *colorPtr; /* Pointer to the color table which is - * no longer required by an instance. */ + ColorTable *colorPtr; /* Pointer to the color table which is no + * longer required by an instance. */ int force; /* Force free to happen immediately. */ { colorPtr->refCount--; @@ -3553,24 +3558,24 @@ FreeColorTable(colorPtr, force) * * AllocateColors -- * - * This procedure allocates the colors required by a color table, - * and sets up the fields in the color table data structure which - * are used in dithering. + * This function allocates the colors required by a color table, and sets + * up the fields in the color table data structure which are used in + * dithering. * * Results: * None. * * Side effects: - * Colors are allocated from the X server. Fields in the - * color table data structure are updated. + * Colors are allocated from the X server. Fields in the color table data + * structure are updated. * *---------------------------------------------------------------------- */ static void AllocateColors(colorPtr) - ColorTable *colorPtr; /* Pointer to the color table requiring - * colors to be allocated. */ + ColorTable *colorPtr; /* Pointer to the color table requiring colors + * to be allocated. */ { int i, r, g, b, rMult, mono; int numColors, nRed, nGreen, nBlue; @@ -3578,11 +3583,13 @@ AllocateColors(colorPtr) XColor *colors; unsigned long *pixels; - /* 16-bit intensity value for i/n of full intensity. */ -# define CFRAC(i, n) ((i) * 65535 / (n)) + /* + * 16-bit intensity value for i/n of full intensity. + */ +#define CFRAC(i, n) ((i) * 65535 / (n)) /* As for CFRAC, but apply exponent of g. */ -# define CGFRAC(i, n, g) ((int)(65535 * pow((double)(i) / (n), (g)))) +#define CGFRAC(i, n, g) ((int)(65535 * pow((double)(i) / (n), (g)))) /* * First parse the palette specification to get the required number of @@ -3594,16 +3601,14 @@ AllocateColors(colorPtr) igam = 1.0 / colorPtr->id.gamma; /* - * Each time around this loop, we reduce the number of colors we're - * trying to allocate until we succeed in allocating all of the colors - * we need. + * Each time around this loop, we reduce the number of colors we're trying + * to allocate until we succeed in allocating all of the colors we need. */ for (;;) { /* - * If we are using 1 bit/pixel, we don't need to allocate - * any colors (we just use the foreground and background - * colors in the GC). + * If we are using 1 bit/pixel, we don't need to allocate any colors + * (we just use the foreground and background colors in the GC). */ if (mono && (nRed <= 2)) { @@ -3612,12 +3617,12 @@ AllocateColors(colorPtr) } /* - * Calculate the RGB coordinates of the colors we want to - * allocate and store them in *colors. + * Calculate the RGB coordinates of the colors we want to allocate and + * store them in *colors. */ if ((colorPtr->visualInfo.class == DirectColor) - || (colorPtr->visualInfo.class == TrueColor)) { + || (colorPtr->visualInfo.class == TrueColor)) { /* * Direct/True Color: allocate shades of red, green, blue @@ -3644,8 +3649,8 @@ AllocateColors(colorPtr) } } else { /* - * PseudoColor, StaticColor, GrayScale or StaticGray visual: - * we have to allocate each color in the color cube separately. + * PseudoColor, StaticColor, GrayScale or StaticGray visual: we + * have to allocate each color in the color cube separately. */ numColors = (mono) ? nRed: (nRed * nGreen * nBlue); @@ -3697,7 +3702,6 @@ AllocateColors(colorPtr) for (i = 0; i < numColors; ++i) { if (!XAllocColor(colorPtr->id.display, colorPtr->id.colormap, &colors[i])) { - /* * Can't get all the colors we want in the default colormap; * first try freeing colors from other unused color tables. @@ -3716,9 +3720,8 @@ AllocateColors(colorPtr) } /* - * If we didn't get all of the colors, reduce the - * resolution of the color cube, free the ones we got, - * and try again. + * If we didn't get all of the colors, reduce the resolution of the + * color cube, free the ones we got, and try again. */ if (i >= numColors) { @@ -3737,10 +3740,10 @@ AllocateColors(colorPtr) mono = 1; } else { /* - * Reduce the number of shades of each primary to about - * 3/4 of the previous value. This should reduce the - * total number of colors required to about half the - * previous value for PseudoColor displays. + * Reduce the number of shades of each primary to about 3/4 of + * the previous value. This should reduce the total number of + * colors required to about half the previous value for + * PseudoColor displays. */ nRed = (nRed * 3 + 2) / 4; @@ -3755,23 +3758,22 @@ AllocateColors(colorPtr) nRed = nRed / 2; } } - + /* - * We have allocated all of the necessary colors: - * fill in various fields of the ColorTable record. + * We have allocated all of the necessary colors: fill in various fields + * of the ColorTable record. */ if (!mono) { colorPtr->flags |= COLOR_WINDOW; /* - * The following is a hairy hack. We only want to index into - * the pixelMap on colormap displays. However, if the display - * is on Windows, then we actually want to store the index not - * the value since we will be passing the color table into the - * TkPutImage call. + * The following is a hairy hack. We only want to index into the + * pixelMap on colormap displays. However, if the display is on + * Windows, then we actually want to store the index not the value + * since we will be passing the color table into the TkPutImage call. */ - + #ifndef __WIN32__ if ((colorPtr->visualInfo.class != DirectColor) && (colorPtr->visualInfo.class != TrueColor)) { @@ -3786,6 +3788,7 @@ AllocateColors(colorPtr) /* * Set up quantization tables for dithering. */ + rMult = nGreen * nBlue; for (i = 0; i < 256; ++i) { r = (i * (nRed - 1) + 127) / 255; @@ -3801,12 +3804,12 @@ AllocateColors(colorPtr) b = (i * (nBlue - 1) + 127) / 255; if ((colorPtr->visualInfo.class == DirectColor) || (colorPtr->visualInfo.class == TrueColor)) { - colorPtr->redValues[i] = colors[r].pixel - & colorPtr->visualInfo.red_mask; - colorPtr->greenValues[i] = colors[g].pixel - & colorPtr->visualInfo.green_mask; - colorPtr->blueValues[i] = colors[b].pixel - & colorPtr->visualInfo.blue_mask; + colorPtr->redValues[i] = + colors[r].pixel & colorPtr->visualInfo.red_mask; + colorPtr->greenValues[i] = + colors[g].pixel & colorPtr->visualInfo.green_mask; + colorPtr->blueValues[i] = + colors[b].pixel & colorPtr->visualInfo.blue_mask; } else { r *= rMult; g *= nBlue; @@ -3836,14 +3839,15 @@ AllocateColors(colorPtr) * * DisposeColorTable -- * + * Release a color table and its associated resources. * * Results: * None. * * Side effects: - * The colors in the argument color table are freed, as is the - * color table structure itself. The color table is removed - * from the hash table which is used to locate color tables. + * The colors in the argument color table are freed, as is the color + * table structure itself. The color table is removed from the hash table + * which is used to locate color tables. * *---------------------------------------------------------------------- */ @@ -3880,21 +3884,21 @@ DisposeColorTable(clientData) * * ReclaimColors -- * - * This procedure is called to try to free up colors in the - * colormap used by a color table. It looks for other color - * tables with the same colormap and with a zero live reference - * count, and frees their colors. It only does so if there is - * the possibility of freeing up at least `numColors' colors. + * This function is called to try to free up colors in the colormap used + * by a color table. It looks for other color tables with the same + * colormap and with a zero live reference count, and frees their colors. + * It only does so if there is the possibility of freeing up at least + * `numColors' colors. * * Results: - * The return value is TRUE if any colors were freed, FALSE - * otherwise. + * The return value is TRUE if any colors were freed, FALSE otherwise. * * Side effects: - * ColorTables which are not currently in use may lose their - * color allocations. + * ColorTables which are not currently in use may lose their color + * allocations. * - *---------------------------------------------------------------------- */ + *---------------------------------------------------------------------- + */ static int ReclaimColors(id, numColors) @@ -3908,8 +3912,8 @@ ReclaimColors(id, numColors) int nAvail; /* - * First scan through the color hash table to get an - * upper bound on how many colors we might be able to free. + * First scan through the color hash table to get an upper bound on how + * many colors we might be able to free. */ nAvail = 0; @@ -3917,11 +3921,10 @@ ReclaimColors(id, numColors) while (entry != NULL) { colorPtr = (ColorTable *) Tcl_GetHashValue(entry); if ((colorPtr->id.display == id->display) - && (colorPtr->id.colormap == id->colormap) - && (colorPtr->liveRefCount == 0 )&& (colorPtr->numColors != 0) - && ((colorPtr->id.palette != id->palette) - || (colorPtr->id.gamma != id->gamma))) { - + && (colorPtr->id.colormap == id->colormap) + && (colorPtr->liveRefCount == 0 )&& (colorPtr->numColors != 0) + && ((colorPtr->id.palette != id->palette) + || (colorPtr->id.gamma != id->gamma))) { /* * We could take this guy's colors off him. */ @@ -3950,8 +3953,7 @@ ReclaimColors(id, numColors) && (colorPtr->id.colormap == id->colormap) && (colorPtr->liveRefCount == 0) && (colorPtr->numColors != 0) && ((colorPtr->id.palette != id->palette) - || (colorPtr->id.gamma != id->gamma))) { - + || (colorPtr->id.gamma != id->gamma))) { /* * Free the colors that this ColorTable has. */ @@ -3974,23 +3976,22 @@ ReclaimColors(id, numColors) * * DisposeInstance -- * - * This procedure is called to finally free up an instance - * of a photo image which is no longer required. + * This function is called to finally free up an instance of a photo + * image which is no longer required. * * Results: * None. * * Side effects: - * The instance data structure and the resources it references - * are freed. + * The instance data structure and the resources it references are freed. * *---------------------------------------------------------------------- */ static void DisposeInstance(clientData) - ClientData clientData; /* Pointer to the instance whose resources - * are to be released. */ + ClientData clientData; /* Pointer to the instance whose resources are + * to be released. */ { PhotoInstance *instancePtr = (PhotoInstance *) clientData; PhotoInstance *prevPtr; @@ -4029,16 +4030,16 @@ DisposeInstance(clientData) * * MatchFileFormat -- * - * This procedure is called to find a photo image file format - * handler which can parse the image data in the given file. - * If a user-specified format string is provided, only handlers - * whose names match a prefix of the format string are tried. + * This function is called to find a photo image file format handler + * which can parse the image data in the given file. If a user-specified + * format string is provided, only handlers whose names match a prefix of + * the format string are tried. * * Results: - * A standard TCL return value. If the return value is TCL_OK, a - * pointer to the image format record is returned in - * *imageFormatPtr, and the width and height of the image are - * returned in *widthPtr and *heightPtr. + * A standard TCL return value. If the return value is TCL_OK, a pointer + * to the image format record is returned in *imageFormatPtr, and the + * width and height of the image are returned in *widthPtr and + * *heightPtr. * * Side effects: * None. @@ -4054,16 +4055,16 @@ MatchFileFormat(interp, chan, fileName, formatObj, imageFormatPtr, char *fileName; /* The name of the image file. */ Tcl_Obj *formatObj; /* User-specified format string, or NULL. */ Tk_PhotoImageFormat **imageFormatPtr; - /* A pointer to the photo image format - * record is returned here. */ - int *widthPtr, *heightPtr; /* The dimensions of the image are - * returned here. */ - int *oldformat; + /* A pointer to the photo image format record + * is returned here. */ + int *widthPtr, *heightPtr; /* The dimensions of the image are returned + * here. */ + int *oldformat; /* returns 1 if the old image API is used */ { int matched; int useoldformat = 0; Tk_PhotoImageFormat *formatPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); char *formatString = NULL; @@ -4072,8 +4073,8 @@ MatchFileFormat(interp, chan, fileName, formatObj, imageFormatPtr, } /* - * Scan through the table of file format handlers to find - * one which can handle the image. + * Scan through the table of file format handlers to find one which can + * handle the image. */ matched = 0; @@ -4093,7 +4094,7 @@ MatchFileFormat(interp, chan, fileName, formatObj, imageFormatPtr, } if (formatPtr->fileMatchProc != NULL) { (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET); - + if ((*formatPtr->fileMatchProc)(chan, fileName, formatObj, widthPtr, heightPtr, interp)) { if (*widthPtr < 1) { @@ -4140,13 +4141,12 @@ MatchFileFormat(interp, chan, fileName, formatObj, imageFormatPtr, if (formatPtr == NULL) { if ((formatObj != NULL) && !matched) { - Tcl_AppendResult(interp, "image file format \"", - formatString, + Tcl_AppendResult(interp, "image file format \"", formatString, "\" is not supported", (char *) NULL); } else { Tcl_AppendResult(interp, - "couldn't recognize data in image file \"", - fileName, "\"", (char *) NULL); + "couldn't recognize data in image file \"", fileName, "\"", + (char *) NULL); } return TCL_ERROR; } @@ -4162,16 +4162,16 @@ MatchFileFormat(interp, chan, fileName, formatObj, imageFormatPtr, * * MatchStringFormat -- * - * This procedure is called to find a photo image file format - * handler which can parse the image data in the given string. - * If a user-specified format string is provided, only handlers - * whose names match a prefix of the format string are tried. + * This function is called to find a photo image file format handler + * which can parse the image data in the given string. If a + * user-specified format string is provided, only handlers whose names + * match a prefix of the format string are tried. * * Results: - * A standard TCL return value. If the return value is TCL_OK, a - * pointer to the image format record is returned in - * *imageFormatPtr, and the width and height of the image are - * returned in *widthPtr and *heightPtr. + * A standard TCL return value. If the return value is TCL_OK, a pointer + * to the image format record is returned in *imageFormatPtr, and the + * width and height of the image are returned in *widthPtr and + * *heightPtr. * * Side effects: * None. @@ -4186,26 +4186,26 @@ MatchStringFormat(interp, data, formatObj, imageFormatPtr, Tcl_Obj *data; /* Object containing the image data. */ Tcl_Obj *formatObj; /* User-specified format string, or NULL. */ Tk_PhotoImageFormat **imageFormatPtr; - /* A pointer to the photo image format - * record is returned here. */ - int *widthPtr, *heightPtr; /* The dimensions of the image are - * returned here. */ + /* A pointer to the photo image format record + * is returned here. */ + int *widthPtr, *heightPtr; /* The dimensions of the image are returned + * here. */ int *oldformat; /* returns 1 if the old image API is used */ { int matched; int useoldformat = 0; Tk_PhotoImageFormat *formatPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); char *formatString = NULL; - + if (formatObj) { formatString = Tcl_GetString(formatObj); } /* - * Scan through the table of file format handlers to find - * one which can handle the image. + * Scan through the table of file format handlers to find one which can + * handle the image. */ matched = 0; @@ -4278,14 +4278,14 @@ MatchStringFormat(interp, data, formatObj, imageFormatPtr, * * Tk_FindPhoto -- * - * This procedure is called to get an opaque handle (actually a - * PhotoMaster *) for a given image, which can be used in - * subsequent calls to Tk_PhotoPutBlock, etc. The `name' - * parameter is the name of the image. + * This function is called to get an opaque handle (actually a + * PhotoMaster *) for a given image, which can be used in subsequent + * calls to Tk_PhotoPutBlock, etc. The `name' parameter is the name of + * the image. * * Results: - * The handle for the photo image, or NULL if there is no - * photo image with the name given. + * The handle for the photo image, or NULL if there is no photo image + * with the name given. * * Side effects: * None. @@ -4314,16 +4314,16 @@ Tk_FindPhoto(interp, imageName) * * Tk_PhotoPutBlock -- * - * This procedure is called to put image data into a photo image. + * This function is called to put image data into a photo image. * * Results: * A standard Tcl result code. * * Side effects: - * The image data is stored. The image may be expanded. - * The Tk image code is informed that the image has changed. - * If the result code is TCL_ERROR, an error message will be placed - * in the interpreter (if non-NULL). + * The image data is stored. The image may be expanded. The Tk image code + * is informed that the image has changed. If the result code is + * TCL_ERROR, an error message will be placed in the interpreter (if + * non-NULL). * *---------------------------------------------------------------------- */ @@ -4332,15 +4332,15 @@ int Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height, compRule) Tcl_Interp *interp; /* Interpreter for passing back error * messages, or NULL. */ - Tk_PhotoHandle handle; /* Opaque handle for the photo image - * to be updated. */ + Tk_PhotoHandle handle; /* Opaque handle for the photo image to be + * updated. */ register Tk_PhotoImageBlock *blockPtr; - /* Pointer to a structure describing the - * pixel data to be copied into the image. */ - int x, y; /* Coordinates of the top-left pixel to - * be updated in the image. */ - int width, height; /* Dimensions of the area of the image - * to be updated. */ + /* Pointer to a structure describing the pixel + * data to be copied into the image. */ + int x, y; /* Coordinates of the top-left pixel to be + * updated in the image. */ + int width, height; /* Dimensions of the area of the image to be + * updated. */ int compRule; /* Compositing rule to use when processing * transparent pixels. */ { @@ -4371,6 +4371,7 @@ Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height, compRule) yEnd = y + height; if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) { int sameSrc = (blockPtr->pixelPtr == masterPtr->pix32); + if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width), MAX(yEnd, masterPtr->height)) == TCL_ERROR) { if (interp != NULL) { @@ -4391,6 +4392,7 @@ Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height, compRule) /* * The dithering isn't correct past the start of this block. */ + masterPtr->ditherX = x; masterPtr->ditherY = y; } @@ -4413,18 +4415,19 @@ Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height, compRule) } /* - * Copy the data into our local 32-bit/pixel array. - * If we can do it with a single memcpy, we do. + * Copy the data into our local 32-bit/pixel array. If we can do it with a + * single memcpy, we do. */ destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4; pitch = masterPtr->width * 4; /* - * This test is probably too restrictive. We should also be able to - * do a memcpy if pixelSize == 3 and alphaOffset == 0. Maybe other cases - * too. + * Test to see if we can do the whole write in a single copy. This test is + * probably too restrictive. We should also be able to do a memcpy if + * pixelSize == 3 and alphaOffset == 0. Maybe other cases too. */ + if ((blockPtr->pixelSize == 4) && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3) && (width <= blockPtr->width) && (height <= blockPtr->height) @@ -4434,90 +4437,114 @@ Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height, compRule) memcpy((VOID *) destLinePtr, (VOID *) (blockPtr->pixelPtr + blockPtr->offset[0]), (size_t) (height * width * 4)); - } else { - int alpha; - for (hLeft = height; hLeft > 0;) { - srcLinePtr = blockPtr->pixelPtr + blockPtr->offset[0]; - hCopy = MIN(hLeft, blockPtr->height); - hLeft -= hCopy; - for (; hCopy > 0; --hCopy) { - if ((blockPtr->pixelSize == 4) && (greenOffset == 1) + + /* + * We know there's an alpha offset and we're setting the data, so skip + * directly to the point when we recompute the photo validity region. + */ + + goto recalculateValidRegion; + } + + /* + * Copy and merge pixels according to the compositing rule. + */ + + for (hLeft = height; hLeft > 0;) { + srcLinePtr = blockPtr->pixelPtr + blockPtr->offset[0]; + hCopy = MIN(hLeft, blockPtr->height); + hLeft -= hCopy; + for (; hCopy > 0; --hCopy) { + /* + * If the layout of the source line matches our memory layout and + * we're setting, we can just copy the bytes directly, which is + * much faster. + */ + + if ((blockPtr->pixelSize == 4) && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3) && (width <= blockPtr->width) && (compRule == TK_PHOTO_COMPOSITE_SET)) { - memcpy((VOID *) destLinePtr, (VOID *) srcLinePtr, - (size_t) (width * 4)); - } else { - destPtr = destLinePtr; - for (wLeft = width; wLeft > 0;) { - wCopy = MIN(wLeft, blockPtr->width); - wLeft -= wCopy; - srcPtr = srcLinePtr; - for (; wCopy > 0; --wCopy) { - alpha = srcPtr[alphaOffset]; - - /* - * In the easy case, we can just copy. - */ - if (!alphaOffset || (alpha == 255)) { - /* new solid part of the image */ - *destPtr++ = srcPtr[0]; - *destPtr++ = srcPtr[greenOffset]; - *destPtr++ = srcPtr[blueOffset]; - *destPtr++ = 255; - srcPtr += blockPtr->pixelSize; - continue; - } + memcpy((VOID *) destLinePtr, (VOID *) srcLinePtr, + (size_t) (width * 4)); + srcLinePtr += blockPtr->pitch; + destLinePtr += pitch; + continue; + } - /* - * Combine according to the compositing rule. - */ - switch (compRule) { - case TK_PHOTO_COMPOSITE_OVERLAY: - if (!destPtr[3]) { - /* - * The destination is entirely - * blank, so set it to the source, - * just as if we used the SET - * compositing rule. - */ - case TK_PHOTO_COMPOSITE_SET: - *destPtr++ = srcPtr[0]; - *destPtr++ = srcPtr[greenOffset]; - *destPtr++ = srcPtr[blueOffset]; - *destPtr++ = alpha; - break; - } + /* + * Have to copy the slow way. + */ - if (alpha) { - int Alpha = destPtr[3]; + destPtr = destLinePtr; + for (wLeft = width; wLeft > 0;) { + wCopy = MIN(wLeft, blockPtr->width); + wLeft -= wCopy; + srcPtr = srcLinePtr; + for (; wCopy>0 ; --wCopy, srcPtr+=blockPtr->pixelSize) { + int alpha = srcPtr[alphaOffset]; - /* - * This implements the Porter-Duff - * Source-Over compositing rule. - */ + /* + * In the easy case, we can just copy. + */ - destPtr[0] = PD_SRC_OVER(srcPtr[0],alpha,destPtr[0],Alpha); - destPtr[1] = PD_SRC_OVER(srcPtr[greenOffset],alpha,destPtr[1],Alpha); - destPtr[2] = PD_SRC_OVER(srcPtr[blueOffset],alpha,destPtr[2],Alpha); - destPtr[3] = PD_SRC_OVER_ALPHA(alpha,Alpha); - } - /* - * else should be empty space - */ - destPtr += 4; - break; - - default: - Tcl_Panic("unknown compositing rule: %d", compRule); - } - srcPtr += blockPtr->pixelSize; - } + if (!alphaOffset || (alpha == 255)) { + /* + * New solid part of the image. + */ + + *destPtr++ = srcPtr[0]; + *destPtr++ = srcPtr[greenOffset]; + *destPtr++ = srcPtr[blueOffset]; + *destPtr++ = 255; + continue; + } + + /* + * Combine according to the compositing rule. + */ + + if ((compRule == TK_PHOTO_COMPOSITE_SET) || !destPtr[3]) { + /* + * Either this is the SET rule (we overwrite whatever + * is there) or the destination is entirely blank. In + * both cases, we just set the destination to the + * source. + */ + + *destPtr++ = srcPtr[0]; + *destPtr++ = srcPtr[greenOffset]; + *destPtr++ = srcPtr[blueOffset]; + *destPtr++ = alpha; + continue; } + + if (alpha) { + int Alpha = destPtr[3]; + + /* + * This implements the Porter-Duff Source-Over + * compositing rule. + */ + + destPtr[0] = PD_SRC_OVER(srcPtr[0], alpha, destPtr[0], + Alpha); + destPtr[1] = PD_SRC_OVER(srcPtr[greenOffset], alpha, + destPtr[1], Alpha); + destPtr[2] = PD_SRC_OVER(srcPtr[blueOffset], alpha, + destPtr[2], Alpha); + destPtr[3] = PD_SRC_OVER_ALPHA(alpha, Alpha); + } + + /* + * else should be empty space + */ + + destPtr += 4; } - srcLinePtr += blockPtr->pitch; - destLinePtr += pitch; } + srcLinePtr += blockPtr->pitch; + destLinePtr += pitch; } } @@ -4526,33 +4553,35 @@ Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height, compRule) */ if (alphaOffset) { - /* - * This block is grossly inefficient. For each row in the image, it + * This block is grossly inefficient. For each row in the image, it * finds each continguous string of nontransparent pixels, then marks - * those areas as valid in the validRegion mask. This makes drawing + * those areas as valid in the validRegion mask. This makes drawing * very efficient, because of the way we use X: we just say, here's - * your mask, and here's your data. We need not worry about the - * current background color, etc. But this costs us a lot on the - * image setup. Still, image setup only happens once, whereas the - * drawing happens many times, so this might be the best way to go. + * your mask, and here's your data. We need not worry about the + * current background color, etc. But this costs us a lot on the image + * setup. Still, image setup only happens once, whereas the drawing + * happens many times, so this might be the best way to go. * * An alternative might be to not set up this mask, and instead, at * drawing time, for each transparent pixel, set its color to the - * color of the background behind that pixel. This is what I suspect - * most of programs do. However, they don't have to deal with the + * color of the background behind that pixel. This is what I suspect + * most of programs do. However, they don't have to deal with the * canvas, which could have many different background colors. * Determining the correct bg color for a given pixel might be * expensive. */ if (compRule != TK_PHOTO_COMPOSITE_OVERLAY) { + TkRegion workRgn; + /* - * Don't need this when using the OVERLAY compositing rule, - * which always strictly increases the valid region. + * Don't need this when using the OVERLAY compositing rule, which + * always strictly increases the valid region. */ - TkRegion workRgn = TkCreateRegion(); + recalculateValidRegion: + workRgn = TkCreateRegion(); rect.x = x; rect.y = y; rect.width = width; @@ -4564,9 +4593,8 @@ Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height, compRule) } /* - * Factorize out the main part of the building of the region - * data to allow for more efficient per-platform - * implementations. [Bug 919066] + * Factorize out the main part of the building of the region data to + * allow for more efficient per-platform implementations. [Bug 919066] */ TkpBuildRegionFromAlphaData(masterPtr->validRegion, (unsigned) x, @@ -4610,15 +4638,15 @@ Tk_PhotoPutBlock(interp, handle, blockPtr, x, y, width, height, compRule) * * Tk_PhotoPutZoomedBlock -- * - * This procedure is called to put image data into a photo image, - * with possible subsampling and/or zooming of the pixels. + * This function is called to put image data into a photo image, with + * possible subsampling and/or zooming of the pixels. * * Results: * None. * * Side effects: - * The image data is stored. The image may be expanded. - * The Tk image code is informed that the image has changed. + * The image data is stored. The image may be expanded. The Tk image code + * is informed that the image has changed. * *---------------------------------------------------------------------- */ @@ -4628,17 +4656,18 @@ Tk_PhotoPutZoomedBlock(interp, handle, blockPtr, x, y, width, height, zoomX, zoomY, subsampleX, subsampleY, compRule) Tcl_Interp *interp; /* Interpreter for passing back error * messages, or NULL. */ - Tk_PhotoHandle handle; /* Opaque handle for the photo image - * to be updated. */ + Tk_PhotoHandle handle; /* Opaque handle for the photo image to be + * updated. */ register Tk_PhotoImageBlock *blockPtr; - /* Pointer to a structure describing the - * pixel data to be copied into the image. */ - int x, y; /* Coordinates of the top-left pixel to - * be updated in the image. */ - int width, height; /* Dimensions of the area of the image - * to be updated. */ + /* Pointer to a structure describing the pixel + * data to be copied into the image. */ + int x, y; /* Coordinates of the top-left pixel to be + * updated in the image. */ + int width, height; /* Dimensions of the area of the image to be + * updated. */ int zoomX, zoomY; /* Zoom factors for the X and Y axes. */ - int subsampleX, subsampleY; /* Subsampling factors for the X and Y axes. */ + int subsampleX, subsampleY; /* Subsampling factors for the X and Y + * axes. */ int compRule; /* Compositing rule to use when processing * transparent pixels. */ { @@ -4771,10 +4800,12 @@ Tk_PhotoPutZoomedBlock(interp, handle, blockPtr, x, y, width, height, srcPtr = srcLinePtr; for (; wCopy > 0; wCopy -= zoomX) { for (xRepeat = MIN(wCopy, zoomX); xRepeat > 0; xRepeat--) { - int alpha = srcPtr[alphaOffset]; + int alpha = srcPtr[alphaOffset];/* source alpha */ + /* * Common case (solid pixels) first */ + if (!alphaOffset || (alpha == 255)) { *destPtr++ = srcPtr[0]; *destPtr++ = srcPtr[greenOffset]; @@ -4783,32 +4814,32 @@ Tk_PhotoPutZoomedBlock(interp, handle, blockPtr, x, y, width, height, continue; } - switch (compRule) { - case TK_PHOTO_COMPOSITE_OVERLAY: - if (!destPtr[3]) { - /* - * The destination is entirely blank, - * so set it to the source, just as if - * we used the SET compositing rule. - */ - case TK_PHOTO_COMPOSITE_SET: - *destPtr++ = srcPtr[0]; - *destPtr++ = srcPtr[greenOffset]; - *destPtr++ = srcPtr[blueOffset]; - *destPtr++ = alpha; - break; - } - if (alpha) { - int Alpha = destPtr[3]; - destPtr[0] = PD_SRC_OVER(srcPtr[0],alpha,destPtr[0],Alpha); - destPtr[1] = PD_SRC_OVER(srcPtr[greenOffset],alpha,destPtr[1],Alpha); - destPtr[2] = PD_SRC_OVER(srcPtr[blueOffset],alpha,destPtr[2],Alpha); - destPtr[3] = PD_SRC_OVER_ALPHA(alpha,Alpha); - } + if (compRule==TK_PHOTO_COMPOSITE_SET || !destPtr[3]) { + /* + * Either this is the SET rule (we overwrite + * whatever is there) or the destination is + * entirely blank. In both cases, we just set the + * destination to the source. + */ + + *destPtr++ = srcPtr[0]; + *destPtr++ = srcPtr[greenOffset]; + *destPtr++ = srcPtr[blueOffset]; + *destPtr++ = alpha; + } else if (alpha) { + int Alpha = destPtr[3]; /* destination alpha */ + + destPtr[0] = PD_SRC_OVER(srcPtr[0], alpha, + destPtr[0], Alpha); + destPtr[1] = PD_SRC_OVER(srcPtr[greenOffset],alpha, + destPtr[1], Alpha); + destPtr[2] = PD_SRC_OVER(srcPtr[blueOffset], alpha, + destPtr[2], Alpha); + destPtr[3] = PD_SRC_OVER_ALPHA(alpha, Alpha); + + destPtr += 4; + } else { destPtr += 4; - break; - default: - Tcl_Panic("unknown compositing rule: %d", compRule); } } srcPtr += blockXSkip; @@ -4835,6 +4866,7 @@ Tk_PhotoPutZoomedBlock(interp, handle, blockPtr, x, y, width, height, * Don't need this when using the OVERLAY compositing rule, which * always strictly increases the valid region. */ + TkRegion workRgn = TkCreateRegion(); rect.x = x; @@ -4847,34 +4879,9 @@ Tk_PhotoPutZoomedBlock(interp, handle, blockPtr, x, y, width, height, TkDestroyRegion(workRgn); } - destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4 + 3; - for (y1 = 0; y1 < height; y1++) { - x1 = 0; - destPtr = destLinePtr; - while (x1 < width) { - /* search for first non-transparent pixel */ - while ((x1 < width) && !*destPtr) { - x1++; - destPtr += 4; - } - end = x1; - /* search for first transparent pixel */ - while ((end < width) && *destPtr) { - end++; - destPtr += 4; - } - if (end > x1) { - rect.x = x + x1; - rect.y = y + y1; - rect.width = end - x1; - rect.height = 1; - TkUnionRectWithRegion(&rect, masterPtr->validRegion, - masterPtr->validRegion); - } - x1 = end; - } - destLinePtr += masterPtr->width * 4; - } + TkBuildRegionFromAlphaData(masterPtr->validRegion, x, y, width, height, + &masterPtr->pix32[(y * masterPtr->width + x) * 4 + 3], 4, + masterPtr->width * 4); } else { rect.x = x; rect.y = y; @@ -4896,7 +4903,7 @@ Tk_PhotoPutZoomedBlock(interp, handle, blockPtr, x, y, width, height, * Update each instance. */ - Tk_DitherPhoto((Tk_PhotoHandle)masterPtr, x, y, width, height); + Tk_DitherPhoto((Tk_PhotoHandle) masterPtr, x, y, width, height); /* * Tell the core image code that this image has changed. @@ -4912,26 +4919,26 @@ Tk_PhotoPutZoomedBlock(interp, handle, blockPtr, x, y, width, height, * * Tk_DitherPhoto -- * - * This procedure is called to update an area of each instance's - * pixmap by dithering the corresponding area of the image master. + * This function is called to update an area of each instance's pixmap by + * dithering the corresponding area of the image master. * * Results: * None. * * Side effects: - * The pixmap of each instance of this image gets updated. - * The fields in *masterPtr indicating which area of the image - * is correctly dithered get updated. + * The pixmap of each instance of this image gets updated. The fields in + * *masterPtr indicating which area of the image is correctly dithered + * get updated. * *---------------------------------------------------------------------- */ void Tk_DitherPhoto(photo, x, y, width, height) - Tk_PhotoHandle photo; /* Image master whose instances are - * to be updated. */ - int x, y; /* Coordinates of the top-left pixel - * in the area to be dithered. */ + Tk_PhotoHandle photo; /* Image master whose instances are to be + * updated. */ + int x, y; /* Coordinates of the top-left pixel in the + * area to be dithered. */ int width, height; /* Dimensions of the area to be dithered. */ { PhotoMaster *masterPtr = (PhotoMaster *) photo; @@ -4947,14 +4954,13 @@ Tk_DitherPhoto(photo, x, y, width, height) } /* - * Work out whether this block will be correctly dithered - * and whether it will extend the correctly dithered region. + * Work out whether this block will be correctly dithered and whether it + * will extend the correctly dithered region. */ if (((y < masterPtr->ditherY) || ((y == masterPtr->ditherY) && (x <= masterPtr->ditherX))) && ((y + height) > (masterPtr->ditherY))) { - /* * This block starts inside (or immediately after) the correctly * dithered region, so the first scan line at least will be right. @@ -4963,8 +4969,8 @@ Tk_DitherPhoto(photo, x, y, width, height) if ((x == 0) && (width == masterPtr->width)) { /* - * We are doing the full width, therefore the dithering - * will be correct to the end. + * We are doing the full width, therefore the dithering will be + * correct to the end. */ masterPtr->ditherX = 0; @@ -4972,8 +4978,8 @@ Tk_DitherPhoto(photo, x, y, width, height) } else { /* * We are doing partial scanlines, therefore the - * correctly-dithered region will be extended by - * at most one scan line. + * correctly-dithered region will be extended by at most one scan + * line. */ if (x <= masterPtr->ditherX) { @@ -4985,16 +4991,15 @@ Tk_DitherPhoto(photo, x, y, width, height) } } } - -} +} /* *---------------------------------------------------------------------- * * DitherInstance -- * - * This procedure is called to update an area of an instance's - * pixmap by dithering the corresponding area of the master. + * This function is called to update an area of an instance's pixmap by + * dithering the corresponding area of the master. * * Results: * None. @@ -5031,8 +5036,8 @@ DitherInstance(instancePtr, xStart, yStart, width, height) masterPtr = instancePtr->masterPtr; /* - * Turn dithering off in certain cases where it is not - * needed (TrueColor, DirectColor with many colors). + * Turn dithering off in certain cases where it is not needed (TrueColor, + * DirectColor with many colors). */ if ((colorPtr->visualInfo.class == DirectColor) @@ -5048,9 +5053,8 @@ DitherInstance(instancePtr, xStart, yStart, width, height) } /* - * First work out how many lines to do at a time, - * then how many bytes we'll need for pixel storage, - * and allocate it. + * First work out how many lines to do at a time, then how many bytes + * we'll need for pixel storage, and allocate it. */ nLines = (MAX_PIXELS + width - 1) / width; @@ -5070,7 +5074,8 @@ DitherInstance(instancePtr, xStart, yStart, width, height) imagePtr->width = width; imagePtr->height = nLines; imagePtr->bytes_per_line = bytesPerLine; - imagePtr->data = (char *) ckalloc((unsigned) (imagePtr->bytes_per_line * nLines)); + imagePtr->data = (char *) + ckalloc((unsigned) (imagePtr->bytes_per_line * nLines)); bigEndian = imagePtr->bitmap_bit_order == MSBFirst; firstBit = bigEndian? (1 << (imagePtr->bitmap_unit - 1)): 1; @@ -5080,8 +5085,8 @@ DitherInstance(instancePtr, xStart, yStart, width, height) xEnd = xStart + width; /* - * Loop over the image, doing at most nLines lines before - * updating the screen image. + * Loop over the image, doing at most nLines lines before updating the + * screen image. */ for (; height > 0; height -= nLines) { @@ -5097,10 +5102,10 @@ DitherInstance(instancePtr, xStart, yStart, width, height) destLongPtr = (pixel *) dstLinePtr; if (colorPtr->flags & COLOR_WINDOW) { /* - * Color window. We dither the three components - * independently, using Floyd-Steinberg dithering, - * which propagates errors from the quantization of - * pixels to the pixels below and to the right. + * Color window. We dither the three components independently, + * using Floyd-Steinberg dithering, which propagates errors + * from the quantization of pixels to the pixels below and to + * the right. */ for (x = xStart; x < xEnd; ++x) { @@ -5108,18 +5113,17 @@ DitherInstance(instancePtr, xStart, yStart, width, height) for (i = 0; i < 3; ++i) { /* * Compute the error propagated into this pixel - * for this component. - * If e[x,y] is the array of quantization error - * values, we compute + * for this component. If e[x,y] is the array of + * quantization error values, we compute * 7/16 * e[x-1,y] + 1/16 * e[x-1,y-1] * + 5/16 * e[x,y-1] + 3/16 * e[x+1,y-1] * and round it to an integer. * - * The expression ((c + 2056) >> 4) - 128 - * computes round(c / 16), and works correctly on - * machines without a sign-extending right shift. + * The expression ((c + 2056) >> 4) - 128 computes + * round(c / 16), and works correctly on machines + * without a sign-extending right shift. */ - + c = (x > 0) ? errPtr[-3] * 7: 0; if (y > 0) { if (x > 0) { @@ -5130,13 +5134,13 @@ DitherInstance(instancePtr, xStart, yStart, width, height) c += errPtr[-lineLength+3] * 3; } } - + /* * Add the propagated error to the value of this * component, quantize it, and store the * quantization error. */ - + c = ((c + 2056) >> 4) - 128 + *srcPtr++; if (c < 0) { c = 0; @@ -5147,9 +5151,9 @@ DitherInstance(instancePtr, xStart, yStart, width, height) *errPtr++ = c - col[i]; } } else { - /* - * Output is virtually continuous in this case, - * so don't bother dithering. + /* + * Output is virtually continuous in this case, so + * don't bother dithering. */ col[0] = *srcPtr++; @@ -5159,8 +5163,8 @@ DitherInstance(instancePtr, xStart, yStart, width, height) srcPtr++; /* - * Translate the quantized component values into - * an X pixel value, and store it in the image. + * Translate the quantized component values into an X + * pixel value, and store it in the image. */ i = colorPtr->redValues[col[0]] @@ -5170,32 +5174,34 @@ DitherInstance(instancePtr, xStart, yStart, width, height) i = colorPtr->pixelMap[i]; } switch (bitsPerPixel) { - case NBBY: - *destBytePtr++ = i; - break; + case NBBY: + *destBytePtr++ = i; + break; #ifndef __WIN32__ -/* - * This case is not valid for Windows because the image format is different - * from the pixel format in Win32. Eventually we need to fix the image - * code in Tk to use the Windows native image ordering. This would speed - * up the image code for all of the common sizes. - */ + /* + * This case is not valid for Windows because the + * image format is different from the pixel format in + * Win32. Eventually we need to fix the image code in + * Tk to use the Windows native image ordering. This + * would speed up the image code for all of the common + * sizes. + */ - case NBBY * sizeof(pixel): - *destLongPtr++ = i; - break; + case NBBY * sizeof(pixel): + *destLongPtr++ = i; + break; #endif - default: - XPutPixel(imagePtr, x - xStart, y - yStart, - (unsigned) i); + default: + XPutPixel(imagePtr, x - xStart, y - yStart, + (unsigned) i); } } } else if (bitsPerPixel > 1) { /* - * Multibit monochrome window. The operation here is similar + * Multibit monochrome window. The operation here is similar * to the color window case above, except that there is only - * one component. If the master image is in color, use the + * one component. If the master image is in color, use the * luminance computed as * 0.344 * red + 0.5 * green + 0.156 * blue. */ @@ -5217,7 +5223,7 @@ DitherInstance(instancePtr, xStart, yStart, width, height) c += srcPtr[0]; } else { c += (unsigned)(srcPtr[0] * 11 + srcPtr[1] * 16 - + srcPtr[2] * 5 + 16) >> 5; + + srcPtr[2] * 5 + 16) >> 5; } srcPtr += 4; @@ -5230,40 +5236,42 @@ DitherInstance(instancePtr, xStart, yStart, width, height) *errPtr++ = c - i; i = colorPtr->redValues[i]; switch (bitsPerPixel) { - case NBBY: - *destBytePtr++ = i; - break; + case NBBY: + *destBytePtr++ = i; + break; #ifndef __WIN32__ -/* - * This case is not valid for Windows because the image format is different - * from the pixel format in Win32. Eventually we need to fix the image - * code in Tk to use the Windows native image ordering. This would speed - * up the image code for all of the common sizes. - */ + /* + * This case is not valid for Windows because the + * image format is different from the pixel format in + * Win32. Eventually we need to fix the image code in + * Tk to use the Windows native image ordering. This + * would speed up the image code for all of the common + * sizes. + */ - case NBBY * sizeof(pixel): - *destLongPtr++ = i; - break; + case NBBY * sizeof(pixel): + *destLongPtr++ = i; + break; #endif - default: - XPutPixel(imagePtr, x - xStart, y - yStart, - (unsigned) i); + default: + XPutPixel(imagePtr, x - xStart, y - yStart, + (unsigned) i); } } } else { /* - * 1-bit monochrome window. This is similar to the - * multibit monochrome case above, except that the - * quantization is simpler (we only have black = 0 - * and white = 255), and we produce an XY-Bitmap. + * 1-bit monochrome window. This is similar to the multibit + * monochrome case above, except that the quantization is + * simpler (we only have black = 0 and white = 255), and we + * produce an XY-Bitmap. */ word = 0; mask = firstBit; for (x = xStart; x < xEnd; ++x) { /* - * If we have accumulated a whole word, store it - * in the image and start a new word. + * If we have accumulated a whole word, store it in the + * image and start a new word. */ if (mask == 0) { @@ -5288,7 +5296,7 @@ DitherInstance(instancePtr, xStart, yStart, width, height) c += srcPtr[0]; } else { c += (unsigned)(srcPtr[0] * 11 + srcPtr[1] * 16 - + srcPtr[2] * 5 + 16) >> 5; + + srcPtr[2] * 5 + 16) >> 5; } srcPtr += 4; @@ -5313,8 +5321,8 @@ DitherInstance(instancePtr, xStart, yStart, width, height) } /* - * Update the pixmap for this instance with the block of - * pixels that we have just computed. + * Update the pixmap for this instance with the block of pixels that + * we have just computed. */ TkPutImage(colorPtr->pixelMap, colorPtr->numColors, @@ -5322,7 +5330,6 @@ DitherInstance(instancePtr, xStart, yStart, width, height) instancePtr->gc, imagePtr, 0, 0, xStart, yStart, (unsigned) width, (unsigned) nLines); yStart = yEnd; - } ckfree(imagePtr->data); @@ -5334,14 +5341,14 @@ DitherInstance(instancePtr, xStart, yStart, width, height) * * Tk_PhotoBlank -- * - * This procedure is called to clear an entire photo image. + * This function is called to clear an entire photo image. * * Results: * None. * * Side effects: - * The valid region for the image is set to the null region. - * The generic image code is notified that the image has changed. + * The valid region for the image is set to the null region. The generic + * image code is notified that the image has changed. * *---------------------------------------------------------------------- */ @@ -5367,8 +5374,8 @@ Tk_PhotoBlank(handle) masterPtr->validRegion = TkCreateRegion(); /* - * Clear out the 32-bit pixel storage array. - * Clear out the dithering error arrays for each instance. + * Clear out the 32-bit pixel storage array. Clear out the dithering error + * arrays for each instance. */ memset((VOID *) masterPtr->pix32, 0, @@ -5395,18 +5402,17 @@ Tk_PhotoBlank(handle) * * Tk_PhotoExpand -- * - * This procedure is called to request that a photo image be - * expanded if necessary to be at least `width' pixels wide and - * `height' pixels high. If the user has declared a definite - * image size (using the -width and -height configuration - * options) then this call has no effect. + * This function is called to request that a photo image be expanded if + * necessary to be at least `width' pixels wide and `height' pixels high. + * If the user has declared a definite image size (using the -width and + * -height configuration options) then this call has no effect. * * Results: * None. * * Side effects: - * The size of the photo image may change; if so the generic - * image code is informed. + * The size of the photo image may change; if so the generic image code + * is informed. * *---------------------------------------------------------------------- */ @@ -5449,12 +5455,10 @@ Tk_PhotoExpand(interp, handle, width, height) * * Tk_PhotoGetSize -- * - * This procedure is called to obtain the current size of a photo - * image. + * This function is called to obtain the current size of a photo image. * * Results: - * The image's width and height are returned in *widthp - * and *heightp. + * The image's width and height are returned in *widthp and *heightp. * * Side effects: * None. @@ -5464,8 +5468,8 @@ Tk_PhotoExpand(interp, handle, width, height) void Tk_PhotoGetSize(handle, widthPtr, heightPtr) - Tk_PhotoHandle handle; /* Handle for the image whose dimensions - * are requested. */ + Tk_PhotoHandle handle; /* Handle for the image whose dimensions are + * requested. */ int *widthPtr, *heightPtr; /* The dimensions of the image are returned * here. */ { @@ -5481,16 +5485,15 @@ Tk_PhotoGetSize(handle, widthPtr, heightPtr) * * Tk_PhotoSetSize -- * - * This procedure is called to set size of a photo image. - * This call is equivalent to using the -width and -height - * configuration options. + * This function is called to set size of a photo image. This call is + * equivalent to using the -width and -height configuration options. * * Results: * None. * * Side effects: - * The size of the image may change; if so the generic - * image code is informed. + * The size of the image may change; if so the generic image code is + * informed. * *---------------------------------------------------------------------- */ @@ -5499,8 +5502,8 @@ int Tk_PhotoSetSize(interp, handle, width, height) Tcl_Interp *interp; /* Interpreter for passing back error * messages, or NULL. */ - Tk_PhotoHandle handle; /* Handle for the image whose size is to - * be set. */ + Tk_PhotoHandle handle; /* Handle for the image whose size is to be + * set. */ int width, height; /* New dimensions for the image. */ { PhotoMaster *masterPtr; @@ -5528,14 +5531,14 @@ Tk_PhotoSetSize(interp, handle, width, height) * * TkGetPhotoValidRegion -- * - * This procedure is called to get the part of the photo where - * there is valid data. Or, conversely, the part of the photo - * which is transparent. + * This function is called to get the part of the photo where there is + * valid data. Or, conversely, the part of the photo which is + * transparent. * * Results: - * A TkRegion value that indicates the current area of the photo - * that is valid. This value should not be used after any - * modification to the photo image. + * A TkRegion value that indicates the current area of the photo that is + * valid. This value should not be used after any modification to the + * photo image. * * Side Effects: * None. @@ -5545,8 +5548,8 @@ Tk_PhotoSetSize(interp, handle, width, height) TkRegion TkPhotoGetValidRegion(handle) - Tk_PhotoHandle handle; /* Handle for the image whose valid region - * is to obtained. */ + Tk_PhotoHandle handle; /* Handle for the image whose valid region is + * to obtained. */ { PhotoMaster *masterPtr; @@ -5559,15 +5562,15 @@ TkPhotoGetValidRegion(handle) * * ImgGetPhoto -- * - * This procedure is called to obtain image data from a photo - * image. This procedure fills in the Tk_PhotoImageBlock structure - * pointed to by `blockPtr' with details of the address and - * layout of the image data in memory. + * This function is called to obtain image data from a photo image. This + * function fills in the Tk_PhotoImageBlock structure pointed to by + * `blockPtr' with details of the address and layout of the image data in + * memory. * * Results: - * A pointer to the allocated data which should be freed later. - * NULL if there is no need to free data because - * blockPtr->pixelPtr points directly to the image data. + * A pointer to the allocated data which should be freed later. NULL if + * there is no need to free data because blockPtr->pixelPtr points + * directly to the image data. * * Side effects: * None. @@ -5577,11 +5580,11 @@ TkPhotoGetValidRegion(handle) static char * ImgGetPhoto(masterPtr, blockPtr, optPtr) - PhotoMaster *masterPtr; /* Handle for the photo image from which - * image data is desired. */ + PhotoMaster *masterPtr; /* Handle for the photo image from which image + * data is desired. */ Tk_PhotoImageBlock *blockPtr; - /* Information about the address and layout - * of the image data is returned here. */ + /* Information about the address and layout of + * the image data is returned here. */ struct SubcommandOptions *optPtr; { unsigned char *pixelPtr; @@ -5597,8 +5600,7 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr) (!(optPtr->options & OPT_BACKGROUND) || ((optPtr->background->red == optPtr->background->green) && (optPtr->background->red == optPtr->background->blue)))) { - blockPtr->offset[0] = blockPtr->offset[1] = - blockPtr->offset[2]; + blockPtr->offset[0] = blockPtr->offset[1] = blockPtr->offset[2]; } alphaOffset = 0; for (y = 0; y < blockPtr->height; y++) { @@ -5624,13 +5626,14 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr) greenOffset = blockPtr->offset[1] - blockPtr->offset[0]; blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; if (((optPtr->options & OPT_BACKGROUND) && alphaOffset) || - ((optPtr->options & OPT_GRAYSCALE) && (greenOffset || blueOffset))) { + ((optPtr->options & OPT_GRAYSCALE) && (greenOffset||blueOffset))) { int newPixelSize,x,y; unsigned char *srcPtr, *destPtr; char *data; - newPixelSize = (!(optPtr->options & OPT_BACKGROUND) && alphaOffset) ? 2 : 1; - if ((greenOffset || blueOffset) && !(optPtr->options & OPT_GRAYSCALE)) { + newPixelSize = (!(optPtr->options & OPT_BACKGROUND) && alphaOffset) + ? 2 : 1; + if ((greenOffset||blueOffset) && !(optPtr->options & OPT_GRAYSCALE)) { newPixelSize += 2; } data = ckalloc((unsigned int) (newPixelSize * @@ -5644,17 +5647,19 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr) srcPtr += blockPtr->pixelSize; destPtr += newPixelSize; } - srcPtr += blockPtr->pitch - (blockPtr->width * blockPtr->pixelSize); + srcPtr += blockPtr->pitch - + blockPtr->width * blockPtr->pixelSize; } } else if (optPtr->options & OPT_GRAYSCALE) { for (y = blockPtr->height; y > 0; y--) { for (x = blockPtr->width; x > 0; x--) { - *destPtr = (unsigned char) ((srcPtr[0] * 11 + srcPtr[1] * 16 - + srcPtr[2] * 5 + 16) >> 5); + *destPtr = (unsigned char) + (srcPtr[0]*11+srcPtr[1]*16+srcPtr[2]*5 + 16) >> 5; srcPtr += blockPtr->pixelSize; destPtr += newPixelSize; } - srcPtr += blockPtr->pitch - (blockPtr->width * blockPtr->pixelSize); + srcPtr += blockPtr->pitch - + blockPtr->width * blockPtr->pixelSize; } } else { for (y = blockPtr->height; y > 0; y--) { @@ -5665,13 +5670,16 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr) srcPtr += blockPtr->pixelSize; destPtr += newPixelSize; } - srcPtr += blockPtr->pitch - (blockPtr->width * blockPtr->pixelSize); + srcPtr += blockPtr->pitch - + blockPtr->width * blockPtr->pixelSize; } } srcPtr = blockPtr->pixelPtr + alphaOffset; destPtr = (unsigned char *) data; if (!alphaOffset) { - /* nothing to be done */ + /* + * Nothing to be done. + */ } else if (optPtr->options & OPT_BACKGROUND) { if (newPixelSize > 2) { int red = optPtr->background->red>>8; @@ -5688,12 +5696,14 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr) srcPtr += blockPtr->pixelSize; destPtr += newPixelSize; } - srcPtr += blockPtr->pitch - (blockPtr->width * blockPtr->pixelSize); + srcPtr += blockPtr->pitch - + blockPtr->width * blockPtr->pixelSize; } } else { int gray = (unsigned char) (((optPtr->background->red>>8) * 11 - + (optPtr->background->green>>8) * 16 - + (optPtr->background->blue>>8) * 5 + 16) >> 5); + + (optPtr->background->green>>8) * 16 + + (optPtr->background->blue>>8) * 5 + 16) >> 5); + for (y = blockPtr->height; y > 0; y--) { for (x = blockPtr->width; x > 0; x--) { destPtr[0] += ((255 - *srcPtr) * @@ -5701,7 +5711,8 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr) srcPtr += blockPtr->pixelSize; destPtr += newPixelSize; } - srcPtr += blockPtr->pitch - (blockPtr->width * blockPtr->pixelSize); + srcPtr += blockPtr->pitch - + blockPtr->width * blockPtr->pixelSize; } } } else { @@ -5712,7 +5723,8 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr) srcPtr += blockPtr->pixelSize; destPtr += newPixelSize; } - srcPtr += blockPtr->pitch - (blockPtr->width * blockPtr->pixelSize); + srcPtr += blockPtr->pitch - + blockPtr->width * blockPtr->pixelSize; } } blockPtr->pixelPtr = (unsigned char *) data; @@ -5736,8 +5748,8 @@ ImgGetPhoto(masterPtr, blockPtr, optPtr) * * ImgStringWrite -- * - * Default string write function. The data is formatted in - * the default format as accepted by the "<img> put" command. + * Default string write function. The data is formatted in the default + * format as accepted by the "<img> put" command. * * Results: * A standard Tcl result. @@ -5789,14 +5801,14 @@ ImgStringWrite(interp, formatString, blockPtr) * * Tk_PhotoGetImage -- * - * This procedure is called to obtain image data from a photo - * image. This procedure fills in the Tk_PhotoImageBlock structure - * pointed to by `blockPtr' with details of the address and - * layout of the image data in memory. + * This function is called to obtain image data from a photo image. This + * function fills in the Tk_PhotoImageBlock structure pointed to by + * `blockPtr' with details of the address and layout of the image data in + * memory. * * Results: - * TRUE (1) indicating that image data is available, - * for backwards compatibility with the old photo widget. + * TRUE (1) indicating that image data is available, for backwards + * compatibility with the old photo widget. * * Side effects: * None. @@ -5806,11 +5818,11 @@ ImgStringWrite(interp, formatString, blockPtr) int Tk_PhotoGetImage(handle, blockPtr) - Tk_PhotoHandle handle; /* Handle for the photo image from which - * image data is desired. */ + Tk_PhotoHandle handle; /* Handle for the photo image from which image + * data is desired. */ Tk_PhotoImageBlock *blockPtr; - /* Information about the address and layout - * of the image data is returned here. */ + /* Information about the address and layout of + * the image data is returned here. */ { PhotoMaster *masterPtr; @@ -5844,26 +5856,26 @@ Tk_PhotoGetImage(handle, blockPtr) */ typedef struct OptionAssocData { - struct OptionAssocData *nextPtr; /* pointer to next OptionAssocData */ - Tcl_ObjCmdProc *command; /* command associated with this - * option */ - char name[1]; /* name of option (remaining chars) */ + struct OptionAssocData *nextPtr; + /* Pointer to next OptionAssocData. */ + Tcl_ObjCmdProc *command; /* Command associated with this option. */ + char name[1]; /* Name of option (remaining chars) */ } OptionAssocData; static Tcl_ObjCmdProc * PhotoOptionFind(interp, obj) Tcl_Interp *interp; /* Interpreter that is being deleted. */ - Tcl_Obj *obj; /* Name of option to be found. */ + Tcl_Obj *obj; /* Name of option to be found. */ { - size_t length; - char *name = Tcl_GetStringFromObj(obj, (int *) &length); + int length; + char *name = Tcl_GetStringFromObj(obj, &length); char *prevname = NULL; Tcl_ObjCmdProc *proc = (Tcl_ObjCmdProc *) NULL; OptionAssocData *list = (OptionAssocData *) Tcl_GetAssocData(interp, "photoOption", (Tcl_InterpDeleteProc **) NULL); while (list != (OptionAssocData *) NULL) { - if (strncmp(name, list->name, length) == 0) { + if (strncmp(name, list->name, (unsigned) length) == 0) { if (proc != (Tcl_ObjCmdProc *) NULL) { Tcl_ResetResult(interp); Tcl_AppendResult(interp, "ambiguous option \"", name, @@ -5892,8 +5904,8 @@ PhotoOptionFind(interp, obj) * * PhotoOptionCleanupProc -- * - * This procedure is invoked whenever an interpreter is deleted - * to cleanup the AssocData for "photoVisitor". + * This function is invoked whenever an interpreter is deleted to cleanup + * the AssocData for "photoVisitor". * * Results: * None. @@ -5906,8 +5918,8 @@ PhotoOptionFind(interp, obj) static void PhotoOptionCleanupProc(clientData, interp) - ClientData clientData; /* Points to "photoVisitor" AssocData - * for the interpreter. */ + ClientData clientData; /* Points to "photoVisitor" AssocData for the + * interpreter. */ Tcl_Interp *interp; /* Interpreter that is being deleted. */ { OptionAssocData *list = (OptionAssocData *) clientData; @@ -5924,24 +5936,23 @@ PhotoOptionCleanupProc(clientData, interp) * * Tk_CreatePhotoOption -- * - * This procedure may be invoked to add a new kind of photo - * option to the core photo command supported by Tk. + * This function may be invoked to add a new kind of photo option to the + * core photo command supported by Tk. * * Results: * None. * * Side effects: - * From now on, the new option will be useable by the - * photo command. + * From now on, the new option will be useable by the photo command. * *-------------------------------------------------------------- */ void Tk_CreatePhotoOption(interp, name, proc) - Tcl_Interp *interp; /* interpreter */ - CONST char *name; /* option name */ - Tcl_ObjCmdProc *proc; /* proc to execute command */ + Tcl_Interp *interp; /* Interpreter */ + CONST char *name; /* Option name */ + Tcl_ObjCmdProc *proc; /* Function to execute command */ { OptionAssocData *typePtr2, *prevPtr, *ptr; OptionAssocData *list; @@ -5978,9 +5989,8 @@ Tk_CreatePhotoOption(interp, name, proc) * * TkPostscriptPhoto -- * - * This procedure is called to output the contents of a - * photo image in Postscript by calling the Tk_PostscriptPhoto - * function. + * This function is called to output the contents of a photo image in + * Postscript by calling the Tk_PostscriptPhoto function. * * Results: * Returns a standard Tcl return value. @@ -5993,7 +6003,7 @@ Tk_CreatePhotoOption(interp, name, proc) static int ImgPhotoPostscript(clientData, interp, tkwin, psInfo, x, y, width, height, prepass) - ClientData clientData; /* Handle for the photo image */ + ClientData clientData; /* Handle for the photo image */ Tcl_Interp *interp; /* Interpreter */ Tk_Window tkwin; /* (unused) */ Tk_PostscriptInfo psInfo; /* postscript info */ @@ -6014,19 +6024,19 @@ ImgPhotoPostscript(clientData, interp, tkwin, psInfo, * * Tk_PhotoPutBlock_NoComposite, Tk_PhotoPutZoomedBlock_NoComposite -- * - * These backward-compatability functions just exist to fill slots in - * stubs table. For the behaviour of *_NoComposite, refer to the - * corresponding function without the extra suffix, except that the - * compositing rule is always "overlay" and the function always panics - * on memory-allocation failure. + * These backward-compatability functions just exist to fill slots in stubs + * table. For the behaviour of *_NoComposite, refer to the corresponding + * function without the extra suffix, except that the compositing rule is + * always "overlay" and the function always panics on memory-allocation + * failure. * *---------------------------------------------------------------------- */ void Tk_PhotoPutBlock_NoComposite(handle, blockPtr, x, y, width, height) - Tk_PhotoHandle handle; - Tk_PhotoImageBlock *blockPtr; - int x, y, width, height; + Tk_PhotoHandle handle; + Tk_PhotoImageBlock *blockPtr; + int x, y, width, height; { if (Tk_PhotoPutBlock(NULL, handle, blockPtr, x, y, width, height, TK_PHOTO_COMPOSITE_OVERLAY) != TCL_OK) { @@ -6036,10 +6046,10 @@ Tk_PhotoPutBlock_NoComposite(handle, blockPtr, x, y, width, height) void Tk_PhotoPutZoomedBlock_NoComposite(handle, blockPtr, x, y, width, height, - zoomX, zoomY, subsampleX, subsampleY) - Tk_PhotoHandle handle; - Tk_PhotoImageBlock *blockPtr; - int x, y, width, height, zoomX, zoomY, subsampleX, subsampleY; + zoomX, zoomY, subsampleX, subsampleY) + Tk_PhotoHandle handle; + Tk_PhotoImageBlock *blockPtr; + int x, y, width, height, zoomX, zoomY, subsampleX, subsampleY; { if (Tk_PhotoPutZoomedBlock(NULL, handle, blockPtr, x, y, width, height, zoomX, zoomY, subsampleX, subsampleY, @@ -6054,11 +6064,11 @@ Tk_PhotoPutZoomedBlock_NoComposite(handle, blockPtr, x, y, width, height, * Tk_PhotoExpand_Panic, Tk_PhotoPutBlock_Panic, * Tk_PhotoPutZoomedBlock_Panic, Tk_PhotoSetSize_Panic * - * Backward compatability functions for preserving the old behaviour - * (i.e. panic on memory allocation failure) so that extensions do not - * need to be significantly updated to take account of TIP #116. These - * call the new interface (i.e. the interface without the extra suffix), - * but panic if an error condition is returned. + * Backward compatability functions for preserving the old behaviour (i.e. + * panic on memory allocation failure) so that extensions do not need to be + * significantly updated to take account of TIP #116. These call the new + * interface (i.e. the interface without the extra suffix), but panic if an + * error condition is returned. * *---------------------------------------------------------------------- */ @@ -6107,3 +6117,11 @@ Tk_PhotoSetSize_Panic(handle, width, height) Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE); } } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkObj.c b/generic/tkObj.c index fc5def6..3b34eed 100644 --- a/generic/tkObj.c +++ b/generic/tkObj.c @@ -1,15 +1,14 @@ -/* +/* * tkObj.c -- * - * This file contains procedures that implement the common Tk object - * types + * This file contains functions that implement the common Tk object types * * Copyright (c) 1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkObj.c,v 1.12 2005/01/11 16:04:41 dkf Exp $ + * RCS: @(#) $Id: tkObj.c,v 1.13 2005/08/10 22:02:22 dkf Exp $ */ #include "tkInt.h" @@ -17,7 +16,7 @@ /* * The following structure is the internal representation for pixel objects. */ - + typedef struct PixelRep { double value; int units; @@ -46,7 +45,7 @@ typedef struct PixelRep { /* * The following structure is the internal representation for mm objects. */ - + typedef struct MMRep { double value; int units; @@ -56,41 +55,35 @@ typedef struct MMRep { /* * The following structure is the internal representation for window objects. - * A WindowRep caches name-to-window lookups. The cache is invalid - * if tkwin is NULL or if mainPtr->deletionEpoch does not match epoch. + * A WindowRep caches name-to-window lookups. The cache is invalid if tkwin is + * NULL or if mainPtr->deletionEpoch does not match epoch. */ typedef struct WindowRep { - Tk_Window tkwin; /* Cached window; NULL if not found */ - TkMainInfo *mainPtr; /* MainWindow associated with tkwin */ + Tk_Window tkwin; /* Cached window; NULL if not found. */ + TkMainInfo *mainPtr; /* MainWindow associated with tkwin. */ long epoch; /* Value of mainPtr->deletionEpoch at last - * successful lookup. */ + * successful lookup. */ } WindowRep; /* - * Prototypes for procedures defined later in this file: + * Prototypes for functions defined later in this file: */ -static void DupMMInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr, - Tcl_Obj *copyPtr)); -static void DupPixelInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr, - Tcl_Obj *copyPtr)); -static void DupWindowInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr, - Tcl_Obj *copyPtr)); -static void FreeMMInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr)); -static void FreePixelInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr)); -static void FreeWindowInternalRep _ANSI_ARGS_((Tcl_Obj *objPtr)); -static void UpdateStringOfMM _ANSI_ARGS_((Tcl_Obj *objPtr)); -static int SetMMFromAny _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *objPtr)); -static int SetPixelFromAny _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *objPtr)); -static int SetWindowFromAny _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *objPtr)); +static void DupMMInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); +static void DupPixelInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr); +static void DupWindowInternalRep(Tcl_Obj *srcPtr,Tcl_Obj *copyPtr); +static void FreeMMInternalRep(Tcl_Obj *objPtr); +static void FreePixelInternalRep(Tcl_Obj *objPtr); +static void FreeWindowInternalRep(Tcl_Obj *objPtr); +static void UpdateStringOfMM(Tcl_Obj *objPtr); +static int SetMMFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); +static int SetPixelFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); +static int SetWindowFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr); /* - * The following structure defines the implementation of the "pixel" - * Tcl object, used for measuring distances. The pixel object remembers - * its initial display-independant settings. + * The following structure defines the implementation of the "pixel" Tcl + * object, used for measuring distances. The pixel object remembers its + * initial display-independant settings. */ static Tcl_ObjType pixelObjType = { @@ -102,9 +95,9 @@ static Tcl_ObjType pixelObjType = { }; /* - * The following structure defines the implementation of the "pixel" - * Tcl object, used for measuring distances. The pixel object remembers - * its initial display-independant settings. + * The following structure defines the implementation of the "pixel" Tcl + * object, used for measuring distances. The pixel object remembers its + * initial display-independant settings. */ static Tcl_ObjType mmObjType = { @@ -121,14 +114,12 @@ static Tcl_ObjType mmObjType = { */ static Tcl_ObjType windowObjType = { - "window", /* name */ - FreeWindowInternalRep, /* freeIntRepProc */ - DupWindowInternalRep, /* dupIntRepProc */ - NULL, /* updateStringProc */ - SetWindowFromAny /* setFromAnyProc */ + "window", /* name */ + FreeWindowInternalRep, /* freeIntRepProc */ + DupWindowInternalRep, /* dupIntRepProc */ + NULL, /* updateStringProc */ + SetWindowFromAny /* setFromAnyProc */ }; - - /* *---------------------------------------------------------------------- @@ -136,8 +127,8 @@ static Tcl_ObjType windowObjType = { * Tk_GetPixelsFromObj -- * * Attempt to return a pixel value from the Tcl object "objPtr". If the - * object is not already a pixel value, an attempt will be made to convert - * it to one. + * object is not already a pixel value, an attempt will be made to + * convert it to one. * * Results: * The return value is a standard Tcl object result. If an error occurs @@ -145,8 +136,8 @@ static Tcl_ObjType windowObjType = { * result unless "interp" is NULL. * * Side effects: - * If the object is not already a pixel, the conversion will free - * any old internal representation. + * If the object is not already a pixel, the conversion will free any old + * internal representation. * *---------------------------------------------------------------------- */ @@ -189,7 +180,7 @@ Tk_GetPixelsFromObj(interp, tkwin, objPtr, intPtr) } pixelPtr->tkwin = tkwin; } - *intPtr = pixelPtr->returnValue; + *intPtr = pixelPtr->returnValue; } return TCL_OK; } @@ -206,8 +197,8 @@ Tk_GetPixelsFromObj(interp, tkwin, objPtr, intPtr) * None. * * Side effects: - * Frees objPtr's internal representation and sets objPtr's - * internalRep to NULL. + * Frees objPtr's internal representation and sets objPtr's internalRep + * to NULL. * *---------------------------------------------------------------------- */ @@ -217,7 +208,7 @@ FreePixelInternalRep(objPtr) Tcl_Obj *objPtr; /* Pixel object with internal rep to free. */ { PixelRep *pixelPtr; - + if (!SIMPLE_PIXELREP(objPtr)) { pixelPtr = GET_COMPLEXPIXEL(objPtr); ckfree((char *) pixelPtr); @@ -231,15 +222,15 @@ FreePixelInternalRep(objPtr) * * DupPixelInternalRep -- * - * Initialize the internal representation of a pixel Tcl_Obj to a - * copy of the internal representation of an existing pixel object. + * Initialize the internal representation of a pixel Tcl_Obj to a copy of + * the internal representation of an existing pixel object. * * Results: * None. * * Side effects: - * copyPtr's internal rep is set to the pixel corresponding to - * srcPtr's internal rep. + * copyPtr's internal rep is set to the pixel corresponding to srcPtr's + * internal rep. * *---------------------------------------------------------------------- */ @@ -250,7 +241,7 @@ DupPixelInternalRep(srcPtr, copyPtr) register Tcl_Obj *copyPtr; /* Object with internal rep to set. */ { PixelRep *oldPtr, *newPtr; - + copyPtr->typePtr = srcPtr->typePtr; if (SIMPLE_PIXELREP(srcPtr)) { @@ -271,8 +262,7 @@ DupPixelInternalRep(srcPtr, copyPtr) * * SetPixelFromAny -- * - * Attempt to generate a pixel internal form for the Tcl object - * "objPtr". + * Attempt to generate a pixel internal form for the Tcl object "objPtr". * * Results: * The return value is a standard Tcl result. If an error occurs during @@ -280,8 +270,8 @@ DupPixelInternalRep(srcPtr, copyPtr) * unless "interp" is NULL. * * Side effects: - * If no error occurs, a pixel representation of the object is - * stored internally and the type of "objPtr" is set to pixel. + * If no error occurs, a pixel representation of the object is stored + * internally and the type of "objPtr" is set to pixel. * *---------------------------------------------------------------------- */ @@ -295,55 +285,39 @@ SetPixelFromAny(interp, objPtr) char *string, *rest; double d; int i, units; - PixelRep *pixelPtr; string = Tcl_GetStringFromObj(objPtr, NULL); d = strtod(string, &rest); if (rest == string) { - /* - * Must copy string before resetting the result in case a caller - * is trying to convert the interpreter's result to pixels. - */ - - char buf[100]; - - error: - sprintf(buf, "bad screen distance \"%.50s\"", string); - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, buf, NULL); - return TCL_ERROR; + goto error; } while ((*rest != '\0') && isspace(UCHAR(*rest))) { rest++; } - switch (*rest) { - case '\0': - units = -1; - break; - - case 'm': - units = 0; - break; - - case 'c': - units = 1; - break; - case 'i': - units = 2; - break; - - case 'p': - units = 3; - break; - - default: - goto error; + switch (*rest) { + case '\0': + units = -1; + break; + case 'm': + units = 0; + break; + case 'c': + units = 1; + break; + case 'i': + units = 2; + break; + case 'p': + units = 3; + break; + default: + goto error; } /* - * Free the old internalRep before setting the new one. + * Free the old internalRep before setting the new one. */ typePtr = objPtr->typePtr; @@ -357,7 +331,8 @@ SetPixelFromAny(interp, objPtr) if ((units < 0) && (i == d)) { SET_SIMPLEPIXEL(objPtr, i); } else { - pixelPtr = (PixelRep *) ckalloc(sizeof(PixelRep)); + PixelRep *pixelPtr = (PixelRep *) ckalloc(sizeof(PixelRep)); + pixelPtr->value = d; pixelPtr->units = units; pixelPtr->tkwin = NULL; @@ -365,6 +340,21 @@ SetPixelFromAny(interp, objPtr) SET_COMPLEXPIXEL(objPtr, pixelPtr); } return TCL_OK; + + error: + if (interp != NULL) { + /* + * Must copy string before resetting the result in case a caller is + * trying to convert the interpreter's result to pixels. + */ + + char buf[100]; + + sprintf(buf, "bad screen distance \"%.50s\"", string); + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, buf, NULL); + } + return TCL_ERROR; } /* @@ -382,8 +372,8 @@ SetPixelFromAny(interp, objPtr) * result unless "interp" is NULL. * * Side effects: - * If the object is not already a pixel, the conversion will free - * any old internal representation. + * If the object is not already a pixel, the conversion will free any old + * internal representation. * *---------------------------------------------------------------------- */ @@ -438,8 +428,8 @@ Tk_GetMMFromObj(interp, tkwin, objPtr, doublePtr) * None. * * Side effects: - * Frees objPtr's internal representation and sets objPtr's - * internalRep to NULL. + * Frees objPtr's internal representation and sets objPtr's internalRep + * to NULL. * *---------------------------------------------------------------------- */ @@ -458,15 +448,15 @@ FreeMMInternalRep(objPtr) * * DupMMInternalRep -- * - * Initialize the internal representation of a pixel Tcl_Obj to a - * copy of the internal representation of an existing pixel object. + * Initialize the internal representation of a pixel Tcl_Obj to a copy of + * the internal representation of an existing pixel object. * * Results: * None. * * Side effects: - * copyPtr's internal rep is set to the pixel corresponding to - * srcPtr's internal rep. + * copyPtr's internal rep is set to the pixel corresponding to srcPtr's + * internal rep. * *---------------------------------------------------------------------- */ @@ -477,7 +467,7 @@ DupMMInternalRep(srcPtr, copyPtr) register Tcl_Obj *copyPtr; /* Object with internal rep to set. */ { MMRep *oldPtr, *newPtr; - + copyPtr->typePtr = srcPtr->typePtr; oldPtr = (MMRep *) srcPtr->internalRep.otherValuePtr; newPtr = (MMRep *) ckalloc(sizeof(MMRep)); @@ -493,17 +483,16 @@ DupMMInternalRep(srcPtr, copyPtr) * * UpdateStringOfMM -- * - * Update the string representation for a pixel Tcl_Obj - * this function is only called, if the pixel Tcl_Obj has no unit, - * because with units the string representation is created by - * SetMMFromAny + * Update the string representation for a pixel Tcl_Obj this function is + * only called, if the pixel Tcl_Obj has no unit, because with units the + * string representation is created by SetMMFromAny * * Results: - * None. + * None. * * Side effects: - * The object's string is set to a valid string that results from - * the double-to-string conversion. + * The object's string is set to a valid string that results from the + * double-to-string conversion. * *---------------------------------------------------------------------- */ @@ -519,7 +508,7 @@ UpdateStringOfMM(objPtr) mmPtr = (MMRep *) objPtr->internalRep.otherValuePtr; /* assert( mmPtr->units == -1 && objPtr->bytes == NULL ); */ if ((mmPtr->units != -1) || (objPtr->bytes != NULL)) { - Tcl_Panic("UpdateStringOfMM: false precondition"); + Tcl_Panic("UpdateStringOfMM: false precondition"); } Tcl_PrintDouble((Tcl_Interp *) NULL, mmPtr->value, buffer); @@ -535,8 +524,7 @@ UpdateStringOfMM(objPtr) * * SetMMFromAny -- * - * Attempt to generate a mm internal form for the Tcl object - * "objPtr". + * Attempt to generate a mm internal form for the Tcl object "objPtr". * * Results: * The return value is a standard Tcl result. If an error occurs during @@ -544,8 +532,8 @@ UpdateStringOfMM(objPtr) * unless "interp" is NULL. * * Side effects: - * If no error occurs, a mm representation of the object is - * stored internally and the type of "objPtr" is set to mm. + * If no error occurs, a mm representation of the object is stored + * internally and the type of "objPtr" is set to mm. * *---------------------------------------------------------------------- */ @@ -566,8 +554,8 @@ SetMMFromAny(interp, objPtr) if (tclDoubleObjType == NULL) { /* - * Cache the object types for comaprison below. - * This allows optimized checks for standard cases. + * Cache the object types for comaprison below. This allows optimized + * checks for standard cases. */ tclDoubleObjType = Tcl_GetObjType("double"); @@ -583,10 +571,11 @@ SetMMFromAny(interp, objPtr) units = -1; /* - * In the case of ints, we need to ensure that a valid - * string exists in order for int-but-not-string objects - * to be converted back to ints again from mm obj types. + * In the case of ints, we need to ensure that a valid string exists + * in order for int-but-not-string objects to be converted back to + * ints again from mm obj types. */ + (void) Tcl_GetStringFromObj(objPtr, NULL); } else { /* @@ -602,42 +591,38 @@ SetMMFromAny(interp, objPtr) * is trying to convert the interpreter's result to mms. */ - error: - Tcl_AppendResult(interp, "bad screen distance \"", string, - "\"", (char *) NULL); - return TCL_ERROR; - } - while ((*rest != '\0') && isspace(UCHAR(*rest))) { - rest++; - } - switch (*rest) { - case '\0': - units = -1; - break; - - case 'c': - units = 0; - break; - - case 'i': - units = 1; - break; - - case 'm': - units = 2; - break; - - case 'p': - units = 3; - break; - - default: - goto error; + error: + Tcl_AppendResult(interp, "bad screen distance \"", string, + "\"", (char *) NULL); + return TCL_ERROR; + } + while ((*rest != '\0') && isspace(UCHAR(*rest))) { + rest++; + } + + switch (*rest) { + case '\0': + units = -1; + break; + case 'c': + units = 0; + break; + case 'i': + units = 1; + break; + case 'm': + units = 2; + break; + case 'p': + units = 3; + break; + default: + goto error; } } /* - * Free the old internalRep before setting the new one. + * Free the old internalRep before setting the new one. */ typePtr = objPtr->typePtr; @@ -673,8 +658,8 @@ SetMMFromAny(interp, objPtr) * result unless "interp" is NULL. * * Side effects: - * If the object is not already a Tk_Window, the conversion will free - * any old internal representation. + * If the object is not already a Tk_Window, the conversion will free any + * old internal representation. * *---------------------------------------------------------------------- */ @@ -698,8 +683,8 @@ TkGetWindowFromObj(interp, tkwin, objPtr, windowPtr) winPtr = (WindowRep *) objPtr->internalRep.otherValuePtr; if ( winPtr->tkwin == NULL || winPtr->mainPtr == NULL - || winPtr->mainPtr != mainPtr - || winPtr->epoch != mainPtr->deletionEpoch) + || winPtr->mainPtr != mainPtr + || winPtr->epoch != mainPtr->deletionEpoch) { /* Cache is invalid. */ @@ -722,14 +707,15 @@ TkGetWindowFromObj(interp, tkwin, objPtr, windowPtr) *---------------------------------------------------------------------- * * SetWindowFromAny -- + * * Generate a windowObj internal form for the Tcl object "objPtr". * * Results: - * Always returns TCL_OK. + * Always returns TCL_OK. * * Side effects: - * Sets objPtr's internal representation to an uninitialized - * windowObj. Frees the old internal representation, if any. + * Sets objPtr's internal representation to an uninitialized windowObj. + * Frees the old internal representation, if any. * * See also: * TkGetWindowFromObj, which initializes the WindowRep cache. @@ -746,7 +732,7 @@ SetWindowFromAny(interp, objPtr) WindowRep *winPtr; /* - * Free the old internalRep before setting the new one. + * Free the old internalRep before setting the new one. */ Tcl_GetStringFromObj(objPtr, NULL); @@ -771,15 +757,15 @@ SetWindowFromAny(interp, objPtr) * * DupWindowInternalRep -- * - * Initialize the internal representation of a window Tcl_Obj to a - * copy of the internal representation of an existing window object. + * Initialize the internal representation of a window Tcl_Obj to a copy + * of the internal representation of an existing window object. * * Results: * None. * * Side effects: - * copyPtr's internal rep is set to refer to the same window as - * srcPtr's internal rep. + * copyPtr's internal rep is set to refer to the same window as srcPtr's + * internal rep. * *---------------------------------------------------------------------- */ @@ -812,8 +798,8 @@ DupWindowInternalRep(srcPtr, copyPtr) * None. * * Side effects: - * Frees objPtr's internal representation and sets objPtr's - * internalRep to NULL. + * Frees objPtr's internal representation and sets objPtr's internalRep + * to NULL. * *---------------------------------------------------------------------- */ @@ -832,19 +818,19 @@ FreeWindowInternalRep(objPtr) * * TkParsePadAmount -- * - * This procedure parses a padding specification and returns - * the appropriate padding values. A padding specification can - * be either a single pixel width, or a list of two pixel widths. - * If a single pixel width, the amount specified is used for - * padding on both sides. If two amounts are specified, then - * they specify the left/right or top/bottom padding. + * This function parses a padding specification and returns the + * appropriate padding values. A padding specification can be either a + * single pixel width, or a list of two pixel widths. If a single pixel + * width, the amount specified is used for padding on both sides. If two + * amounts are specified, then they specify the left/right or top/bottom + * padding. * * Results: * A standard Tcl return value. * * Side effects: - * An error message is written to the interpreter is something - * is not right. + * An error message is written to the interpreter if something is not + * right. * *-------------------------------------------------------------- */ @@ -854,7 +840,7 @@ TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr) Tcl_Interp *interp; /* Interpreter for error reporting. */ Tk_Window tkwin; /* A window. Needed by Tk_GetPixels() */ Tcl_Obj *specObj; /* The argument to "-padx", "-pady", "-ipadx", - * or "-ipady". The thing to be parsed. */ + * or "-ipady". The thing to be parsed. */ int *halfPtr; /* Write the left/top part of padding here */ int *allPtr; /* Write the total padding here */ { @@ -880,8 +866,8 @@ TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr) } /* - * Pad specifications are a list of one or two elements, each of - * which is a pixel specification. + * Pad specifications are a list of one or two elements, each of which is + * a pixel specification. */ if (Tcl_ListObjGetElements(interp, specObj, &objc, &objv) != TCL_OK) { @@ -906,8 +892,8 @@ TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr) } /* - * Parse the second part if it exists, otherwise it is as if it - * was the same as the first part. + * Parse the second part if it exists, otherwise it is as if it was the + * same as the first part. */ if (objc == 1) { @@ -944,8 +930,8 @@ TkParsePadAmount(interp, tkwin, specObj, halfPtr, allPtr) * None * * Side effects: - * All instances of Tcl_ObjType structues used in Tk are registered - * with Tcl. + * All instances of Tcl_ObjType structues used in Tk are registered with + * Tcl. * *---------------------------------------------------------------------- */ @@ -965,3 +951,11 @@ TkRegisterObjTypes() Tcl_RegisterObjType(&windowObjType); Tcl_RegisterObjType(&tkTextIndexType); } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkOption.c b/generic/tkOption.c index 7f1b007..a0080fc 100644 --- a/generic/tkOption.c +++ b/generic/tkOption.c @@ -1,59 +1,58 @@ -/* +/* * tkOption.c -- * - * This module contains procedures to manage the option - * database, which allows various strings to be associated - * with windows either by name or by class or both. + * This module contains functions to manage the option database, which + * allows various strings to be associated with windows either by name or + * by class or both. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkOption.c,v 1.15 2002/08/05 04:30:40 dgp Exp $ + * RCS: @(#) $Id: tkOption.c,v 1.16 2005/08/10 22:02:22 dkf Exp $ */ #include "tkPort.h" #include "tkInt.h" /* - * The option database is stored as one tree for each main window. - * Each name or class field in an option is associated with a node or - * leaf of the tree. For example, the options "x.y.z" and "x.y*a" - * each correspond to three nodes in the tree; they share the nodes - * "x" and "x.y", but have different leaf nodes. One of the following - * structures exists for each node or leaf in the option tree. It is - * actually stored as part of the parent node, and describes a particular - * child of the parent. - * - * The structure of the option db tree is a little confusing. There are - * four different kinds of nodes in the tree: + * The option database is stored as one tree for each main window. Each name + * or class field in an option is associated with a node or leaf of the tree. + * For example, the options "x.y.z" and "x.y*a" each correspond to three nodes + * in the tree; they share the nodes "x" and "x.y", but have different leaf + * nodes. One of the following structures exists for each node or leaf in the + * option tree. It is actually stored as part of the parent node, and + * describes a particular child of the parent. + * + * The structure of the option db tree is a little confusing. There are four + * different kinds of nodes in the tree: * interior class nodes * interior name nodes * leaf class nodes * leaf name nodes * * All interior nodes refer to _window_ classes and names; all leaf nodes - * refer to _option_ classes and names. When looking for a particular option, + * refer to _option_ classes and names. When looking for a particular option, * therefore, you must compare interior node values to corresponding window * values, and compare leaf node values to corresponding option values. * * The tree is actually stored in a collection of arrays; there is one each - * combination of WILDCARD/EXACT and CLASS/NAME and NODE/LEAF. The NODE arrays + * combination of WILDCARD/EXACT and CLASS/NAME and NODE/LEAF. The NODE arrays * contain the interior nodes of the tree; each element has a pointer to an - * array of elements which are the leaves of the tree. The LEAF arrays, rather + * array of elements which are the leaves of the tree. The LEAF arrays, rather * than holding the leaves of the tree, hold a cached subset of the option * database, consisting of the values of all defined options for a single * window, and some additional information about each ancestor of the window - * (since some options may be inherited from a parent), all the way back to the - * root window. + * (since some options may be inherited from a parent), all the way back to + * the root window. * * Each time a call is made to Tk_GetOption, Tk will attempt to use the cached - * information to satisfy the lookup. If the call is for a window other than + * information to satisfy the lookup. If the call is for a window other than * that for which options are currently cached, the portion of the cache that - * contains information for common ancestors of the two windows is retained and - * the remainder is discarded and rebuilt with new information for the new + * contains information for common ancestors of the two windows is retained + * and the remainder is discarded and rebuilt with new information for the new * window. */ @@ -61,35 +60,34 @@ typedef struct Element { Tk_Uid nameUid; /* Name or class from one element of * an option spec. */ union { - struct ElArray *arrayPtr; /* If this is an intermediate node, - * a pointer to a structure describing + struct ElArray *arrayPtr; /* If this is an intermediate node, a + * pointer to a structure describing * the remaining elements of all - * options whose prefixes are the - * same up through this element. */ + * options whose prefixes are the same + * up through this element. */ Tk_Uid valueUid; /* For leaf nodes, this is the string * value of the option. */ } child; int priority; /* Used to select among matching - * options. Includes both the - * priority level and a serial #. - * Greater value means higher - * priority. Irrelevant except in - * leaf nodes. */ - int flags; /* OR-ed combination of bits. See + * options. Includes both the priority + * level and a serial #. Greater value + * means higher priority. Irrelevant + * except in leaf nodes. */ + int flags; /* OR-ed combination of bits. See * below for values. */ } Element; /* * Flags in Element structures: * - * CLASS - Non-zero means this element refers to a class, - * Zero means this element refers to a name. - * NODE - Zero means this is a leaf element (the child - * field is a value, not a pointer to another node). - * One means this is a node element. - * WILDCARD - Non-zero means this there was a star in the - * original specification just before this element. - * Zero means there was a dot. + * CLASS - Non-zero means this element refers to a class, zero + * means this element refers to a name. + * NODE - Zero means this is a leaf element (the child field is + * a value, not a pointer to another node). One means + * this is a node element. + * WILDCARD - Non-zero means this there was a star in the original + * specification just before this element. Zero means + * there was a dot. */ #define TYPE_MASK 0x7 @@ -108,25 +106,22 @@ typedef struct Element { #define WILDCARD_NODE_CLASS 0x7 /* - * The following structure is used to manage a dynamic array of - * Elements. These structures are used for two purposes: to store - * the contents of a node in the option tree, and for the option - * stacks described below. + * The following structure is used to manage a dynamic array of Elements. + * These structures are used for two purposes: to store the contents of a node + * in the option tree, and for the option stacks described below. */ typedef struct ElArray { - int arraySize; /* Number of elements actually - * allocated in the "els" array. */ - int numUsed; /* Number of elements currently in - * use out of els. */ + int arraySize; /* Number of elements actually allocated in + * the "els" array. */ + int numUsed; /* Number of elements currently in use out of + * els. */ Element *nextToUse; /* Pointer to &els[numUsed]. */ - Element els[1]; /* Array of structures describing - * children of this node. The - * array will actually contain enough - * elements for all of the children - * (and even a few extras, perhaps). - * This must be the last field in - * the structure. */ + Element els[1]; /* Array of structures describing children of + * this node. The array will actually contain + * enough elements for all of the children + * (and even a few extras, perhaps). This must + * be the last field in the structure. */ } ElArray; #define EL_ARRAY_SIZE(numEls) ((unsigned) (sizeof(ElArray) \ @@ -135,54 +130,53 @@ typedef struct ElArray { /* * In addition to the option tree, which is a relatively static structure, - * there are eight additional structures called "stacks", which are used - * to speed up queries into the option database. The stack structures - * are designed for the situation where an individual widget makes repeated - * requests for its particular options. The requests differ only in - * their last name/class, so during the first request we extract all - * the options pertaining to the particular widget and save them in a - * stack-like cache; subsequent requests for the same widget can search - * the cache relatively quickly. In fact, the cache is a hierarchical - * one, storing a list of relevant options for this widget and all of - * its ancestors up to the application root; hence the name "stack". - * - * Each of the eight stacks consists of an array of Elements, ordered in - * terms of levels in the window hierarchy. All the elements relevant - * for the top-level widget appear first in the array, followed by all - * those from the next-level widget on the path to the current widget, - * etc. down to those for the current widget. - * - * Cached information is divided into eight stacks according to the - * CLASS, NODE, and WILDCARD flags. Leaf and non-leaf information is - * kept separate to speed up individual probes (non-leaf information is - * only relevant when building the stacks, but isn't relevant when - * making probes; similarly, only non-leaf information is relevant - * when the stacks are being extended to the next widget down in the - * widget hierarchy). Wildcard elements are handled separately from - * "exact" elements because once they appear at a particular level in - * the stack they remain active for all deeper levels; exact elements - * are only relevant at a particular level. For example, when searching - * for options relevant in a particular window, the entire wildcard - * stacks get checked, but only the portions of the exact stacks that - * pertain to the window's parent. Lastly, name and class stacks are - * kept separate because different search keys are used when searching - * them; keeping them separate speeds up the searches. + * there are eight additional structures called "stacks", which are used to + * speed up queries into the option database. The stack structures are + * designed for the situation where an individual widget makes repeated + * requests for its particular options. The requests differ only in their last + * name/class, so during the first request we extract all the options + * pertaining to the particular widget and save them in a stack-like cache; + * subsequent requests for the same widget can search the cache relatively + * quickly. In fact, the cache is a hierarchical one, storing a list of + * relevant options for this widget and all of its ancestors up to the + * application root; hence the name "stack". + * + * Each of the eight stacks consists of an array of Elements, ordered in terms + * of levels in the window hierarchy. All the elements relevant for the + * top-level widget appear first in the array, followed by all those from the + * next-level widget on the path to the current widget, etc. down to those for + * the current widget. + * + * Cached information is divided into eight stacks according to the CLASS, + * NODE, and WILDCARD flags. Leaf and non-leaf information is kept separate to + * speed up individual probes (non-leaf information is only relevant when + * building the stacks, but isn't relevant when making probes; similarly, only + * non-leaf information is relevant when the stacks are being extended to the + * next widget down in the widget hierarchy). Wildcard elements are handled + * separately from "exact" elements because once they appear at a particular + * level in the stack they remain active for all deeper levels; exact elements + * are only relevant at a particular level. For example, when searching for + * options relevant in a particular window, the entire wildcard stacks get + * checked, but only the portions of the exact stacks that pertain to the + * window's parent. Lastly, name and class stacks are kept separate because + * different search keys are used when searching them; keeping them separate + * speeds up the searches. */ #define NUM_STACKS 8 /* - * One of the following structures is used to keep track of each - * level in the stacks. + * One of the following structures is used to keep track of each level in the + * stacks. */ typedef struct StackLevel { TkWindow *winPtr; /* Window corresponding to this stack * level. */ - int bases[NUM_STACKS]; /* For each stack, index of first - * element on stack corresponding to - * this level (used to restore "numUsed" - * fields when popping out of a level. */ + int bases[NUM_STACKS]; /* For each stack, index of first element on + * stack corresponding to this level (used to + * restore "numUsed" fields when popping out + * of a level. */ } StackLevel; typedef struct ThreadSpecificData { @@ -190,59 +184,51 @@ typedef struct ThreadSpecificData { * for the current thread needs to be * initialized. */ ElArray *stacks[NUM_STACKS]; - TkWindow *cachedWindow; - /* Lowest-level window currently - * loaded in stacks at present. - * NULL means stacks have never - * been used, or have been - * invalidated because of a change - * to the database. */ + TkWindow *cachedWindow; /* Lowest-level window currently loaded in + * stacks at present. NULL means stacks have + * never been used, or have been invalidated + * because of a change to the database. */ /* - * Information about all of the stack levels that are currently - * active. This array grows dynamically to become as large as needed. + * Information about all of the stack levels that are currently active. + * This array grows dynamically to become as large as needed. */ StackLevel *levels; /* Array describing current stack. */ int numLevels; /* Total space allocated. */ - int curLevel; /* Highest level currently in use. Note: - * curLevel is never 0! (I don't remember - * why anymore...) */ - /* - * The variable below is a serial number for all options entered into - * the database so far. It increments on each addition to the option - * database. It is used in computing option priorities, so that the - * most recent entry wins when choosing between options at the same - * priority level. - */ - - int serial; - Element defaultMatch; /* Special "no match" Element to use as + int curLevel; /* Highest level currently in use. Note: + * curLevel is never 0! (I don't remember why + * anymore...) */ + int serial; /* A serial number for all options entered + * into the database so far. It increments on + * each addition to the option database. It is + * used in computing option priorities, so + * that the most recent entry wins when + * choosing between options at the same + * priority level. + */ + Element defaultMatch; /* Special "no match" Element to use as * default for searches.*/ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; /* - * Forward declarations for procedures defined in this file: + * Forward declarations for functions defined in this file: */ -static int AddFromString _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window tkwin, char *string, int priority)); -static void ClearOptionTree _ANSI_ARGS_((ElArray *arrayPtr)); -static ElArray * ExtendArray _ANSI_ARGS_((ElArray *arrayPtr, - Element *elPtr)); -static void ExtendStacks _ANSI_ARGS_((ElArray *arrayPtr, - int leaf)); -static int GetDefaultOptions _ANSI_ARGS_((Tcl_Interp *interp, - TkWindow *winPtr)); -static ElArray * NewArray _ANSI_ARGS_((int numEls)); -static void OptionThreadExitProc _ANSI_ARGS_(( - ClientData clientData)); -static void OptionInit _ANSI_ARGS_((TkMainInfo *mainPtr)); -static int ParsePriority _ANSI_ARGS_((Tcl_Interp *interp, - char *string)); -static int ReadOptionFile _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window tkwin, char *fileName, int priority)); -static void SetupStacks _ANSI_ARGS_((TkWindow *winPtr, int leaf)); +static int AddFromString(Tcl_Interp *interp, Tk_Window tkwin, + char *string, int priority); +static void ClearOptionTree(ElArray *arrayPtr); +static ElArray * ExtendArray(ElArray *arrayPtr, Element *elPtr); +static void ExtendStacks(ElArray *arrayPtr, int leaf); +static int GetDefaultOptions(Tcl_Interp *interp, + TkWindow *winPtr); +static ElArray * NewArray(int numEls); +static void OptionThreadExitProc(ClientData clientData); +static void OptionInit(TkMainInfo *mainPtr); +static int ParsePriority(Tcl_Interp *interp, char *string); +static int ReadOptionFile(Tcl_Interp *interp, Tk_Window tkwin, + char *fileName, int priority); +static void SetupStacks(TkWindow *winPtr, int leaf); /* *-------------------------------------------------------------- @@ -262,14 +248,14 @@ static void SetupStacks _ANSI_ARGS_((TkWindow *winPtr, int leaf)); void Tk_AddOption(tkwin, name, value, priority) - Tk_Window tkwin; /* Window token; option will be associated + Tk_Window tkwin; /* Window token; option will be associated * with main window for this window. */ CONST char *name; /* Multi-element name of option. */ CONST char *value; /* String value for option. */ - int priority; /* Overall priority level to use for - * this option, such as TK_USER_DEFAULT_PRIO - * or TK_INTERACTIVE_PRIO. Must be between - * 0 and TK_MAX_PRIO. */ + int priority; /* Overall priority level to use for this + * option, such as TK_USER_DEFAULT_PRIO or + * TK_INTERACTIVE_PRIO. Must be between 0 and + * TK_MAX_PRIO. */ { TkWindow *winPtr = ((TkWindow *) tkwin)->mainPtr->winPtr; register ElArray **arrayPtrPtr; @@ -280,18 +266,17 @@ Tk_AddOption(tkwin, name, value, priority) int count, firstField, length; #define TMP_SIZE 100 char tmp[TMP_SIZE+1]; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (winPtr->mainPtr->optionRootPtr == NULL) { OptionInit(winPtr->mainPtr); } - tsdPtr->cachedWindow = NULL; /* Invalidate the cache. */ + tsdPtr->cachedWindow = NULL;/* Invalidate the cache. */ /* - * Compute the priority for the new element, including both the - * overall level and the serial number (to disambiguate with the - * level). + * Compute the priority for the new element, including both the overall + * level and the serial number (to disambiguate with the level). */ if (priority < 0) { @@ -309,11 +294,10 @@ Tk_AddOption(tkwin, name, value, priority) arrayPtrPtr = &(((TkWindow *) tkwin)->mainPtr->optionRootPtr); p = name; for (firstField = 1; ; firstField = 0) { - /* - * Scan the next field from the name and convert it to a Tk_Uid. - * Must copy the field before calling Tk_Uid, so that a terminating - * NULL may be added without modifying the source string. + * Scan the next field from the name and convert it to a Tk_Uid. Must + * copy the field before calling Tk_Uid, so that a terminating NULL + * may be added without modifying the source string. */ if (*p == '*') { @@ -338,12 +322,10 @@ Tk_AddOption(tkwin, name, value, priority) } if (*p != 0) { - /* - * New element will be a node. If this option can't possibly - * apply to this main window, then just skip it. Otherwise, - * add it to the parent, if it isn't already there, and descend - * into it. + * New element will be a node. If this option can't possibly apply + * to this main window, then just skip it. Otherwise, add it to + * the parent, if it isn't already there, and descend into it. */ newEl.flags |= NODE; @@ -370,11 +352,10 @@ Tk_AddOption(tkwin, name, value, priority) p++; } } else { - /* - * New element is a leaf. Add it to the parent, if it isn't - * already there. If it exists already, keep whichever value - * has highest priority. + * New element is a leaf. Add it to the parent, if it isn't + * already there. If it exists already, keep whichever value has + * highest priority. */ newEl.child.valueUid = Tk_GetUid(value); @@ -405,27 +386,26 @@ Tk_AddOption(tkwin, name, value, priority) * Retrieve an option from the option database. * * Results: - * The return value is the value specified in the option - * database for the given name and class on the given - * window. If there is nothing specified in the database - * for that option, then NULL is returned. + * The return value is the value specified in the option database for the + * given name and class on the given window. If there is nothing + * specified in the database for that option, then NULL is returned. * * Side effects: - * The internal caches used to speed up option mapping - * may be modified, if this tkwin is different from the - * last tkwin used for option retrieval. + * The internal caches used to speed up option mapping may be modified, + * if this tkwin is different from the last tkwin used for option + * retrieval. * *-------------------------------------------------------------- */ Tk_Uid Tk_GetOption(tkwin, name, className) - Tk_Window tkwin; /* Token for window that option is - * associated with. */ + Tk_Window tkwin; /* Token for window that option is associated + * with. */ CONST char *name; /* Name of option. */ - CONST char *className; /* Class of option. NULL means there - * is no class for this option: just - * check for name. */ + CONST char *className; /* Class of option. NULL means there is no + * class for this option: just check for + * name. */ { Tk_Uid nameId, classId = NULL; char *masqName; @@ -433,12 +413,12 @@ Tk_GetOption(tkwin, name, className) register int count; StackLevel *levelPtr; int stackDepth[NUM_STACKS]; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* - * Note: no need to call OptionInit here: it will be done by - * the SetupStacks call below (squeeze out those nanoseconds). + * Note: no need to call OptionInit here: it will be done by the + * SetupStacks call below (squeeze out those nanoseconds). */ if (tkwin != (Tk_Window) tsdPtr->cachedWindow) { @@ -448,32 +428,33 @@ Tk_GetOption(tkwin, name, className) /* * Get a default "best" match. */ - + bestPtr = &tsdPtr->defaultMatch; /* * For megawidget support, we want to have some widget options masquerade - * as options for other widgets. For example, a combobox has a button in + * as options for other widgets. For example, a combobox has a button in * it; this button ought to pick up the *Button.background, etc., options. * But because the class of the widget is Combobox, our normal search * won't get that option. * * To work around this, the option name field syntax was extended to allow * for a "." in the name; if this character occurs in the name, then it - * indicates that this name contains a new window class and an option name, - * ie, "Button.foreground". If we see this form in the name field, we - * query the option database directly (since the option stacks will not + * indicates that this name contains a new window class and an option + * name, ie, "Button.foreground". If we see this form in the name field, + * we query the option database directly (since the option stacks will not * have the information we need). */ masqName = strchr(name, (int)'.'); if (masqName != NULL) { /* - * This option is masquerading with a different window class. - * Search the stack to the depth it was before the current window's + * This option is masquerading with a different window class. Search + * the stack to the depth it was before the current window's * information was pushed (the value for which is stored in the bases * field). */ + levelPtr = &tsdPtr->levels[tsdPtr->curLevel]; nameId = Tk_GetUid(masqName+1); for (count = 0; count < NUM_STACKS; count++) { @@ -481,9 +462,10 @@ Tk_GetOption(tkwin, name, className) } } else { /* - * No option masquerading here. Just use the current level to get the + * No option masquerading here. Just use the current level to get the * stack depths. */ + nameId = Tk_GetUid(name); for (count = 0; count < NUM_STACKS; count++) { stackDepth[count] = tsdPtr->stacks[count]->numUsed; @@ -530,11 +512,11 @@ Tk_GetOption(tkwin, name, className) } } } - + /* - * If this option was masquerading with a different window class, - * probe the option database now. Note that this will be inefficient - * if the option database is densely populated, or if the widget has many + * If this option was masquerading with a different window class, probe + * the option database now. Note that this will be inefficient if the + * option database is densely populated, or if the widget has many * masquerading options. */ @@ -543,43 +525,42 @@ Tk_GetOption(tkwin, name, className) Tk_Uid nodeId, winClassId, winNameId; unsigned int classNameLength; register Element *nodePtr, *leafPtr; - static int searchOrder[] = { EXACT_NODE_NAME, - WILDCARD_NODE_NAME, - EXACT_NODE_CLASS, - WILDCARD_NODE_CLASS, - -1 }; + static int searchOrder[] = { + EXACT_NODE_NAME, WILDCARD_NODE_NAME, EXACT_NODE_CLASS, + WILDCARD_NODE_CLASS, -1 + }; int *currentPtr, currentStack, leafCount; - + /* * Extract the masquerade class name from the name field. */ - + classNameLength = (unsigned int)(masqName - name); - masqClass = (char *)ckalloc(classNameLength + 1); + masqClass = (char *) ckalloc(classNameLength + 1); strncpy(masqClass, name, classNameLength); masqClass[classNameLength] = '\0'; - - winClassId = Tk_GetUid(masqClass); + + winClassId = Tk_GetUid(masqClass); ckfree(masqClass); - winNameId = ((TkWindow *)tkwin)->nameUid; + winNameId = ((TkWindow *)tkwin)->nameUid; levelPtr = &tsdPtr->levels[tsdPtr->curLevel]; for (currentPtr = searchOrder; *currentPtr != -1; currentPtr++) { currentStack = *currentPtr; - nodePtr = tsdPtr->stacks[currentStack]->els; - count = levelPtr->bases[currentStack]; + nodePtr = tsdPtr->stacks[currentStack]->els; + count = levelPtr->bases[currentStack]; /* - * For wildcard stacks, check all entries; for non-wildcard + * For wildcard stacks, check all entries; for non-wildcard * stacks, only check things that matched in the parent. */ - + if (!(currentStack & WILDCARD)) { nodePtr += levelPtr[-1].bases[currentStack]; count -= levelPtr[-1].bases[currentStack]; } - + if (currentStack && CLASS) { nodeId = winClassId; } else { @@ -588,8 +569,8 @@ Tk_GetOption(tkwin, name, className) for ( ; count > 0; nodePtr++, count--) { if (nodePtr->nameUid == nodeId) { - leafPtr = nodePtr->child.arrayPtr->els; - leafCount = nodePtr->child.arrayPtr->numUsed; + leafPtr = nodePtr->child.arrayPtr->els; + leafCount = nodePtr->child.arrayPtr->numUsed; for ( ; leafCount > 0; leafPtr++, leafCount--) { if (leafPtr->flags & CLASS && className != NULL) { if (leafPtr->nameUid == classId && @@ -607,7 +588,7 @@ Tk_GetOption(tkwin, name, className) } } } - + return bestPtr->child.valueUid; } @@ -616,8 +597,8 @@ Tk_GetOption(tkwin, name, className) * * Tk_OptionObjCmd -- * - * This procedure is invoked to process the "option" Tcl command. - * See the user documentation for details on what it does. + * This function is invoked to process the "option" Tcl command. See the + * user documentation for details on what it does. * * Results: * A standard Tcl result. @@ -630,15 +611,14 @@ Tk_GetOption(tkwin, name, className) int Tk_OptionObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Main window associated with - * interpreter. */ + ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of Tcl_Obj arguments. */ Tcl_Obj *CONST objv[]; /* Tcl_Obj arguments. */ { Tk_Window tkwin = (Tk_Window) clientData; int index, result; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); static CONST char *optionCmds[] = { @@ -659,85 +639,85 @@ Tk_OptionObjCmd(clientData, interp, objc, objv) if (result != TCL_OK) { return result; } - + result = TCL_OK; switch ((enum optionVals) index) { - case OPTION_ADD: { - int priority; - if ((objc != 4) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 2, objv, "pattern value ?priority?"); + case OPTION_ADD: { + int priority; + if ((objc != 4) && (objc != 5)) { + Tcl_WrongNumArgs(interp, 2, objv, "pattern value ?priority?"); + return TCL_ERROR; + } + + if (objc == 4) { + priority = TK_INTERACTIVE_PRIO; + } else { + priority = ParsePriority(interp, Tcl_GetString(objv[4])); + if (priority < 0) { return TCL_ERROR; } + } + Tk_AddOption(tkwin, Tcl_GetString(objv[2]), Tcl_GetString(objv[3]), + priority); + break; + } - if (objc == 4) { - priority = TK_INTERACTIVE_PRIO; - } else { - priority = ParsePriority(interp, Tcl_GetString(objv[4])); - if (priority < 0) { - return TCL_ERROR; - } - } - Tk_AddOption(tkwin, Tcl_GetString(objv[2]), - Tcl_GetString(objv[3]), priority); - break; + case OPTION_CLEAR: { + TkMainInfo *mainPtr; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 2, objv, ""); + return TCL_ERROR; + } + mainPtr = ((TkWindow *) tkwin)->mainPtr; + if (mainPtr->optionRootPtr != NULL) { + ClearOptionTree(mainPtr->optionRootPtr); + mainPtr->optionRootPtr = NULL; } + tsdPtr->cachedWindow = NULL; + break; + } - case OPTION_CLEAR: { - TkMainInfo *mainPtr; + case OPTION_GET: { + Tk_Window window; + Tk_Uid value; - if (objc != 2) { - Tcl_WrongNumArgs(interp, 2, objv, ""); - return TCL_ERROR; - } - mainPtr = ((TkWindow *) tkwin)->mainPtr; - if (mainPtr->optionRootPtr != NULL) { - ClearOptionTree(mainPtr->optionRootPtr); - mainPtr->optionRootPtr = NULL; - } - tsdPtr->cachedWindow = NULL; - break; + if (objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "window name class"); + return TCL_ERROR; + } + window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin); + if (window == NULL) { + return TCL_ERROR; } + value = Tk_GetOption(window, Tcl_GetString(objv[3]), + Tcl_GetString(objv[4])); + if (value != NULL) { + Tcl_SetResult(interp, (char *)value, TCL_STATIC); + } + break; + } - case OPTION_GET: { - Tk_Window window; - Tk_Uid value; - - if (objc != 5) { - Tcl_WrongNumArgs(interp, 2, objv, "window name class"); - return TCL_ERROR; - } - window = Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin); - if (window == NULL) { - return TCL_ERROR; - } - value = Tk_GetOption(window, Tcl_GetString(objv[3]), - Tcl_GetString(objv[4])); - if (value != NULL) { - Tcl_SetResult(interp, (char *)value, TCL_STATIC); - } - break; + case OPTION_READFILE: { + int priority; + + if ((objc != 3) && (objc != 4)) { + Tcl_WrongNumArgs(interp, 2, objv, "fileName ?priority?"); + return TCL_ERROR; } - case OPTION_READFILE: { - int priority; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 2, objv, "fileName ?priority?"); + if (objc == 4) { + priority = ParsePriority(interp, Tcl_GetString(objv[3])); + if (priority < 0) { return TCL_ERROR; } - - if (objc == 4) { - priority = ParsePriority(interp, Tcl_GetString(objv[3])); - if (priority < 0) { - return TCL_ERROR; - } - } else { - priority = TK_INTERACTIVE_PRIO; - } - result = ReadOptionFile(interp, tkwin, Tcl_GetString(objv[2]), - priority); - break; + } else { + priority = TK_INTERACTIVE_PRIO; } + result = ReadOptionFile(interp, tkwin, Tcl_GetString(objv[2]), + priority); + break; + } } return result; } @@ -747,16 +727,14 @@ Tk_OptionObjCmd(clientData, interp, objc, objv) * * TkOptionDeadWindow -- * - * This procedure is called whenever a window is deleted. - * It cleans up any option-related stuff associated with - * the window. + * This function is called whenever a window is deleted. It cleans up any + * option-related stuff associated with the window. * * Results: * None. * * Side effects: - * Option-related resources are freed. See code below - * for details. + * Option-related resources are freed. See code below for details. * *-------------------------------------------------------------- */ @@ -765,7 +743,7 @@ void TkOptionDeadWindow(winPtr) register TkWindow *winPtr; /* Window to be cleaned up. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* @@ -783,8 +761,7 @@ TkOptionDeadWindow(winPtr) } /* - * If this window was a main window, then delete its option - * database. + * If this window was a main window, then delete its option database. */ if ((winPtr->mainPtr != NULL) && (winPtr->mainPtr->winPtr == winPtr) @@ -799,10 +776,9 @@ TkOptionDeadWindow(winPtr) * * TkOptionClassChanged -- * - * This procedure is invoked when a window's class changes. If - * the window is on the option cache, this procedure flushes - * any information for the window, since the new class could change - * what is relevant. + * This function is invoked when a window's class changes. If the window + * is on the option cache, this function flushes any information for the + * window, since the new class could change what is relevant. * * Results: * None. @@ -819,7 +795,7 @@ TkOptionClassChanged(winPtr) { int i, j, *basePtr; ElArray *arrayPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (winPtr->optionLevel == -1) { @@ -827,8 +803,8 @@ TkOptionClassChanged(winPtr) } /* - * Find the lowest stack level that refers to this window, then - * flush all of the levels above the matching one. + * Find the lowest stack level that refers to this window, then flush all + * of the levels above the matching one. */ for (i = 1; i <= tsdPtr->curLevel; i++) { @@ -861,9 +837,9 @@ TkOptionClassChanged(winPtr) * Parse a string priority value. * * Results: - * The return value is the integer priority level corresponding - * to string, or -1 if string doesn't point to a valid priority level. - * In this case, an error message is left in the interp's result. + * The return value is the integer priority level corresponding to + * string, or -1 if string doesn't point to a valid priority level. In + * this case, an error message is left in the interp's result. * * Side effects: * None. @@ -915,17 +891,17 @@ ParsePriority(interp, string) * * AddFromString -- * - * Given a string containing lines in the standard format for - * X resources (see other documentation for details on what this - * is), parse the resource specifications and enter them as options - * for tkwin's main window. + * Given a string containing lines in the standard format for X resources + * (see other documentation for details on what this is), parse the + * resource specifications and enter them as options for tkwin's main + * window. * * Results: - * The return value is a standard Tcl return code. In the case of - * an error in parsing string, TCL_ERROR will be returned and an - * error message will be left in the interp's result. The memory at - * string is totally trashed by this procedure. If you care about - * its contents, make a copy before calling here. + * The return value is a standard Tcl return code. In the case of an + * error in parsing string, TCL_ERROR will be returned and an error + * message will be left in the interp's result. The memory at string is + * totally trashed by this function. If you care about its contents, make + * a copy before calling here. * * Side effects: * None. @@ -936,13 +912,13 @@ ParsePriority(interp, string) static int AddFromString(interp, tkwin, string, priority) Tcl_Interp *interp; /* Interpreter to use for reporting results. */ - Tk_Window tkwin; /* Token for window: options are entered - * for this window's main window. */ + Tk_Window tkwin; /* Token for window: options are entered for + * this window's main window. */ char *string; /* String containing option specifiers. */ - int priority; /* Priority level to use for options in - * this string, such as TK_USER_DEFAULT_PRIO - * or TK_INTERACTIVE_PRIO. Must be between - * 0 and TK_MAX_PRIO. */ + int priority; /* Priority level to use for options in this + * string, such as TK_USER_DEFAULT_PRIO or + * TK_INTERACTIVE_PRIO. Must be between 0 and + * TK_MAX_PRIO. */ { register char *src, *dst; char *name, *value; @@ -973,7 +949,7 @@ AddFromString(interp, tkwin, string, priority) src++; lineNum++; continue; - } + } if (*src == '\0') { break; } @@ -987,7 +963,7 @@ AddFromString(interp, tkwin, string, priority) while (*src != ':') { if ((*src == '\0') || (*src == '\n')) { char buf[32 + TCL_INTEGER_SPACE]; - + sprintf(buf, "missing colon on line %d", lineNum); Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; @@ -1022,7 +998,7 @@ AddFromString(interp, tkwin, string, priority) } if (*src == '\0') { char buf[32 + TCL_INTEGER_SPACE]; - + sprintf(buf, "missing value on line %d", lineNum); Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; @@ -1037,7 +1013,7 @@ AddFromString(interp, tkwin, string, priority) while (*src != '\n') { if (*src == '\0') { char buf[32 + TCL_INTEGER_SPACE]; - + sprintf(buf, "missing newline on line %d", lineNum); Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; @@ -1069,13 +1045,13 @@ AddFromString(interp, tkwin, string, priority) * * ReadOptionFile -- * - * Read a file of options ("resources" in the old X terminology) - * and load them into the option database. + * Read a file of options ("resources" in the old X terminology) and load + * them into the option database. * * Results: - * The return value is a standard Tcl return code. In the case of - * an error in parsing string, TCL_ERROR will be returned and an - * error message will be left in the interp's result. + * The return value is a standard Tcl return code. In the case of an + * error in parsing string, TCL_ERROR will be returned and an error + * message will be left in the interp's result. * * Side effects: * None. @@ -1086,13 +1062,13 @@ AddFromString(interp, tkwin, string, priority) static int ReadOptionFile(interp, tkwin, fileName, priority) Tcl_Interp *interp; /* Interpreter to use for reporting results. */ - Tk_Window tkwin; /* Token for window: options are entered - * for this window's main window. */ + Tk_Window tkwin; /* Token for window: options are entered for + * this window's main window. */ char *fileName; /* Name of file containing options. */ - int priority; /* Priority level to use for options in - * this file, such as TK_USER_DEFAULT_PRIO - * or TK_INTERACTIVE_PRIO. Must be between - * 0 and TK_MAX_PRIO. */ + int priority; /* Priority level to use for options in this + * file, such as TK_USER_DEFAULT_PRIO or + * TK_INTERACTIVE_PRIO. Must be between 0 and + * TK_MAX_PRIO. */ { CONST char *realName; char *buffer; @@ -1103,13 +1079,13 @@ ReadOptionFile(interp, tkwin, fileName, priority) /* * Prevent file system access in a safe interpreter. */ - + if (Tcl_IsSafe(interp)) { Tcl_AppendResult(interp, "can't read options from a file in a", " safe interpreter", (char *) NULL); return TCL_ERROR; } - + realName = Tcl_TranslateFileName(interp, fileName, &newName); if (realName == NULL) { return TCL_ERROR; @@ -1124,10 +1100,10 @@ ReadOptionFile(interp, tkwin, fileName, priority) } /* - * Compute size of file by seeking to the end of the file. This will + * Compute size of file by seeking to the end of the file. This will * overallocate if we are performing CRLF translation. */ - + bufferSize = (int) Tcl_Seek(chan, (Tcl_WideInt) 0, SEEK_END); (void) Tcl_Seek(chan, (Tcl_WideInt) 0, SEEK_SET); @@ -1161,9 +1137,8 @@ ReadOptionFile(interp, tkwin, fileName, priority) * Create a new ElArray structure of a given size. * * Results: - * The return value is a pointer to a properly initialized - * element array with "numEls" space. The array is marked - * as having no active elements. + * The return value is a pointer to a properly initialized element array + * with "numEls" space. The array is marked as having no active elements. * * Side effects: * Memory is allocated. @@ -1189,12 +1164,11 @@ NewArray(numEls) * * ExtendArray -- * - * Add a new element to an array, extending the array if - * necessary. + * Add a new element to an array, extending the array if necessary. * * Results: - * The return value is a pointer to the new array, which - * will be different from arrayPtr if the array got expanded. + * The return value is a pointer to the new array, which will be + * different from arrayPtr if the array got expanded. * * Side effects: * Memory may be allocated or freed. @@ -1204,8 +1178,8 @@ NewArray(numEls) static ElArray * ExtendArray(arrayPtr, elPtr) - register ElArray *arrayPtr; /* Array to be extended. */ - register Element *elPtr; /* Element to be copied into array. */ + register ElArray *arrayPtr; /* Array to be extended. */ + register Element *elPtr; /* Element to be copied into array. */ { /* * If the current array has filled up, make it bigger. @@ -1235,40 +1209,40 @@ ExtendArray(arrayPtr, elPtr) * * SetupStacks -- * - * Arrange the stacks so that they cache all the option - * information for a particular window. + * Arrange the stacks so that they cache all the option information for a + * particular window. * * Results: * None. * * Side effects: - * The stacks are modified to hold information for tkwin - * and all its ancestors in the window hierarchy. + * The stacks are modified to hold information for tkwin and all its + * ancestors in the window hierarchy. * *-------------------------------------------------------------- */ static void SetupStacks(winPtr, leaf) - TkWindow *winPtr; /* Window for which information is to - * be cached. */ - int leaf; /* Non-zero means this is the leaf - * window being probed. Zero means this - * is an ancestor of the desired leaf. */ + TkWindow *winPtr; /* Window for which information is to be + * cached. */ + int leaf; /* Non-zero means this is the leaf window + * being probed. Zero means this is an + * ancestor of the desired leaf. */ { int level, i, *iPtr; register StackLevel *levelPtr; register ElArray *arrayPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* - * The following array defines the order in which the current - * stacks are searched to find matching entries to add to the - * stacks. Given the current priority-based scheme, the order - * below is no longer relevant; all that matters is that an - * element is on the list *somewhere*. The ordering is a relic - * of the old days when priorities were determined differently. + * The following array defines the order in which the current stacks are + * searched to find matching entries to add to the stacks. Given the + * current priority-based scheme, the order below is no longer relevant; + * all that matters is that an element is on the list *somewhere*. The + * ordering is a relic of the old days when priorities were determined + * differently. */ static int searchOrder[] = {WILDCARD_NODE_CLASS, WILDCARD_NODE_NAME, @@ -1279,8 +1253,7 @@ SetupStacks(winPtr, leaf) } /* - * Step 1: make sure that options are cached for this window's - * parent. + * Step 1: make sure that options are cached for this window's parent. */ if (winPtr->parentPtr != NULL) { @@ -1295,8 +1268,8 @@ SetupStacks(winPtr, leaf) } /* - * Step 2: pop extra unneeded information off the stacks and - * mark those windows as no longer having cached information. + * Step 2: pop extra unneeded information off the stacks and mark those + * windows as no longer having cached information. */ if (tsdPtr->curLevel >= level) { @@ -1314,9 +1287,9 @@ SetupStacks(winPtr, leaf) tsdPtr->curLevel = winPtr->optionLevel = level; /* - * Step 3: if the root database information isn't loaded or - * isn't valid, initialize level 0 of the stack from the - * database root (this only happens if winPtr is a main window). + * Step 3: if the root database information isn't loaded or isn't valid, + * initialize level 0 of the stack from the database root (this only + * happens if winPtr is a main window). */ if ((tsdPtr->curLevel == 1) @@ -1331,10 +1304,9 @@ SetupStacks(winPtr, leaf) } /* - * Step 4: create a new stack level; grow the level array if - * we've run out of levels. Clear the stacks for EXACT_LEAF_NAME - * and EXACT_LEAF_CLASS (anything that was there is of no use - * any more). + * Step 4: create a new stack level; grow the level array if we've run out + * of levels. Clear the stacks for EXACT_LEAF_NAME and EXACT_LEAF_CLASS + * (anything that was there is of no use any more). */ if (tsdPtr->curLevel >= tsdPtr->numLevels) { @@ -1359,10 +1331,10 @@ SetupStacks(winPtr, leaf) for (i = 0; i < NUM_STACKS; i++) { levelPtr->bases[i] = tsdPtr->stacks[i]->numUsed; } + /* * Step 5: scan the current stack level looking for matches to this - * window's name or class; where found, add new information to the - * stacks. + * window's name or class; where found, add new information to the stacks. */ for (iPtr = searchOrder; *iPtr != -1; iPtr++) { @@ -1380,8 +1352,8 @@ SetupStacks(winPtr, leaf) count = levelPtr->bases[i]; /* - * For wildcard stacks, check all entries; for non-wildcard - * stacks, only check things that matched in the parent. + * For wildcard stacks, check all entries; for non-wildcard stacks, + * only check things that matched in the parent. */ if (!(i & WILDCARD)) { @@ -1403,9 +1375,8 @@ SetupStacks(winPtr, leaf) * * ExtendStacks -- * - * Given an element array, copy all the elements from the - * array onto the system stacks (except for irrelevant leaf - * elements). + * Given an element array, copy all the elements from the array onto the + * system stacks (except for irrelevant leaf elements). * * Results: * None. @@ -1424,7 +1395,7 @@ ExtendStacks(arrayPtr, leaf) { register int count; register Element *elPtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); for (elPtr = arrayPtr->els, count = arrayPtr->numUsed; @@ -1457,7 +1428,7 @@ static void OptionThreadExitProc(clientData) ClientData clientData; /* not used */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->initialized) { @@ -1488,20 +1459,20 @@ OptionThreadExitProc(clientData) static void OptionInit(mainPtr) - register TkMainInfo *mainPtr; /* Top-level information about - * window that isn't initialized - * yet. */ + register TkMainInfo *mainPtr; + /* Top-level information about window that + * isn't initialized yet. */ { int i; Tcl_Interp *interp; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Element *defaultMatchPtr = &tsdPtr->defaultMatch; /* * First, once-only initialization. */ - + if (tsdPtr->initialized == 0) { tsdPtr->initialized = 1; tsdPtr->cachedWindow = NULL; @@ -1509,13 +1480,13 @@ OptionInit(mainPtr) tsdPtr->curLevel = -1; tsdPtr->serial = 0; - tsdPtr->levels = (StackLevel *) ckalloc((unsigned) + tsdPtr->levels = (StackLevel *) ckalloc((unsigned) (5*sizeof(StackLevel))); for (i = 0; i < NUM_STACKS; i++) { tsdPtr->stacks[i] = NewArray(10); tsdPtr->levels[0].bases[i] = 0; } - + defaultMatchPtr->nameUid = NULL; defaultMatchPtr->child.valueUid = NULL; defaultMatchPtr->priority = -1; @@ -1524,7 +1495,7 @@ OptionInit(mainPtr) } /* - * Then, per-main-window initialization. Create and delete dummy + * Then, per-main-window initialization. Create and delete dummy * interpreter for message logging. */ @@ -1539,23 +1510,22 @@ OptionInit(mainPtr) * * ClearOptionTree -- * - * This procedure is called to erase everything in a - * hierarchical option database. + * This function is called to erase everything in a hierarchical option + * database. * * Results: * None. * * Side effects: - * All the options associated with arrayPtr are deleted, - * along with all option subtrees. The space pointed to - * by arrayPtr is freed. + * All the options associated with arrayPtr are deleted, along with all + * option subtrees. The space pointed to by arrayPtr is freed. * *-------------------------------------------------------------- */ static void ClearOptionTree(arrayPtr) - ElArray *arrayPtr; /* Array of options; delete everything + ElArray *arrayPtr; /* Array of options; delete everything * referred to recursively by this. */ { register Element *elPtr; @@ -1575,17 +1545,16 @@ ClearOptionTree(arrayPtr) * * GetDefaultOptions -- * - * This procedure is invoked to load the default set of options - * for a window. + * This function is invoked to load the default set of options for a + * window. * * Results: * None. * * Side effects: - * Options are added to those for winPtr's main window. If - * there exists a RESOURCE_MANAGER proprety for winPtr's - * display, that is used. Otherwise, the .Xdefaults file in - * the user's home directory is used. + * Options are added to those for winPtr's main window. If there exists a + * RESOURCE_MANAGER proprety for winPtr's display, that is used. + * Otherwise, the .Xdefaults file in the user's home directory is used. * *-------------------------------------------------------------- */ @@ -1621,8 +1590,7 @@ GetDefaultOptions(interp, winPtr) } /* - * No luck there. Try a .Xdefaults file in the user's home - * directory. + * No luck there. Try a .Xdefaults file in the user's home directory. */ if (regProp != NULL) { @@ -1632,3 +1600,11 @@ GetDefaultOptions(interp, winPtr) TK_USER_DEFAULT_PRIO); return result; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkPack.c b/generic/tkPack.c index 269e395..105bca0 100644 --- a/generic/tkPack.c +++ b/generic/tkPack.c @@ -1,16 +1,16 @@ -/* +/* * tkPack.c -- * - * This file contains code to implement the "packer" - * geometry manager for Tk. + * This file contains code to implement the "packer" geometry manager for + * Tk. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkPack.c,v 1.21 2005/01/11 10:35:27 dkf Exp $ + * RCS: @(#) $Id: tkPack.c,v 1.22 2005/08/10 22:02:22 dkf Exp $ */ #include "tkPort.h" @@ -28,70 +28,68 @@ static CONST char *sideNames[] = { */ typedef struct Packer { - Tk_Window tkwin; /* Tk token for window. NULL means that - * the window has been deleted, but the - * packet hasn't had a chance to clean up - * yet because the structure is still in - * use. */ - struct Packer *masterPtr; /* Master window within which this window - * is packed (NULL means this window - * isn't managed by the packer). */ - struct Packer *nextPtr; /* Next window packed within same - * master. List is priority-ordered: - * first on list gets packed first. */ - struct Packer *slavePtr; /* First in list of slaves packed - * inside this window (NULL means - * no packed slaves). */ - Side side; /* Side of master against which - * this window is packed. */ + Tk_Window tkwin; /* Tk token for window. NULL means that the + * window has been deleted, but the packet + * hasn't had a chance to clean up yet because + * the structure is still in use. */ + struct Packer *masterPtr; /* Master window within which this window is + * packed (NULL means this window isn't + * managed by the packer). */ + struct Packer *nextPtr; /* Next window packed within same master. + * List is priority-ordered: first on list + * gets packed first. */ + struct Packer *slavePtr; /* First in list of slaves packed inside this + * window (NULL means no packed slaves). */ + Side side; /* Side of master against which this window is + * packed. */ Tk_Anchor anchor; /* If frame allocated for window is larger - * than window needs, this indicates how - * where to position window in frame. */ + * than window needs, this indicates how where + * to position window in frame. */ int padX, padY; /* Total additional pixels to leave around the - * window. Some is of this space is on each - * side. This is space *outside* the window: + * window. Some is of this space is on each + * side. This is space *outside* the window: * we'll allocate extra space in frame but * won't enlarge window). */ - int padLeft, padTop; /* The part of padX or padY to use on the - * left or top of the widget, respectively. - * By default, this is half of padX or padY. */ + int padLeft, padTop; /* The part of padX or padY to use on the left + * or top of the widget, respectively. By + * default, this is half of padX or padY. */ int iPadX, iPadY; /* Total extra pixels to allocate inside the * window (half of this amount will appear on * each side). */ - int doubleBw; /* Twice the window's last known border - * width. If this changes, the window - * must be repacked within its master. */ - int *abortPtr; /* If non-NULL, it means that there is a nested - * call to ArrangePacking already working on - * this window. *abortPtr may be set to 1 to - * abort that nested call. This happens, for - * example, if tkwin or any of its slaves - * is deleted. */ - int flags; /* Miscellaneous flags; see below - * for definitions. */ + int doubleBw; /* Twice the window's last known border width. + * If this changes, the window must be + * repacked within its master. */ + int *abortPtr; /* If non-NULL, it means that there is a + * nested call to ArrangePacking already + * working on this window. *abortPtr may be + * set to 1 to abort that nested call. This + * happens, for example, if tkwin or any of + * its slaves is deleted. */ + int flags; /* Miscellaneous flags; see below for + * definitions. */ } Packer; /* * Flag values for Packer structures: * - * REQUESTED_REPACK: 1 means a Tcl_DoWhenIdle request - * has already been made to repack - * all the slaves of this window. - * FILLX: 1 means if frame allocated for window - * is wider than window needs, expand window - * to fill frame. 0 means don't make window - * any larger than needed. + * REQUESTED_REPACK: 1 means a Tcl_DoWhenIdle request has already + * been made to repack all the slaves of this + * window. + * FILLX: 1 means if frame allocated for window is wider + * than window needs, expand window to fill + * frame. 0 means don't make window any larger + * than needed. * FILLY: Same as FILLX, except for height. * EXPAND: 1 means this window's frame will absorb any * extra space in the master window. - * OLD_STYLE: 1 means this window is being managed with - * the old-style packer algorithms (before - * Tk version 3.3). The main difference is - * that padding and filling are done differently. + * OLD_STYLE: 1 means this window is being managed with the + * old-style packer algorithms (before Tk version + * 3.3). The main difference is that padding and + * filling are done differently. * DONT_PROPAGATE: 1 means don't set this window's requested - * size. 0 means if this window is a master - * then Tk will set its requested size to fit - * the needs of its slaves. + * size. 0 means if this window is a master then + * Tk will set its requested size to fit the + * needs of its slaves. */ #define REQUESTED_REPACK 1 @@ -102,14 +100,12 @@ typedef struct Packer { #define DONT_PROPAGATE 32 /* - * The following structure is the official type record for the - * packer: + * The following structure is the official type record for the packer: */ -static void PackReqProc _ANSI_ARGS_((ClientData clientData, - Tk_Window tkwin)); -static void PackLostSlaveProc _ANSI_ARGS_((ClientData clientData, - Tk_Window tkwin)); +static void PackReqProc(ClientData clientData, Tk_Window tkwin); +static void PackLostSlaveProc(ClientData clientData, + Tk_Window tkwin); static Tk_GeomMgr packerType = { "pack", /* name */ @@ -118,36 +114,31 @@ static Tk_GeomMgr packerType = { }; /* - * Forward declarations for procedures defined later in this file: + * Forward declarations for functions defined later in this file: */ -static void ArrangePacking _ANSI_ARGS_((ClientData clientData)); -static int ConfigureSlaves _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Window tkwin, int objc, Tcl_Obj *CONST objv[])); -static void DestroyPacker _ANSI_ARGS_((char *memPtr)); -static Packer * GetPacker _ANSI_ARGS_((Tk_Window tkwin)); -static int PackAfter _ANSI_ARGS_((Tcl_Interp *interp, - Packer *prevPtr, Packer *masterPtr, int objc, - Tcl_Obj *CONST objv[])); -static void PackReqProc _ANSI_ARGS_((ClientData clientData, - Tk_Window tkwin)); -static void PackStructureProc _ANSI_ARGS_((ClientData clientData, - XEvent *eventPtr)); -static void Unlink _ANSI_ARGS_((Packer *packPtr)); -static int XExpansion _ANSI_ARGS_((Packer *slavePtr, - int cavityWidth)); -static int YExpansion _ANSI_ARGS_((Packer *slavePtr, - int cavityHeight)); +static void ArrangePacking(ClientData clientData); +static int ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin, + int objc, Tcl_Obj *CONST objv[]); +static void DestroyPacker(char *memPtr); +static Packer * GetPacker(Tk_Window tkwin); +static int PackAfter(Tcl_Interp *interp, Packer *prevPtr, + Packer *masterPtr, int objc,Tcl_Obj *CONST objv[]); +static void PackReqProc(ClientData clientData, Tk_Window tkwin); +static void PackStructureProc(ClientData clientData, + XEvent *eventPtr); +static void Unlink(Packer *packPtr); +static int XExpansion(Packer *slavePtr, int cavityWidth); +static int YExpansion(Packer *slavePtr, int cavityHeight); /* *-------------------------------------------------------------- * * TkPrintPadAmount -- * - * This procedure generates a text value that describes one - * of the -padx, -pady, -ipadx, or -ipady configuration options. - * The text value generated is appended to the interpreter - * result. + * This function generates a text value that describes one of the -padx, + * -pady, -ipadx, or -ipady configuration options. The text value + * generated is appended to the interpreter result. * * Results: * None. @@ -157,10 +148,11 @@ static int YExpansion _ANSI_ARGS_((Packer *slavePtr, * *-------------------------------------------------------------- */ -void + +void TkPrintPadAmount(interp, switchName, halfSpace, allSpace) - Tcl_Interp *interp; /* The interpreter into which the result - * is written. */ + Tcl_Interp *interp; /* The interpreter into which the result is + * written. */ char *switchName; /* One of "padx", "pady", "ipadx" or "ipady" */ int halfSpace; /* The left or top padding amount */ int allSpace; /* The total amount of padding */ @@ -181,8 +173,8 @@ TkPrintPadAmount(interp, switchName, halfSpace, allSpace) * * Tk_PackCmd -- * - * This procedure is invoked to process the "pack" Tcl command. - * See the user documentation for details on what it does. + * This function is invoked to process the "pack" Tcl command. See the + * user documentation for details on what it does. * * Results: * A standard Tcl result. @@ -195,8 +187,7 @@ TkPrintPadAmount(interp, switchName, halfSpace, allSpace) int Tk_PackObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Main window associated with - * interpreter. */ + ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ @@ -226,9 +217,8 @@ Tk_PackObjCmd(clientData, interp, objc, objv) if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0, &index) != TCL_OK) { /* - * Call it again without the deprecated ones to get a proper - * error message. - * This works well since there can't be any ambiguity between + * Call it again without the deprecated ones to get a proper error + * message. This works well since there can't be any ambiguity between * deprecated and new options. */ @@ -239,7 +229,8 @@ Tk_PackObjCmd(clientData, interp, objc, objv) } argv2 = Tcl_GetString(objv[2]); - if (index == PACK_AFTER) { + switch ((enum options) index) { + case PACK_AFTER: { Packer *prevPtr; Tk_Window tkwin2; @@ -253,7 +244,8 @@ Tk_PackObjCmd(clientData, interp, objc, objv) return TCL_ERROR; } return PackAfter(interp, prevPtr, prevPtr->masterPtr, objc-3, objv+3); - } else if (index == PACK_APPEND) { + } + case PACK_APPEND: { Packer *masterPtr; register Packer *prevPtr; Tk_Window tkwin2; @@ -269,7 +261,8 @@ Tk_PackObjCmd(clientData, interp, objc, objv) } } return PackAfter(interp, prevPtr, masterPtr, objc-3, objv+3); - } else if (index == PACK_BEFORE) { + } + case PACK_BEFORE: { Packer *packPtr, *masterPtr; register Packer *prevPtr; Tk_Window tkwin2; @@ -298,14 +291,15 @@ Tk_PackObjCmd(clientData, interp, objc, objv) } } return PackAfter(interp, prevPtr, masterPtr, objc-3, objv+3); - } else if (index == PACK_CONFIGURE) { + } + case PACK_CONFIGURE: if (argv2[0] != '.') { Tcl_AppendResult(interp, "bad argument \"", argv2, "\": must be name of window", (char *) NULL); return TCL_ERROR; } return ConfigureSlaves(interp, tkwin, objc-2, objv+2); - } else if (index == PACK_FORGET) { + case PACK_FORGET: { Tk_Window slave; Packer *slavePtr; int i; @@ -326,7 +320,9 @@ Tk_PackObjCmd(clientData, interp, objc, objv) Tk_UnmapWindow(slavePtr->tkwin); } } - } else if (index == PACK_INFO) { + break; + } + case PACK_INFO: { register Packer *slavePtr; Tk_Window slave; @@ -351,26 +347,28 @@ Tk_PackObjCmd(clientData, interp, objc, objv) (slavePtr->flags & EXPAND) ? "1" : "0", " -fill ", (char *) NULL); switch (slavePtr->flags & (FILLX|FILLY)) { - case 0: - Tcl_AppendResult(interp, "none", (char *) NULL); - break; - case FILLX: - Tcl_AppendResult(interp, "x", (char *) NULL); - break; - case FILLY: - Tcl_AppendResult(interp, "y", (char *) NULL); - break; - case FILLX|FILLY: - Tcl_AppendResult(interp, "both", (char *) NULL); - break; + case 0: + Tcl_AppendResult(interp, "none", (char *) NULL); + break; + case FILLX: + Tcl_AppendResult(interp, "x", (char *) NULL); + break; + case FILLY: + Tcl_AppendResult(interp, "y", (char *) NULL); + break; + case FILLX|FILLY: + Tcl_AppendResult(interp, "both", (char *) NULL); + break; } - TkPrintPadAmount(interp, "ipadx", slavePtr->iPadX/2, slavePtr->iPadX); - TkPrintPadAmount(interp, "ipady", slavePtr->iPadY/2, slavePtr->iPadY); - TkPrintPadAmount(interp, "padx", slavePtr->padLeft, slavePtr->padX); - TkPrintPadAmount(interp, "pady", slavePtr->padTop, slavePtr->padY); + TkPrintPadAmount(interp, "ipadx", slavePtr->iPadX/2, slavePtr->iPadX); + TkPrintPadAmount(interp, "ipady", slavePtr->iPadY/2, slavePtr->iPadY); + TkPrintPadAmount(interp, "padx", slavePtr->padLeft, slavePtr->padX); + TkPrintPadAmount(interp, "pady", slavePtr->padTop, slavePtr->padY); Tcl_AppendResult(interp, " -side ", sideNames[slavePtr->side], (char *) NULL); - } else if (index == PACK_PROPAGATE) { + break; + } + case PACK_PROPAGATE: { Tk_Window master; Packer *masterPtr; int propagate; @@ -409,7 +407,9 @@ Tk_PackObjCmd(clientData, interp, objc, objv) } else { masterPtr->flags |= DONT_PROPAGATE; } - } else if (index == PACK_SLAVES) { + break; + } + case PACK_SLAVES: { Tk_Window master; Packer *masterPtr, *slavePtr; @@ -425,7 +425,9 @@ Tk_PackObjCmd(clientData, interp, objc, objv) slavePtr = slavePtr->nextPtr) { Tcl_AppendElement(interp, Tk_PathName(slavePtr->tkwin)); } - } else if (index == PACK_UNPACK) { + break; + } + case PACK_UNPACK: { Tk_Window tkwin2; Packer *packPtr; @@ -447,6 +449,7 @@ Tk_PackObjCmd(clientData, interp, objc, objv) Unlink(packPtr); Tk_UnmapWindow(packPtr->tkwin); } + break; } return TCL_OK; @@ -457,15 +460,15 @@ Tk_PackObjCmd(clientData, interp, objc, objv) * * PackReqProc -- * - * This procedure is invoked by Tk_GeometryRequest for - * windows managed by the packer. + * This function is invoked by Tk_GeometryRequest for windows managed by + * the packer. * * Results: * None. * * Side effects: - * Arranges for tkwin, and all its managed siblings, to - * be re-packed at the next idle point. + * Arranges for tkwin, and all its managed siblings, to be re-packed at + * the next idle point. * *-------------------------------------------------------------- */ @@ -473,11 +476,10 @@ Tk_PackObjCmd(clientData, interp, objc, objv) /* ARGSUSED */ static void PackReqProc(clientData, tkwin) - ClientData clientData; /* Packer's information about - * window that got new preferred - * geometry. */ - Tk_Window tkwin; /* Other Tk-related information - * about the window. */ + ClientData clientData; /* Packer's information about window that got + * new preferred geometry. */ + Tk_Window tkwin; /* Other Tk-related information about the + * window. */ { register Packer *packPtr = (Packer *) clientData; @@ -493,8 +495,8 @@ PackReqProc(clientData, tkwin) * * PackLostSlaveProc -- * - * This procedure is invoked by Tk whenever some other geometry - * claims control over a slave that used to be managed by us. + * This function is invoked by Tk whenever some other geometry claims + * control over a slave that used to be managed by us. * * Results: * None. @@ -508,8 +510,8 @@ PackReqProc(clientData, tkwin) /* ARGSUSED */ static void PackLostSlaveProc(clientData, tkwin) - ClientData clientData; /* Packer structure for slave window that - * was stolen away. */ + ClientData clientData; /* Packer structure for slave window that was + * stolen away. */ Tk_Window tkwin; /* Tk's handle for the slave window. */ { register Packer *slavePtr = (Packer *) clientData; @@ -526,18 +528,16 @@ PackLostSlaveProc(clientData, tkwin) * * ArrangePacking -- * - * This procedure is invoked (using the Tcl_DoWhenIdle - * mechanism) to re-layout a set of windows managed by - * the packer. It is invoked at idle time so that a - * series of packer requests can be merged into a single - * layout operation. + * This function is invoked (using the Tcl_DoWhenIdle mechanism) to + * re-layout a set of windows managed by the packer. It is invoked at + * idle time so that a series of packer requests can be merged into a + * single layout operation. * * Results: * None. * * Side effects: - * The packed slaves of masterPtr may get resized or - * moved. + * The packed slaves of masterPtr may get resized or moved. * *-------------------------------------------------------------- */ @@ -548,16 +548,16 @@ ArrangePacking(clientData) * are to be re-layed out. */ { register Packer *masterPtr = (Packer *) clientData; - register Packer *slavePtr; + register Packer *slavePtr; int cavityX, cavityY, cavityWidth, cavityHeight; /* These variables keep track of the - * as-yet-unallocated space remaining in - * the middle of the master window. */ + * as-yet-unallocated space remaining in the + * middle of the master window. */ int frameX, frameY, frameWidth, frameHeight; /* These variables keep track of the frame * allocated to the current window. */ - int x, y, width, height; /* These variables are used to hold the - * actual geometry of the current window. */ + int x, y, width, height; /* These variables are used to hold the actual + * geometry of the current window. */ int abort; /* May get set to non-zero to abort this * repacking operation. */ int borderX, borderY; @@ -568,8 +568,8 @@ ArrangePacking(clientData) masterPtr->flags &= ~REQUESTED_REPACK; /* - * If the master has no slaves anymore, then don't do anything - * at all: just leave the master's size as-is. + * If the master has no slaves anymore, then don't do anything at all: + * just leave the master's size as-is. */ if (masterPtr->slavePtr == NULL) { @@ -577,9 +577,9 @@ ArrangePacking(clientData) } /* - * Abort any nested call to ArrangePacking for this window, since - * we'll do everything necessary here, and set up so this call - * can be aborted if necessary. + * Abort any nested call to ArrangePacking for this window, since we'll do + * everything necessary here, and set up so this call can be aborted if + * necessary. */ if (masterPtr->abortPtr != NULL) { @@ -590,22 +590,19 @@ ArrangePacking(clientData) Tcl_Preserve((ClientData) masterPtr); /* - * Pass #1: scan all the slaves to figure out the total amount - * of space needed. Two separate width and height values are - * computed: + * Pass #1: scan all the slaves to figure out the total amount of space + * needed. Two separate width and height values are computed: * - * width - Holds the sum of the widths (plus padding) of - * all the slaves seen so far that were packed LEFT - * or RIGHT. - * height - Holds the sum of the heights (plus padding) of - * all the slaves seen so far that were packed TOP - * or BOTTOM. + * width - Holds the sum of the widths (plus padding) of all the + * slaves seen so far that were packed LEFT or RIGHT. + * height - Holds the sum of the heights (plus padding) of all the + * slaves seen so far that were packed TOP or BOTTOM. * - * maxWidth - Gradually builds up the width needed by the master - * to just barely satisfy all the slave's needs. For - * each slave, the code computes the width needed for - * all the slaves so far and updates maxWidth if the - * new value is greater. + * maxWidth - Gradually builds up the width needed by the master to + * just barely satisfy all the slave's needs. For each + * slave, the code computes the width needed for all the + * slaves so far and updates maxWidth if the new value is + * greater. * maxHeight - Same as maxWidth, except keeps height info. */ @@ -648,11 +645,10 @@ ArrangePacking(clientData) } /* - * If the total amount of space needed in the master window has - * changed, and if we're propagating geometry information, then - * notify the next geometry manager up and requeue ourselves to - * start again after the master has had a chance to - * resize us. + * If the total amount of space needed in the master window has changed, + * and if we're propagating geometry information, then notify the next + * geometry manager up and requeue ourselves to start again after the + * master has had a chance to resize us. */ if (((maxWidth != Tk_ReqWidth(masterPtr->tkwin)) @@ -665,14 +661,12 @@ ArrangePacking(clientData) } /* - * Pass #2: scan the slaves a second time assigning - * new sizes. The "cavity" variables keep track of the - * unclaimed space in the cavity of the window; this - * shrinks inward as we allocate windows around the - * edges. The "frame" variables keep track of the space - * allocated to the current window and its frame. The - * current window is then placed somewhere inside the - * frame, depending on anchor. + * Pass #2: scan the slaves a second time assigning new sizes. The + * "cavity" variables keep track of the unclaimed space in the cavity of + * the window; this shrinks inward as we allocate windows around the + * edges. The "frame" variables keep track of the space allocated to the + * current window and its frame. The current window is then placed + * somewhere inside the frame, depending on anchor. */ cavityX = x = Tk_InternalBorderLeft(masterPtr->tkwin); @@ -726,13 +720,12 @@ ArrangePacking(clientData) } /* - * Now that we've got the size of the frame for the window, - * compute the window's actual size and location using the - * fill, padding, and frame factors. The variables "borderX" - * and "borderY" are used to handle the differences between - * old-style packing and the new style (in old-style, iPadX - * and iPadY are always zero and padding is completely ignored - * except when computing frame size). + * Now that we've got the size of the frame for the window, compute + * the window's actual size and location using the fill, padding, and + * frame factors. The variables "borderX" and "borderY" are used to + * handle the differences between old-style packing and the new style + * (in old-style, iPadX and iPadY are always zero and padding is + * completely ignored except when computing frame size). */ if (slavePtr->flags & OLD_STYLE) { @@ -760,52 +753,52 @@ ArrangePacking(clientData) height = frameHeight - borderY; } switch (slavePtr->anchor) { - case TK_ANCHOR_N: - x = frameX + (borderLeft + frameWidth - width - borderRight)/2; - y = frameY + borderTop; - break; - case TK_ANCHOR_NE: - x = frameX + frameWidth - width - borderRight; - y = frameY + borderTop; - break; - case TK_ANCHOR_E: - x = frameX + frameWidth - width - borderRight; - y = frameY + (borderTop + frameHeight - height - borderBtm)/2; - break; - case TK_ANCHOR_SE: - x = frameX + frameWidth - width - borderRight; - y = frameY + frameHeight - height - borderBtm; - break; - case TK_ANCHOR_S: - x = frameX + (borderLeft + frameWidth - width - borderRight)/2; - y = frameY + frameHeight - height - borderBtm; - break; - case TK_ANCHOR_SW: - x = frameX + borderLeft; - y = frameY + frameHeight - height - borderBtm; - break; - case TK_ANCHOR_W: - x = frameX + borderLeft; - y = frameY + (borderTop + frameHeight - height - borderBtm)/2; - break; - case TK_ANCHOR_NW: - x = frameX + borderLeft; - y = frameY + borderTop; - break; - case TK_ANCHOR_CENTER: - x = frameX + (borderLeft + frameWidth - width - borderRight)/2; - y = frameY + (borderTop + frameHeight - height - borderBtm)/2; - break; - default: - Tcl_Panic("bad frame factor in ArrangePacking"); + case TK_ANCHOR_N: + x = frameX + (borderLeft + frameWidth - width - borderRight)/2; + y = frameY + borderTop; + break; + case TK_ANCHOR_NE: + x = frameX + frameWidth - width - borderRight; + y = frameY + borderTop; + break; + case TK_ANCHOR_E: + x = frameX + frameWidth - width - borderRight; + y = frameY + (borderTop + frameHeight - height - borderBtm)/2; + break; + case TK_ANCHOR_SE: + x = frameX + frameWidth - width - borderRight; + y = frameY + frameHeight - height - borderBtm; + break; + case TK_ANCHOR_S: + x = frameX + (borderLeft + frameWidth - width - borderRight)/2; + y = frameY + frameHeight - height - borderBtm; + break; + case TK_ANCHOR_SW: + x = frameX + borderLeft; + y = frameY + frameHeight - height - borderBtm; + break; + case TK_ANCHOR_W: + x = frameX + borderLeft; + y = frameY + (borderTop + frameHeight - height - borderBtm)/2; + break; + case TK_ANCHOR_NW: + x = frameX + borderLeft; + y = frameY + borderTop; + break; + case TK_ANCHOR_CENTER: + x = frameX + (borderLeft + frameWidth - width - borderRight)/2; + y = frameY + (borderTop + frameHeight - height - borderBtm)/2; + break; + default: + Tcl_Panic("bad frame factor in ArrangePacking"); } width -= slavePtr->doubleBw; height -= slavePtr->doubleBw; /* * The final step is to set the position, size, and mapped/unmapped - * state of the slave. If the slave is a child of the master, then - * do this here. Otherwise let Tk_MaintainGeometry do the work. + * state of the slave. If the slave is a child of the master, then do + * this here. Otherwise let Tk_MaintainGeometry do the work. */ if (masterPtr->tkwin == Tk_Parent(slavePtr->tkwin)) { @@ -823,8 +816,8 @@ ArrangePacking(clientData) } /* - * Don't map the slave if the master isn't mapped: wait - * until the master gets mapped later. + * Don't map the slave if the master isn't mapped: wait until + * the master gets mapped later. */ if (Tk_IsMapped(masterPtr->tkwin)) { @@ -842,9 +835,9 @@ ArrangePacking(clientData) } /* - * Changes to the window's structure could cause almost anything - * to happen, including deleting the parent or child. If this - * happens, we'll be told to abort. + * Changes to the window's structure could cause almost anything to + * happen, including deleting the parent or child. If this happens, + * we'll be told to abort. */ if (abort) { @@ -852,7 +845,7 @@ ArrangePacking(clientData) } } - done: + done: masterPtr->abortPtr = NULL; Tcl_Release((ClientData) masterPtr); } @@ -862,13 +855,12 @@ ArrangePacking(clientData) * * XExpansion -- * - * Given a list of packed slaves, the first of which is packed - * on the left or right and is expandable, compute how much to - * expand the child. + * Given a list of packed slaves, the first of which is packed on the + * left or right and is expandable, compute how much to expand the child. * * Results: - * The return value is the number of additional pixels to give to - * the child. + * The return value is the number of additional pixels to give to the + * child. * * Side effects: * None. @@ -878,23 +870,22 @@ ArrangePacking(clientData) static int XExpansion(slavePtr, cavityWidth) - register Packer *slavePtr; /* First in list of remaining - * slaves. */ - int cavityWidth; /* Horizontal space left for all - * remaining slaves. */ + register Packer *slavePtr; /* First in list of remaining slaves. */ + int cavityWidth; /* Horizontal space left for all remaining + * slaves. */ { int numExpand, minExpand, curExpand; int childWidth; /* - * This procedure is tricky because windows packed top or bottom can - * be interspersed among expandable windows packed left or right. - * Scan through the list, keeping a running sum of the widths of - * all left and right windows (actually, count the cavity space not - * allocated) and a running count of all expandable left and right - * windows. At each top or bottom window, and at the end of the - * list, compute the expansion factor that seems reasonable at that - * point. Return the smallest factor seen at any of these points. + * This function is tricky because windows packed top or bottom can be + * interspersed among expandable windows packed left or right. Scan + * through the list, keeping a running sum of the widths of all left and + * right windows (actually, count the cavity space not allocated) and a + * running count of all expandable left and right windows. At each top or + * bottom window, and at the end of the list, compute the expansion factor + * that seems reasonable at that point. Return the smallest factor seen at + * any of these points. */ minExpand = cavityWidth; @@ -926,13 +917,12 @@ XExpansion(slavePtr, cavityWidth) * * YExpansion -- * - * Given a list of packed slaves, the first of which is packed - * on the top or bottom and is expandable, compute how much to - * expand the child. + * Given a list of packed slaves, the first of which is packed on the top + * or bottom and is expandable, compute how much to expand the child. * * Results: - * The return value is the number of additional pixels to give to - * the child. + * The return value is the number of additional pixels to give to the + * child. * * Side effects: * None. @@ -942,10 +932,9 @@ XExpansion(slavePtr, cavityWidth) static int YExpansion(slavePtr, cavityHeight) - register Packer *slavePtr; /* First in list of remaining - * slaves. */ - int cavityHeight; /* Vertical space left for all - * remaining slaves. */ + register Packer *slavePtr; /* First in list of remaining slaves. */ + int cavityHeight; /* Vertical space left for all remaining + * slaves. */ { int numExpand, minExpand, curExpand; int childHeight; @@ -983,26 +972,24 @@ YExpansion(slavePtr, cavityHeight) * * GetPacker -- * - * This internal procedure is used to locate a Packer - * structure for a given window, creating one if one - * doesn't exist already. + * This internal function is used to locate a Packer structure for a + * given window, creating one if one doesn't exist already. * * Results: - * The return value is a pointer to the Packer structure - * corresponding to tkwin. + * The return value is a pointer to the Packer structure corresponding to + * tkwin. * * Side effects: - * A new packer structure may be created. If so, then - * a callback is set up to clean things up when the - * window is deleted. + * A new packer structure may be created. If so, then a callback is set + * up to clean things up when the window is deleted. * *-------------------------------------------------------------- */ static Packer * GetPacker(tkwin) - Tk_Window tkwin; /* Token for window for which - * packer structure is desired. */ + Tk_Window tkwin; /* Token for window for which packer structure + * is desired. */ { register Packer *packPtr; Tcl_HashEntry *hPtr; @@ -1015,12 +1002,12 @@ GetPacker(tkwin) } /* - * See if there's already packer for this window. If not, - * then create a new one. + * See if there's already packer for this window. If not, then create a + * new one. */ - hPtr = Tcl_CreateHashEntry(&dispPtr->packerHashTable, (char *) tkwin, - &new); + hPtr = Tcl_CreateHashEntry(&dispPtr->packerHashTable, (char *) tkwin, + &new); if (!new) { return (Packer *) Tcl_GetHashValue(hPtr); } @@ -1048,15 +1035,15 @@ GetPacker(tkwin) * * PackAfter -- * - * This procedure does most of the real work of adding - * one or more windows into the packing order for its master. + * This function does most of the real work of adding one or more windows + * into the packing order for its master. * * Results: * A standard Tcl return value. * * Side effects: - * The geometry of the specified windows may change, both now and - * again in the future. + * The geometry of the specified windows may change, both now and again + * in the future. * *-------------------------------------------------------------- */ @@ -1065,13 +1052,13 @@ static int PackAfter(interp, prevPtr, masterPtr, objc, objv) Tcl_Interp *interp; /* Interpreter for error reporting. */ Packer *prevPtr; /* Pack windows in argv just after this - * window; NULL means pack as first - * child of masterPtr. */ + * window; NULL means pack as first child of + * masterPtr. */ Packer *masterPtr; /* Master in which to pack windows. */ int objc; /* Number of elements in objv. */ - Tcl_Obj *CONST objv[]; /* Array of lists, each containing 2 - * elements: window name and side - * against which to pack. */ + Tcl_Obj *CONST objv[]; /* Array of lists, each containing 2 elements: + * window name and side against which to + * pack. */ { register Packer *packPtr; Tk_Window tkwin, ancestor, parent; @@ -1080,10 +1067,9 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv) int index, optionCount, c; /* - * Iterate over all of the window specifiers, each consisting of - * two arguments. The first argument contains the window name and - * the additional arguments contain options such as "top" or - * "padx 20". + * Iterate over all of the window specifiers, each consisting of two + * arguments. The first argument contains the window name and the + * additional arguments contain options such as "top" or "padx 20". */ for ( ; objc > 0; objc -= 2, objv += 2, prevPtr = packPtr) { @@ -1095,9 +1081,9 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv) } /* - * Find the packer for the window to be packed, and make sure - * that the window in which it will be packed is either its - * or a descendant of its parent. + * Find the packer for the window to be packed, and make sure that the + * window in which it will be packed is either its or a descendant of + * its parent. */ if (TkGetWindowFromObj(interp, masterPtr->tkwin, objv[0], &tkwin) @@ -1111,7 +1097,7 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv) break; } if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_HIERARCHY) { - badWindow: + badWindow: Tcl_AppendResult(interp, "can't pack ", Tcl_GetString(objv[0]), " inside ", Tk_PathName(masterPtr->tkwin), (char *) NULL); @@ -1143,7 +1129,7 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv) packPtr->flags |= OLD_STYLE; for (index = 0 ; index < optionCount; index++) { Tcl_Obj *curOptPtr = options[index]; - char *curOpt = Tcl_GetStringFromObj(curOptPtr, (int *) &length); + char *curOpt = Tcl_GetStringFromObj(curOptPtr, &length); c = curOpt[0]; @@ -1171,7 +1157,7 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv) packPtr->flags |= FILLY; } else if ((c == 'p') && (strcmp(curOpt, "padx")) == 0) { if (optionCount < (index+2)) { - missingPad: + missingPad: Tcl_AppendResult(interp, "wrong # args: \"", curOpt, "\" option must be followed by screen distance", (char *) NULL); @@ -1234,11 +1220,10 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv) } Unlink(packPtr); } - + /* - * Add the window in the correct place in its master's - * packing order, then make sure that the window is - * managed by us. + * Add the window in the correct place in its master's packing + * order, then make sure that the window is managed by us. */ packPtr->masterPtr = masterPtr; @@ -1254,8 +1239,7 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv) } /* - * Arrange for the master to be re-packed at the first - * idle moment. + * Arrange for the master to be re-packed at the first idle moment. */ if (masterPtr->abortPtr != NULL) { @@ -1286,7 +1270,7 @@ PackAfter(interp, prevPtr, masterPtr, objc, objv) static void Unlink(packPtr) - register Packer *packPtr; /* Window to unlink. */ + register Packer *packPtr; /* Window to unlink. */ { register Packer *masterPtr, *packPtr2; @@ -1323,9 +1307,9 @@ Unlink(packPtr) * * DestroyPacker -- * - * This procedure is invoked by Tcl_EventuallyFree or Tcl_Release - * to clean up the internal structure of a packer at a safe time - * (when no-one is using it anymore). + * This function is invoked by Tcl_EventuallyFree or Tcl_Release to clean + * up the internal structure of a packer at a safe time (when no-one is + * using it anymore). * * Results: * None. @@ -1350,25 +1334,24 @@ DestroyPacker(memPtr) * * PackStructureProc -- * - * This procedure is invoked by the Tk event dispatcher in response - * to StructureNotify events. + * This function is invoked by the Tk event dispatcher in response to + * StructureNotify events. * * Results: * None. * * Side effects: * If a window was just deleted, clean up all its packer-related - * information. If it was just resized, repack its slaves, if - * any. + * information. If it was just resized, repack its slaves, if any. * *---------------------------------------------------------------------- */ static void PackStructureProc(clientData, eventPtr) - ClientData clientData; /* Our information about window - * referred to by eventPtr. */ - XEvent *eventPtr; /* Describes what just happened. */ + ClientData clientData; /* Our information about window referred to by + * eventPtr. */ + XEvent *eventPtr; /* Describes what just happened. */ { register Packer *packPtr = (Packer *) clientData; @@ -1392,6 +1375,7 @@ PackStructureProc(clientData, eventPtr) if (packPtr->masterPtr != NULL) { Unlink(packPtr); } + for (slavePtr = packPtr->slavePtr; slavePtr != NULL; slavePtr = nextPtr) { Tk_ManageGeometry(slavePtr->tkwin, (Tk_GeomMgr *) NULL, @@ -1401,11 +1385,13 @@ PackStructureProc(clientData, eventPtr) nextPtr = slavePtr->nextPtr; slavePtr->nextPtr = NULL; } + if (packPtr->tkwin != NULL) { TkDisplay *dispPtr = ((TkWindow *) packPtr->tkwin)->dispPtr; Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->packerHashTable, (char *) packPtr->tkwin)); } + if (packPtr->flags & REQUESTED_REPACK) { Tcl_CancelIdleCall(ArrangePacking, (ClientData) packPtr); } @@ -1413,8 +1399,8 @@ PackStructureProc(clientData, eventPtr) Tcl_EventuallyFree((ClientData) packPtr, DestroyPacker); } else if (eventPtr->type == MapNotify) { /* - * When a master gets mapped, must redo the geometry computation - * so that all of its slaves get remapped. + * When a master gets mapped, must redo the geometry computation so + * that all of its slaves get remapped. */ if ((packPtr->slavePtr != NULL) @@ -1426,10 +1412,10 @@ PackStructureProc(clientData, eventPtr) register Packer *packPtr2; /* - * Unmap all of the slaves when the master gets unmapped, - * so that they don't bother to keep redisplaying - * themselves. + * Unmap all of the slaves when the master gets unmapped, so that they + * don't bother to keep redisplaying themselves. */ + for (packPtr2 = packPtr->slavePtr; packPtr2 != NULL; packPtr2 = packPtr2->nextPtr) { Tk_UnmapWindow(packPtr2->tkwin); @@ -1442,13 +1428,13 @@ PackStructureProc(clientData, eventPtr) * * ConfigureSlaves -- * - * This implements the guts of the "pack configure" command. Given - * a list of slaves and configuration options, it arranges for the - * packer to manage the slaves and sets the specified options. + * This implements the guts of the "pack configure" command. Given a list + * of slaves and configuration options, it arranges for the packer to + * manage the slaves and sets the specified options. * * Results: - * TCL_OK is returned if all went well. Otherwise, TCL_ERROR is - * returned and the interp's result is set to contain an error message. + * TCL_OK is returned if all went well. Otherwise, TCL_ERROR is returned + * and the interp's result is set to contain an error message. * * Side effects: * Slave windows get taken over by the packer. @@ -1460,13 +1446,12 @@ static int ConfigureSlaves(interp, tkwin, objc, objv) Tcl_Interp *interp; /* Interpreter for error reporting. */ Tk_Window tkwin; /* Any window in application containing - * slaves. Used to look up slave names. */ + * slaves. Used to look up slave names. */ int objc; /* Number of elements in argv. */ - Tcl_Obj *CONST objv[]; /* Argument objects: contains one or more - * window names followed by any number - * of "option value" pairs. Caller must - * make sure that there is at least one - * window name. */ + Tcl_Obj *CONST objv[]; /* Argument objects: contains one or more + * window names followed by any number of + * "option value" pairs. Caller must make sure + * that there is at least one window name. */ { Packer *masterPtr, *slavePtr, *prevPtr, *otherPtr; Tk_Window other, slave, parent, ancestor; @@ -1493,13 +1478,12 @@ ConfigureSlaves(interp, tkwin, objc, objv) /* * Iterate over all of the slave windows, parsing the configuration - * options for each slave. It's a bit wasteful to re-parse the - * options for each slave, but things get too messy if we try to - * parse the arguments just once at the beginning. For example, - * if a slave already is packed we want to just change a few - * existing values without resetting everything. If there are - * multiple windows, the -after, -before, and -in options only - * get processed for the first window. + * options for each slave. It's a bit wasteful to re-parse the options for + * each slave, but things get too messy if we try to parse the arguments + * just once at the beginning. For example, if a slave already is packed + * we want to just change a few existing values without resetting + * everything. If there are multiple windows, the -after, -before, and -in + * options only get processed for the first window. */ masterPtr = NULL; @@ -1518,9 +1502,9 @@ ConfigureSlaves(interp, tkwin, objc, objv) slavePtr->flags &= ~OLD_STYLE; /* - * If the slave isn't currently packed, reset all of its - * configuration information to default values (there could - * be old values left from a previous packing). + * If the slave isn't currently packed, reset all of its configuration + * information to default values (there could be old values left from + * a previous packing). */ if (slavePtr->masterPtr == NULL) { @@ -1543,7 +1527,9 @@ ConfigureSlaves(interp, tkwin, objc, objv) 0, &index) != TCL_OK) { return TCL_ERROR; } - if (index == CONF_AFTER) { + + switch ((enum options) index) { + case CONF_AFTER: if (j == 0) { if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) != TCL_OK) { @@ -1560,12 +1546,14 @@ ConfigureSlaves(interp, tkwin, objc, objv) masterPtr = prevPtr->masterPtr; positionGiven = 1; } - } else if (index == CONF_ANCHOR) { + break; + case CONF_ANCHOR: if (Tk_GetAnchorFromObj(interp, objv[i+1], &slavePtr->anchor) != TCL_OK) { return TCL_ERROR; } - } else if (index == CONF_BEFORE) { + break; + case CONF_BEFORE: if (j == 0) { if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) != TCL_OK) { @@ -1586,7 +1574,8 @@ ConfigureSlaves(interp, tkwin, objc, objv) } positionGiven = 1; } - } else if (index == CONF_EXPAND) { + break; + case CONF_EXPAND: if (Tcl_GetBooleanFromObj(interp, objv[i+1], &tmp) != TCL_OK) { return TCL_ERROR; } @@ -1594,7 +1583,8 @@ ConfigureSlaves(interp, tkwin, objc, objv) if (tmp) { slavePtr->flags |= EXPAND; } - } else if (index == CONF_FILL) { + break; + case CONF_FILL: string = Tcl_GetString(objv[i+1]); if (strcmp(string, "none") == 0) { slavePtr->flags &= ~(FILLX|FILLY); @@ -1609,7 +1599,8 @@ ConfigureSlaves(interp, tkwin, objc, objv) "\": must be none, x, y, or both", (char *) NULL); return TCL_ERROR; } - } else if (index == CONF_IN) { + break; + case CONF_IN: if (j == 0) { if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) != TCL_OK) { @@ -1624,7 +1615,8 @@ ConfigureSlaves(interp, tkwin, objc, objv) } positionGiven = 1; } - } else if (index == CONF_IPADX) { + break; + case CONF_IPADX: if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp) != TCL_OK) || (tmp < 0)) { @@ -1636,7 +1628,8 @@ ConfigureSlaves(interp, tkwin, objc, objv) return TCL_ERROR; } slavePtr->iPadX = tmp * 2; - } else if (index == CONF_IPADY) { + break; + case CONF_IPADY: if ((Tk_GetPixelsFromObj(interp, slave, objv[i+1], &tmp) != TCL_OK) || (tmp < 0)) { @@ -1648,29 +1641,33 @@ ConfigureSlaves(interp, tkwin, objc, objv) return TCL_ERROR; } slavePtr->iPadY = tmp * 2; - } else if (index == CONF_PADX) { + break; + case CONF_PADX: if (TkParsePadAmount(interp, slave, objv[i+1], &slavePtr->padLeft, &slavePtr->padX) != TCL_OK) { return TCL_ERROR; } - } else if (index == CONF_PADY) { + break; + case CONF_PADY: if (TkParsePadAmount(interp, slave, objv[i+1], &slavePtr->padTop, &slavePtr->padY) != TCL_OK) { return TCL_ERROR; } - } else if (index == CONF_SIDE) { + break; + case CONF_SIDE: if (Tcl_GetIndexFromObj(interp, objv[i+1], sideNames, "side", TCL_EXACT, &side) != TCL_OK) { return TCL_ERROR; } slavePtr->side = (Side) side; + break; } } /* - * If no position in a packing list was specified and the slave - * is already packed, then leave it in its current location in - * its current packing list. + * If no position in a packing list was specified and the slave is + * already packed, then leave it in its current location in its + * current packing list. */ if (!positionGiven && (slavePtr->masterPtr != NULL)) { @@ -1679,22 +1676,22 @@ ConfigureSlaves(interp, tkwin, objc, objv) } /* - * If the slave is going to be put back after itself or - * the same -in window is passed in again, then just - * skip the whole operation, since it won't work anyway. + * If the slave is going to be put back after itself or the same -in + * window is passed in again, then just skip the whole operation, + * since it won't work anyway. */ if (prevPtr == slavePtr) { masterPtr = slavePtr->masterPtr; goto scheduleLayout; } - + /* - * If none of the "-in", "-before", or "-after" options has - * been specified, arrange for the slave to go at the end of - * the order for its parent. + * If none of the "-in", "-before", or "-after" options has been + * specified, arrange for the slave to go at the end of the order for + * its parent. */ - + if (!positionGiven) { masterPtr = GetPacker(Tk_Parent(slave)); prevPtr = masterPtr->slavePtr; @@ -1706,11 +1703,11 @@ ConfigureSlaves(interp, tkwin, objc, objv) } /* - * Make sure that the slave's parent is either the master or - * an ancestor of the master, and that the master and slave - * aren't the same. + * Make sure that the slave's parent is either the master or an + * ancestor of the master, and that the master and slave aren't the + * same. */ - + parent = Tk_Parent(slave); for (ancestor = masterPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) { if (ancestor == parent) { @@ -1730,8 +1727,8 @@ ConfigureSlaves(interp, tkwin, objc, objv) } /* - * Unpack the slave if it's currently packed, then position it - * after prevPtr. + * Unpack the slave if it's currently packed, then position it after + * prevPtr. */ if (slavePtr->masterPtr != NULL) { @@ -1755,11 +1752,10 @@ ConfigureSlaves(interp, tkwin, objc, objv) prevPtr = slavePtr; /* - * Arrange for the master to be re-packed at the first - * idle moment. + * Arrange for the master to be re-packed at the first idle moment. */ - scheduleLayout: + scheduleLayout: if (masterPtr->abortPtr != NULL) { *masterPtr->abortPtr = 1; } @@ -1770,3 +1766,11 @@ ConfigureSlaves(interp, tkwin, objc, objv) } return TCL_OK; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkRectOval.c b/generic/tkRectOval.c index 8d13a60..7e612f9 100644 --- a/generic/tkRectOval.c +++ b/generic/tkRectOval.c @@ -1,16 +1,15 @@ -/* +/* * tkRectOval.c -- * - * This file implements rectangle and oval items for canvas - * widgets. + * This file implements rectangle and oval items for canvas widgets. * * Copyright (c) 1991-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkRectOval.c,v 1.12 2004/11/11 01:24:32 das Exp $ + * RCS: @(#) $Id: tkRectOval.c,v 1.13 2005/08/10 22:02:22 dkf Exp $ */ #include <stdio.h> @@ -25,18 +24,22 @@ typedef struct RectOvalItem { Tk_Item header; /* Generic stuff that's the same for all - * types. MUST BE FIRST IN STRUCTURE. */ + * types. MUST BE FIRST IN STRUCTURE. */ Tk_Outline outline; /* Outline structure */ double bbox[4]; /* Coordinates of bounding box for rectangle - * or oval (x1, y1, x2, y2). Item includes - * x1 and x2 but not y1 and y2. */ + * or oval (x1, y1, x2, y2). Item includes x1 + * and x2 but not y1 and y2. */ Tk_TSOffset tsoffset; XColor *fillColor; /* Color for filling rectangle/oval. */ - XColor *activeFillColor; /* Color for filling rectangle/oval if state is active. */ - XColor *disabledFillColor; /* Color for filling rectangle/oval if state is disabled. */ + XColor *activeFillColor; /* Color for filling rectangle/oval if state + * is active. */ + XColor *disabledFillColor; /* Color for filling rectangle/oval if state + * is disabled. */ Pixmap fillStipple; /* Stipple bitmap for filling item. */ - Pixmap activeFillStipple; /* Stipple bitmap for filling item if state is active. */ - Pixmap disabledFillStipple; /* Stipple bitmap for filling item if state is disabled. */ + Pixmap activeFillStipple; /* Stipple bitmap for filling item if state is + * active. */ + Pixmap disabledFillStipple; /* Stipple bitmap for filling item if state is + * disabled. */ GC fillGC; /* Graphics context for filling item. */ } RectOvalItem; @@ -125,7 +128,7 @@ static Tk_ConfigSpec configSpecs[] = { (char *) NULL, Tk_Offset(Tk_Item, state),TK_CONFIG_NULL_OK, &stateOption}, {TK_CONFIG_BITMAP, "-stipple", (char *) NULL, (char *) NULL, - (char *) NULL, Tk_Offset(RectOvalItem, fillStipple), TK_CONFIG_NULL_OK}, + (char *) NULL, Tk_Offset(RectOvalItem, fillStipple),TK_CONFIG_NULL_OK}, {TK_CONFIG_CUSTOM, "-tags", (char *) NULL, (char *) NULL, (char *) NULL, 0, TK_CONFIG_NULL_OK, &tagsOption}, {TK_CONFIG_CUSTOM, "-width", (char *) NULL, (char *) NULL, @@ -136,90 +139,88 @@ static Tk_ConfigSpec configSpecs[] = { }; /* - * Prototypes for procedures defined in this file: + * Prototypes for functions defined in this file: */ -static void ComputeRectOvalBbox _ANSI_ARGS_((Tk_Canvas canvas, - RectOvalItem *rectOvalPtr)); -static int ConfigureRectOval _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Canvas canvas, Tk_Item *itemPtr, int objc, - Tcl_Obj *CONST objv[], int flags)); -static int CreateRectOval _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Canvas canvas, struct Tk_Item *itemPtr, - int objc, Tcl_Obj *CONST objv[])); -static void DeleteRectOval _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, Display *display)); -static void DisplayRectOval _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, Display *display, Drawable dst, - int x, int y, int width, int height)); -static int OvalToArea _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, double *areaPtr)); -static double OvalToPoint _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, double *pointPtr)); -static int RectOvalCoords _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Canvas canvas, Tk_Item *itemPtr, int objc, - Tcl_Obj *CONST objv[])); -static int RectOvalToPostscript _ANSI_ARGS_((Tcl_Interp *interp, - Tk_Canvas canvas, Tk_Item *itemPtr, int prepass)); -static int RectToArea _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, double *areaPtr)); -static double RectToPoint _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, double *pointPtr)); -static void ScaleRectOval _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, double originX, double originY, - double scaleX, double scaleY)); -static void TranslateRectOval _ANSI_ARGS_((Tk_Canvas canvas, - Tk_Item *itemPtr, double deltaX, double deltaY)); +static void ComputeRectOvalBbox(Tk_Canvas canvas, + RectOvalItem *rectOvalPtr); +static int ConfigureRectOval(Tcl_Interp *interp, Tk_Canvas canvas, + Tk_Item *itemPtr, int objc, Tcl_Obj *CONST objv[], + int flags); +static int CreateRectOval(Tcl_Interp *interp, Tk_Canvas canvas, + Tk_Item *itemPtr, int objc, Tcl_Obj *CONST objv[]); +static void DeleteRectOval(Tk_Canvas canvas, Tk_Item *itemPtr, + Display *display); +static void DisplayRectOval(Tk_Canvas canvas, Tk_Item *itemPtr, + Display *display, Drawable dst, int x, int y, + int width, int height); +static int OvalToArea(Tk_Canvas canvas, Tk_Item *itemPtr, + double *areaPtr); +static double OvalToPoint(Tk_Canvas canvas, Tk_Item *itemPtr, + double *pointPtr); +static int RectOvalCoords(Tcl_Interp *interp, Tk_Canvas canvas, + Tk_Item *itemPtr, int objc, Tcl_Obj *CONST objv[]); +static int RectOvalToPostscript(Tcl_Interp *interp, + Tk_Canvas canvas, Tk_Item *itemPtr, int prepass); +static int RectToArea(Tk_Canvas canvas, Tk_Item *itemPtr, + double *areaPtr); +static double RectToPoint(Tk_Canvas canvas, Tk_Item *itemPtr, + double *pointPtr); +static void ScaleRectOval(Tk_Canvas canvas, Tk_Item *itemPtr, + double originX, double originY, + double scaleX, double scaleY); +static void TranslateRectOval(Tk_Canvas canvas, Tk_Item *itemPtr, + double deltaX, double deltaY); /* - * The structures below defines the rectangle and oval item types - * by means of procedures that can be invoked by generic item code. + * The structures below defines the rectangle and oval item types by means of + * functions that can be invoked by generic item code. */ Tk_ItemType tkRectangleType = { - "rectangle", /* name */ - sizeof(RectOvalItem), /* itemSize */ - CreateRectOval, /* createProc */ - configSpecs, /* configSpecs */ - ConfigureRectOval, /* configureProc */ - RectOvalCoords, /* coordProc */ - DeleteRectOval, /* deleteProc */ - DisplayRectOval, /* displayProc */ - TK_CONFIG_OBJS, /* flags */ - RectToPoint, /* pointProc */ - RectToArea, /* areaProc */ - RectOvalToPostscript, /* postscriptProc */ - ScaleRectOval, /* scaleProc */ - TranslateRectOval, /* translateProc */ - (Tk_ItemIndexProc *) NULL, /* indexProc */ - (Tk_ItemCursorProc *) NULL, /* icursorProc */ - (Tk_ItemSelectionProc *) NULL, /* selectionProc */ - (Tk_ItemInsertProc *) NULL, /* insertProc */ - (Tk_ItemDCharsProc *) NULL, /* dTextProc */ - (Tk_ItemType *) NULL, /* nextPtr */ + "rectangle", /* name */ + sizeof(RectOvalItem), /* itemSize */ + CreateRectOval, /* createProc */ + configSpecs, /* configSpecs */ + ConfigureRectOval, /* configureProc */ + RectOvalCoords, /* coordProc */ + DeleteRectOval, /* deleteProc */ + DisplayRectOval, /* displayProc */ + TK_CONFIG_OBJS, /* flags */ + RectToPoint, /* pointProc */ + RectToArea, /* areaProc */ + RectOvalToPostscript, /* postscriptProc */ + ScaleRectOval, /* scaleProc */ + TranslateRectOval, /* translateProc */ + (Tk_ItemIndexProc *) NULL, /* indexProc */ + (Tk_ItemCursorProc *) NULL, /* icursorProc */ + (Tk_ItemSelectionProc *) NULL, /* selectionProc */ + (Tk_ItemInsertProc *) NULL, /* insertProc */ + (Tk_ItemDCharsProc *) NULL, /* dTextProc */ + (Tk_ItemType *) NULL, /* nextPtr */ }; Tk_ItemType tkOvalType = { - "oval", /* name */ - sizeof(RectOvalItem), /* itemSize */ - CreateRectOval, /* createProc */ - configSpecs, /* configSpecs */ - ConfigureRectOval, /* configureProc */ - RectOvalCoords, /* coordProc */ - DeleteRectOval, /* deleteProc */ - DisplayRectOval, /* displayProc */ - TK_CONFIG_OBJS, /* flags */ - OvalToPoint, /* pointProc */ - OvalToArea, /* areaProc */ - RectOvalToPostscript, /* postscriptProc */ - ScaleRectOval, /* scaleProc */ - TranslateRectOval, /* translateProc */ - (Tk_ItemIndexProc *) NULL, /* indexProc */ - (Tk_ItemCursorProc *) NULL, /* cursorProc */ - (Tk_ItemSelectionProc *) NULL, /* selectionProc */ - (Tk_ItemInsertProc *) NULL, /* insertProc */ - (Tk_ItemDCharsProc *) NULL, /* dTextProc */ - (Tk_ItemType *) NULL, /* nextPtr */ + "oval", /* name */ + sizeof(RectOvalItem), /* itemSize */ + CreateRectOval, /* createProc */ + configSpecs, /* configSpecs */ + ConfigureRectOval, /* configureProc */ + RectOvalCoords, /* coordProc */ + DeleteRectOval, /* deleteProc */ + DisplayRectOval, /* displayProc */ + TK_CONFIG_OBJS, /* flags */ + OvalToPoint, /* pointProc */ + OvalToArea, /* areaProc */ + RectOvalToPostscript, /* postscriptProc */ + ScaleRectOval, /* scaleProc */ + TranslateRectOval, /* translateProc */ + (Tk_ItemIndexProc *) NULL, /* indexProc */ + (Tk_ItemCursorProc *) NULL, /* cursorProc */ + (Tk_ItemSelectionProc *) NULL, /* selectionProc */ + (Tk_ItemInsertProc *) NULL, /* insertProc */ + (Tk_ItemDCharsProc *) NULL, /* dTextProc */ + (Tk_ItemType *) NULL, /* nextPtr */ }; /* @@ -227,14 +228,14 @@ Tk_ItemType tkOvalType = { * * CreateRectOval -- * - * This procedure is invoked to create a new rectangle - * or oval item in a canvas. + * This function is invoked to create a new rectangle or oval item in a + * canvas. * * Results: - * A standard Tcl return value. If an error occurred in - * creating the item, then an error message is left in - * the interp's result; in this case itemPtr is left uninitialized, - * so it can be safely freed by the caller. + * A standard Tcl return value. If an error occurred in creating the + * item, then an error message is left in the interp's result; in this + * case itemPtr is left uninitialized, so it can be safely freed by the + * caller. * * Side effects: * A new rectangle or oval item is created. @@ -244,12 +245,12 @@ Tk_ItemType tkOvalType = { static int CreateRectOval(interp, canvas, itemPtr, objc, objv) - Tcl_Interp *interp; /* For error reporting. */ - Tk_Canvas canvas; /* Canvas to hold new item. */ - Tk_Item *itemPtr; /* Record to hold new item; header - * has been initialized by caller. */ - int objc; /* Number of arguments in objv. */ - Tcl_Obj *CONST objv[]; /* Arguments describing rectangle. */ + Tcl_Interp *interp; /* For error reporting. */ + Tk_Canvas canvas; /* Canvas to hold new item. */ + Tk_Item *itemPtr; /* Record to hold new item; header has been + * initialized by caller. */ + int objc; /* Number of arguments in objv. */ + Tcl_Obj *CONST objv[]; /* Arguments describing rectangle. */ { RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; int i; @@ -259,8 +260,8 @@ CreateRectOval(interp, canvas, itemPtr, objc, objv) } /* - * Carry out initialization that is needed in order to clean - * up after errors during the the remainder of this procedure. + * Carry out initialization that is needed in order to clean up after + * errors during the the remainder of this function. */ Tk_CreateOutline(&(rectOvalPtr->outline)); @@ -293,7 +294,7 @@ CreateRectOval(interp, canvas, itemPtr, objc, objv) return TCL_OK; } - error: + error: DeleteRectOval(canvas, itemPtr, Tk_Display(Tk_CanvasTkwin(canvas))); return TCL_ERROR; } @@ -303,9 +304,9 @@ CreateRectOval(interp, canvas, itemPtr, objc, objv) * * RectOvalCoords -- * - * This procedure is invoked to process the "coords" widget - * command on rectangles and ovals. See the user documentation - * for details on what it does. + * This function is invoked to process the "coords" widget command on + * rectangles and ovals. See the user documentation for details on what + * it does. * * Results: * Returns TCL_OK or TCL_ERROR, and sets the interp's result. @@ -318,59 +319,72 @@ CreateRectOval(interp, canvas, itemPtr, objc, objv) static int RectOvalCoords(interp, canvas, itemPtr, objc, objv) - Tcl_Interp *interp; /* Used for error reporting. */ - Tk_Canvas canvas; /* Canvas containing item. */ - Tk_Item *itemPtr; /* Item whose coordinates are to be - * read or modified. */ - int objc; /* Number of coordinates supplied in - * objv. */ - Tcl_Obj *CONST objv[]; /* Array of coordinates: x1, y1, - * x2, y2, ... */ + Tcl_Interp *interp; /* Used for error reporting. */ + Tk_Canvas canvas; /* Canvas containing item. */ + Tk_Item *itemPtr; /* Item whose coordinates are to be read or + * modified. */ + int objc; /* Number of coordinates supplied in objv. */ + Tcl_Obj *CONST objv[]; /* Array of coordinates: x1,y1,x2,y2,... */ { RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; + /* + * If no coordinates, return the current coordinates (i.e. bounding box). + */ + if (objc == 0) { Tcl_Obj *obj = Tcl_NewObj(); - Tcl_Obj *subobj = Tcl_NewDoubleObj(rectOvalPtr->bbox[0]); - Tcl_ListObjAppendElement(interp, obj, subobj); - subobj = Tcl_NewDoubleObj(rectOvalPtr->bbox[1]); - Tcl_ListObjAppendElement(interp, obj, subobj); - subobj = Tcl_NewDoubleObj(rectOvalPtr->bbox[2]); - Tcl_ListObjAppendElement(interp, obj, subobj); - subobj = Tcl_NewDoubleObj(rectOvalPtr->bbox[3]); - Tcl_ListObjAppendElement(interp, obj, subobj); + + Tcl_ListObjAppendElement(NULL, obj, + Tcl_NewDoubleObj(rectOvalPtr->bbox[0])); + Tcl_ListObjAppendElement(NULL, obj, + Tcl_NewDoubleObj(rectOvalPtr->bbox[1])); + Tcl_ListObjAppendElement(NULL, obj, + Tcl_NewDoubleObj(rectOvalPtr->bbox[2])); + Tcl_ListObjAppendElement(NULL, obj, + Tcl_NewDoubleObj(rectOvalPtr->bbox[3])); Tcl_SetObjResult(interp, obj); - } else if ((objc == 1)||(objc == 4)) { - if (objc==1) { - if (Tcl_ListObjGetElements(interp, objv[0], &objc, - (Tcl_Obj ***) &objv) != TCL_OK) { - return TCL_ERROR; - } else if (objc != 4) { - char buf[64 + TCL_INTEGER_SPACE]; + return TCL_OK; + } - sprintf(buf, "wrong # coordinates: expected 0 or 4, got %d", objc); - Tcl_SetResult(interp, buf, TCL_VOLATILE); - return TCL_ERROR; - } - } - if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0], - &rectOvalPtr->bbox[0]) != TCL_OK) - || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1], - &rectOvalPtr->bbox[1]) != TCL_OK) - || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[2], - &rectOvalPtr->bbox[2]) != TCL_OK) - || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[3], - &rectOvalPtr->bbox[3]) != TCL_OK)) { + /* + * If one "coordinate", treat as list of coordinates. + */ + + if (objc == 1) { + if (Tcl_ListObjGetElements(interp, objv[0], &objc, + (Tcl_Obj ***) &objv) != TCL_OK) { return TCL_ERROR; } - ComputeRectOvalBbox(canvas, rectOvalPtr); - } else { + } + + /* + * Better have four coordinates now. Spit out an error message otherwise. + */ + + if (objc != 4) { char buf[64 + TCL_INTEGER_SPACE]; - + sprintf(buf, "wrong # coordinates: expected 0 or 4, got %d", objc); Tcl_SetResult(interp, buf, TCL_VOLATILE); return TCL_ERROR; } + + /* + * Parse the coordinates and update our bounding box. + */ + + if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0], + &rectOvalPtr->bbox[0]) != TCL_OK) + || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1], + &rectOvalPtr->bbox[1]) != TCL_OK) + || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[2], + &rectOvalPtr->bbox[2]) != TCL_OK) + || (Tk_CanvasGetCoordFromObj(interp, canvas, objv[3], + &rectOvalPtr->bbox[3]) != TCL_OK)) { + return TCL_ERROR; + } + ComputeRectOvalBbox(canvas, rectOvalPtr); return TCL_OK; } @@ -379,17 +393,16 @@ RectOvalCoords(interp, canvas, itemPtr, objc, objv) * * ConfigureRectOval -- * - * This procedure is invoked to configure various aspects - * of a rectangle or oval item, such as its border and - * background colors. + * This function is invoked to configure various aspects of a rectangle + * or oval item, such as its border and background colors. * * Results: - * A standard Tcl result code. If an error occurs, then - * an error message is left in the interp's result. + * A standard Tcl result code. If an error occurs, then an error message + * is left in the interp's result. * * Side effects: - * Configuration information, such as colors and stipple - * patterns, may be set for itemPtr. + * Configuration information, such as colors and stipple patterns, may be + * set for itemPtr. * *-------------------------------------------------------------- */ @@ -399,7 +412,7 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags) Tcl_Interp *interp; /* Used for error reporting. */ Tk_Canvas canvas; /* Canvas containing itemPtr. */ Tk_Item *itemPtr; /* Rectangle item to reconfigure. */ - int objc; /* Number of elements in objv. */ + int objc; /* Number of elements in objv. */ Tcl_Obj *CONST objv[]; /* Arguments describing things to configure. */ int flags; /* Flags to pass to Tk_ConfigureWidget. */ { @@ -416,14 +429,14 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags) tkwin = Tk_CanvasTkwin(canvas); if (TCL_OK != Tk_ConfigureWidget(interp, tkwin, configSpecs, objc, - (CONST char **) objv, (char *) rectOvalPtr, flags|TK_CONFIG_OBJS)) { + (CONST char **)objv, (char *) rectOvalPtr, flags|TK_CONFIG_OBJS)) { return TCL_ERROR; } state = itemPtr->state; /* - * A few of the options require additional processing, such as - * graphics contexts. + * A few of the options require additional processing, such as graphics + * contexts. */ if (rectOvalPtr->outline.activeWidth > rectOvalPtr->outline.width || @@ -442,27 +455,28 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags) if (flags & TK_OFFSET_LEFT) { tsoffset->xoffset = (int) (rectOvalPtr->bbox[0] + 0.5); } else if (flags & TK_OFFSET_CENTER) { - tsoffset->xoffset = (int) ((rectOvalPtr->bbox[0]+rectOvalPtr->bbox[2]+1)/2); + tsoffset->xoffset = (int) + ((rectOvalPtr->bbox[0]+rectOvalPtr->bbox[2]+1)/2); } else if (flags & TK_OFFSET_RIGHT) { tsoffset->xoffset = (int) (rectOvalPtr->bbox[2] + 0.5); } if (flags & TK_OFFSET_TOP) { tsoffset->yoffset = (int) (rectOvalPtr->bbox[1] + 0.5); } else if (flags & TK_OFFSET_MIDDLE) { - tsoffset->yoffset = (int) ((rectOvalPtr->bbox[1]+rectOvalPtr->bbox[3]+1)/2); + tsoffset->yoffset = (int) + ((rectOvalPtr->bbox[1]+rectOvalPtr->bbox[3]+1)/2); } else if (flags & TK_OFFSET_BOTTOM) { tsoffset->yoffset = (int) (rectOvalPtr->bbox[2] + 0.5); } /* - * Configure the outline graphics context. If mask is non-zero, - * the gc has changed and must be reallocated, provided that the - * new settings specify a valid outline (non-zero width and non-NULL - * color) + * Configure the outline graphics context. If mask is non-zero, the gc has + * changed and must be reallocated, provided that the new settings specify + * a valid outline (non-zero width and non-NULL color) */ mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, - &(rectOvalPtr->outline)); + &(rectOvalPtr->outline)); if (mask && \ rectOvalPtr->outline.width != 0 && \ rectOvalPtr->outline.color != NULL) { @@ -477,10 +491,10 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags) } rectOvalPtr->outline.gc = newGC; - if(state == TK_STATE_NULL) { + if (state == TK_STATE_NULL) { state = ((TkCanvas *)canvas)->canvas_state; } - if (state==TK_STATE_HIDDEN) { + if (state == TK_STATE_HIDDEN) { ComputeRectOvalBbox(canvas, rectOvalPtr); return TCL_OK; } @@ -494,7 +508,7 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags) if (rectOvalPtr->activeFillStipple!=None) { stipple = rectOvalPtr->activeFillStipple; } - } else if (state==TK_STATE_DISABLED) { + } else if (state == TK_STATE_DISABLED) { if (rectOvalPtr->disabledFillColor!=NULL) { color = rectOvalPtr->disabledFillColor; } @@ -526,14 +540,16 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags) if (flags & TK_OFFSET_LEFT) { tsoffset->xoffset = (int) (rectOvalPtr->bbox[0] + 0.5); } else if (flags & TK_OFFSET_CENTER) { - tsoffset->xoffset = (int) ((rectOvalPtr->bbox[0]+rectOvalPtr->bbox[2]+1)/2); + tsoffset->xoffset = (int) + ((rectOvalPtr->bbox[0]+rectOvalPtr->bbox[2]+1)/2); } else if (flags & TK_OFFSET_RIGHT) { tsoffset->xoffset = (int) (rectOvalPtr->bbox[2] + 0.5); } if (flags & TK_OFFSET_TOP) { tsoffset->yoffset = (int) (rectOvalPtr->bbox[1] + 0.5); } else if (flags & TK_OFFSET_MIDDLE) { - tsoffset->yoffset = (int) ((rectOvalPtr->bbox[1]+rectOvalPtr->bbox[3]+1)/2); + tsoffset->yoffset = (int) + ((rectOvalPtr->bbox[1]+rectOvalPtr->bbox[3]+1)/2); } else if (flags & TK_OFFSET_BOTTOM) { tsoffset->yoffset = (int) (rectOvalPtr->bbox[3] + 0.5); } @@ -548,8 +564,8 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags) * * DeleteRectOval -- * - * This procedure is called to clean up the data structure - * associated with a rectangle or oval item. + * This function is called to clean up the data structure associated with + * a rectangle or oval item. * * Results: * None. @@ -562,10 +578,9 @@ ConfigureRectOval(interp, canvas, itemPtr, objc, objv, flags) static void DeleteRectOval(canvas, itemPtr, display) - Tk_Canvas canvas; /* Info about overall widget. */ - Tk_Item *itemPtr; /* Item that is being deleted. */ - Display *display; /* Display containing window for - * canvas. */ + Tk_Canvas canvas; /* Info about overall widget. */ + Tk_Item *itemPtr; /* Item that is being deleted. */ + Display *display; /* Display containing window for canvas. */ { RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; @@ -598,16 +613,14 @@ DeleteRectOval(canvas, itemPtr, display) * * ComputeRectOvalBbox -- * - * This procedure is invoked to compute the bounding box of - * all the pixels that may be drawn as part of a rectangle - * or oval. + * This function is invoked to compute the bounding box of all the pixels + * that may be drawn as part of a rectangle or oval. * * Results: * None. * * Side effects: - * The fields x1, y1, x2, and y2 are updated in the header - * for itemPtr. + * The fields x1, y1, x2, and y2 are updated in the header for itemPtr. * *-------------------------------------------------------------- */ @@ -615,20 +628,19 @@ DeleteRectOval(canvas, itemPtr, display) /* ARGSUSED */ static void ComputeRectOvalBbox(canvas, rectOvalPtr) - Tk_Canvas canvas; /* Canvas that contains item. */ - RectOvalItem *rectOvalPtr; /* Item whose bbox is to be - * recomputed. */ + Tk_Canvas canvas; /* Canvas that contains item. */ + RectOvalItem *rectOvalPtr; /* Item whose bbox is to be recomputed. */ { int bloat, tmp; double dtmp, width; Tk_State state = rectOvalPtr->header.state; - if(state == TK_STATE_NULL) { + if (state == TK_STATE_NULL) { state = ((TkCanvas *)canvas)->canvas_state; } width = rectOvalPtr->outline.width; - if (state==TK_STATE_HIDDEN) { + if (state == TK_STATE_HIDDEN) { rectOvalPtr->header.x1 = rectOvalPtr->header.y1 = rectOvalPtr->header.x2 = rectOvalPtr->header.y2 = -1; return; @@ -637,7 +649,7 @@ ComputeRectOvalBbox(canvas, rectOvalPtr) if (rectOvalPtr->outline.activeWidth>width) { width = rectOvalPtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { + } else if (state == TK_STATE_DISABLED) { if (rectOvalPtr->outline.disabledWidth>0) { width = rectOvalPtr->outline.disabledWidth; } @@ -648,24 +660,25 @@ ComputeRectOvalBbox(canvas, rectOvalPtr) */ if (rectOvalPtr->bbox[1] > rectOvalPtr->bbox[3]) { - double tmp; - tmp = rectOvalPtr->bbox[3]; + double tmpY = rectOvalPtr->bbox[3]; + rectOvalPtr->bbox[3] = rectOvalPtr->bbox[1]; - rectOvalPtr->bbox[1] = tmp; + rectOvalPtr->bbox[1] = tmpY; } if (rectOvalPtr->bbox[0] > rectOvalPtr->bbox[2]) { - double tmp; - tmp = rectOvalPtr->bbox[2]; + double tmpX = rectOvalPtr->bbox[2]; + rectOvalPtr->bbox[2] = rectOvalPtr->bbox[0]; - rectOvalPtr->bbox[0] = tmp; + rectOvalPtr->bbox[0] = tmpX; } if (rectOvalPtr->outline.gc == None) { /* - * The Win32 switch was added for 8.3 to solve a problem - * with ovals leaving traces on bottom and right of 1 pixel. - * This may not be the correct place to solve it, but it works. + * The Win32 switch was added for 8.3 to solve a problem with ovals + * leaving traces on bottom and right of 1 pixel. This may not be the + * correct place to solve it, but it works. */ + #ifdef __WIN32__ bloat = 1; #else @@ -673,9 +686,12 @@ ComputeRectOvalBbox(canvas, rectOvalPtr) #endif } else { #ifdef MAC_OSX_TK - /* Mac OS X CoreGraphics needs correct rounding here - * otherwise it will draw outside the bounding box. - * Probably correct on other platforms as well? */ + /* + * Mac OS X CoreGraphics needs correct rounding here otherwise it will + * draw outside the bounding box. Probably correct on other platforms + * as well? + */ + bloat = (int) (width+1.5)/2; #else bloat = (int) (width+1)/2; @@ -683,9 +699,9 @@ ComputeRectOvalBbox(canvas, rectOvalPtr) } /* - * Special note: the rectangle is always drawn at least 1x1 in - * size, so round up the upper coordinates to be at least 1 unit - * greater than the lower ones. + * Special note: the rectangle is always drawn at least 1x1 in size, so + * round up the upper coordinates to be at least 1 unit greater than the + * lower ones. */ tmp = (int) ((rectOvalPtr->bbox[0] >= 0) ? rectOvalPtr->bbox[0] + .5 @@ -713,28 +729,27 @@ ComputeRectOvalBbox(canvas, rectOvalPtr) * * DisplayRectOval -- * - * This procedure is invoked to draw a rectangle or oval - * item in a given drawable. + * This function is invoked to draw a rectangle or oval item in a given + * drawable. * * Results: * None. * * Side effects: - * ItemPtr is drawn in drawable using the transformation - * information in canvas. + * ItemPtr is drawn in drawable using the transformation information in + * canvas. * *-------------------------------------------------------------- */ static void DisplayRectOval(canvas, itemPtr, display, drawable, x, y, width, height) - Tk_Canvas canvas; /* Canvas that contains item. */ - Tk_Item *itemPtr; /* Item to be displayed. */ - Display *display; /* Display on which to draw item. */ - Drawable drawable; /* Pixmap or window in which to draw - * item. */ - int x, y, width, height; /* Describes region of canvas that - * must be redisplayed (not used). */ + Tk_Canvas canvas; /* Canvas that contains item. */ + Tk_Item *itemPtr; /* Item to be displayed. */ + Display *display; /* Display on which to draw item. */ + Drawable drawable; /* Pixmap or window in which to draw item. */ + int x, y, width, height; /* Describes region of canvas that must be + * redisplayed (not used). */ { RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; short x1, y1, x2, y2; @@ -742,9 +757,9 @@ DisplayRectOval(canvas, itemPtr, display, drawable, x, y, width, height) Tk_State state = itemPtr->state; /* - * Compute the screen coordinates of the bounding box for the item. - * Make sure that the bbox is at least one pixel large, since some - * X servers will die if it isn't. + * Compute the screen coordinates of the bounding box for the item. Make + * sure that the bbox is at least one pixel large, since some X servers + * will die if it isn't. */ Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[0], rectOvalPtr->bbox[1], @@ -759,22 +774,21 @@ DisplayRectOval(canvas, itemPtr, display, drawable, x, y, width, height) } /* - * Display filled part first (if wanted), then outline. If we're - * stippling, then modify the stipple offset in the GC. Be sure to - * reset the offset when done, since the GC is supposed to be - * read-only. + * Display filled part first (if wanted), then outline. If we're + * stippling, then modify the stipple offset in the GC. Be sure to reset + * the offset when done, since the GC is supposed to be read-only. */ - if(state == TK_STATE_NULL) { + if (state == TK_STATE_NULL) { state = ((TkCanvas *)canvas)->canvas_state; } fillStipple = rectOvalPtr->fillStipple; if (((TkCanvas *)canvas)->currentItemPtr == (Tk_Item *)rectOvalPtr) { - if (rectOvalPtr->activeFillStipple!=None) { + if (rectOvalPtr->activeFillStipple != None) { fillStipple = rectOvalPtr->activeFillStipple; } - } else if (state==TK_STATE_DISABLED) { - if (rectOvalPtr->disabledFillStipple!=None) { + } else if (state == TK_STATE_DISABLED) { + if (rectOvalPtr->disabledFillStipple != None) { fillStipple = rectOvalPtr->disabledFillStipple; } } @@ -782,10 +796,12 @@ DisplayRectOval(canvas, itemPtr, display, drawable, x, y, width, height) if (rectOvalPtr->fillGC != None) { if (fillStipple != None) { Tk_TSOffset *tsoffset; - int w=0; int h=0; + int w = 0, h = 0; + tsoffset = &rectOvalPtr->tsoffset; if (tsoffset) { int flags = tsoffset->flags; + if (flags & (TK_OFFSET_CENTER|TK_OFFSET_MIDDLE)) { Tk_SizeOfBitmap(display, fillStipple, &w, &h); if (flags & TK_OFFSET_CENTER) { @@ -820,6 +836,7 @@ DisplayRectOval(canvas, itemPtr, display, drawable, x, y, width, height) XSetTSOrigin(display, rectOvalPtr->fillGC, 0, 0); } } + if (rectOvalPtr->outline.gc != None) { Tk_ChangeOutlineGC(canvas, itemPtr, &(rectOvalPtr->outline)); if (rectOvalPtr->header.typePtr == &tkRectangleType) { @@ -838,17 +855,16 @@ DisplayRectOval(canvas, itemPtr, display, drawable, x, y, width, height) * * RectToPoint -- * - * Computes the distance from a given point to a given - * rectangle, in canvas units. + * Computes the distance from a given point to a given rectangle, in + * canvas units. * * Results: - * The return value is 0 if the point whose x and y coordinates - * are coordPtr[0] and coordPtr[1] is inside the rectangle. If the - * point isn't inside the rectangle then the return value is the - * distance from the point to the rectangle. If itemPtr is filled, - * then anywhere in the interior is considered "inside"; if - * itemPtr isn't filled, then "inside" means only the area - * occupied by the outline. + * The return value is 0 if the point whose x and y coordinates are + * coordPtr[0] and coordPtr[1] is inside the rectangle. If the point + * isn't inside the rectangle then the return value is the distance from + * the point to the rectangle. If itemPtr is filled, then anywhere in the + * interior is considered "inside"; if itemPtr isn't filled, then + * "inside" means only the area occupied by the outline. * * Side effects: * None. @@ -868,7 +884,7 @@ RectToPoint(canvas, itemPtr, pointPtr) double width; Tk_State state = itemPtr->state; - if(state == TK_STATE_NULL) { + if (state == TK_STATE_NULL) { state = ((TkCanvas *)canvas)->canvas_state; } @@ -877,15 +893,15 @@ RectToPoint(canvas, itemPtr, pointPtr) if (rectPtr->outline.activeWidth>width) { width = rectPtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { + } else if (state == TK_STATE_DISABLED) { if (rectPtr->outline.disabledWidth>0) { width = rectPtr->outline.disabledWidth; } } /* - * Generate a new larger rectangle that includes the border - * width, if there is one. + * Generate a new larger rectangle that includes the border width, if + * there is one. */ x1 = rectPtr->bbox[0]; @@ -901,14 +917,13 @@ RectToPoint(canvas, itemPtr, pointPtr) } /* - * If the point is inside the rectangle, handle specially: - * distance is 0 if rectangle is filled, otherwise compute - * distance to nearest edge of rectangle and subtract width - * of edge. + * If the point is inside the rectangle, handle specially: distance is 0 + * if rectangle is filled, otherwise compute distance to nearest edge of + * rectangle and subtract width of edge. */ if ((pointPtr[0] >= x1) && (pointPtr[0] < x2) - && (pointPtr[1] >= y1) && (pointPtr[1] < y2)) { + && (pointPtr[1] >= y1) && (pointPtr[1] < y2)) { if ((rectPtr->fillGC != None) || (rectPtr->outline.gc == None)) { return 0.0; } @@ -960,17 +975,16 @@ RectToPoint(canvas, itemPtr, pointPtr) * * OvalToPoint -- * - * Computes the distance from a given point to a given - * oval, in canvas units. + * Computes the distance from a given point to a given oval, in canvas + * units. * * Results: - * The return value is 0 if the point whose x and y coordinates - * are coordPtr[0] and coordPtr[1] is inside the oval. If the - * point isn't inside the oval then the return value is the - * distance from the point to the oval. If itemPtr is filled, - * then anywhere in the interior is considered "inside"; if - * itemPtr isn't filled, then "inside" means only the area - * occupied by the outline. + * The return value is 0 if the point whose x and y coordinates are + * coordPtr[0] and coordPtr[1] is inside the oval. If the point isn't + * inside the oval then the return value is the distance from the point + * to the oval. If itemPtr is filled, then anywhere in the interior is + * considered "inside"; if itemPtr isn't filled, then "inside" means only + * the area occupied by the outline. * * Side effects: * None. @@ -990,7 +1004,7 @@ OvalToPoint(canvas, itemPtr, pointPtr) int filled; Tk_State state = itemPtr->state; - if(state == TK_STATE_NULL) { + if (state == TK_STATE_NULL) { state = ((TkCanvas *)canvas)->canvas_state; } @@ -999,7 +1013,7 @@ OvalToPoint(canvas, itemPtr, pointPtr) if (ovalPtr->outline.activeWidth>width) { width = (double) ovalPtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { + } else if (state == TK_STATE_DISABLED) { if (ovalPtr->outline.disabledWidth>0) { width = (double) ovalPtr->outline.disabledWidth; } @@ -1019,14 +1033,13 @@ OvalToPoint(canvas, itemPtr, pointPtr) * * RectToArea -- * - * This procedure is called to determine whether an item - * lies entirely inside, entirely outside, or overlapping - * a given rectangle. + * This function is called to determine whether an item lies entirely + * inside, entirely outside, or overlapping a given rectangle. * * Results: - * -1 is returned if the item is entirely outside the area - * given by rectPtr, 0 if it overlaps, and 1 if it is entirely - * inside the given area. + * -1 is returned if the item is entirely outside the area given by + * rectPtr, 0 if it overlaps, and 1 if it is entirely inside the given + * area. * * Side effects: * None. @@ -1039,16 +1052,15 @@ static int RectToArea(canvas, itemPtr, areaPtr) Tk_Canvas canvas; /* Canvas containing item. */ Tk_Item *itemPtr; /* Item to check against rectangle. */ - double *areaPtr; /* Pointer to array of four coordinates - * (x1, y1, x2, y2) describing rectangular - * area. */ + double *areaPtr; /* Pointer to array of four coordinates (x1, + * y1, x2, y2) describing rectangular area. */ { RectOvalItem *rectPtr = (RectOvalItem *) itemPtr; double halfWidth; double width; Tk_State state = itemPtr->state; - if(state == TK_STATE_NULL) { + if (state == TK_STATE_NULL) { state = ((TkCanvas *)canvas)->canvas_state; } @@ -1057,7 +1069,7 @@ RectToArea(canvas, itemPtr, areaPtr) if (rectPtr->outline.activeWidth>width) { width = rectPtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { + } else if (state == TK_STATE_DISABLED) { if (rectPtr->outline.disabledWidth>0) { width = rectPtr->outline.disabledWidth; } @@ -1095,14 +1107,13 @@ RectToArea(canvas, itemPtr, areaPtr) * * OvalToArea -- * - * This procedure is called to determine whether an item - * lies entirely inside, entirely outside, or overlapping - * a given rectangular area. + * This function is called to determine whether an item lies entirely + * inside, entirely outside, or overlapping a given rectangular area. * * Results: - * -1 is returned if the item is entirely outside the area - * given by rectPtr, 0 if it overlaps, and 1 if it is entirely - * inside the given area. + * -1 is returned if the item is entirely outside the area given by + * rectPtr, 0 if it overlaps, and 1 if it is entirely inside the given + * area. * * Side effects: * None. @@ -1115,9 +1126,8 @@ static int OvalToArea(canvas, itemPtr, areaPtr) Tk_Canvas canvas; /* Canvas containing item. */ Tk_Item *itemPtr; /* Item to check against oval. */ - double *areaPtr; /* Pointer to array of four coordinates - * (x1, y1, x2, y2) describing rectangular - * area. */ + double *areaPtr; /* Pointer to array of four coordinates (x1, + * y1, x2, y2) describing rectangular area. */ { RectOvalItem *ovalPtr = (RectOvalItem *) itemPtr; double oval[4], halfWidth; @@ -1125,7 +1135,7 @@ OvalToArea(canvas, itemPtr, areaPtr) double width; Tk_State state = itemPtr->state; - if(state == TK_STATE_NULL) { + if (state == TK_STATE_NULL) { state = ((TkCanvas *)canvas)->canvas_state; } @@ -1134,7 +1144,7 @@ OvalToArea(canvas, itemPtr, areaPtr) if (ovalPtr->outline.activeWidth>width) { width = ovalPtr->outline.activeWidth; } - } else if (state==TK_STATE_DISABLED) { + } else if (state == TK_STATE_DISABLED) { if (ovalPtr->outline.disabledWidth>0) { width = ovalPtr->outline.disabledWidth; } @@ -1156,10 +1166,10 @@ OvalToArea(canvas, itemPtr, areaPtr) result = TkOvalToArea(oval, areaPtr); /* - * If the rectangle appears to overlap the oval and the oval - * isn't filled, do one more check to see if perhaps all four - * of the rectangle's corners are totally inside the oval's - * unfilled center, in which case we should return "outside". + * If the rectangle appears to overlap the oval and the oval isn't filled, + * do one more check to see if perhaps all four of the rectangle's corners + * are totally inside the oval's unfilled center, in which case we should + * return "outside". */ if ((result == 0) && (ovalPtr->outline.gc != None) @@ -1194,16 +1204,14 @@ OvalToArea(canvas, itemPtr, areaPtr) * * ScaleRectOval -- * - * This procedure is invoked to rescale a rectangle or oval - * item. + * This function is invoked to rescale a rectangle or oval item. * * Results: * None. * * Side effects: - * The rectangle or oval referred to by itemPtr is rescaled - * so that the following transformation is applied to all - * point coordinates: + * The rectangle or oval referred to by itemPtr is rescaled so that the + * following transformation is applied to all point coordinates: * x' = originX + scaleX*(x-originX) * y' = originY + scaleY*(y-originY) * @@ -1212,11 +1220,11 @@ OvalToArea(canvas, itemPtr, areaPtr) static void ScaleRectOval(canvas, itemPtr, originX, originY, scaleX, scaleY) - Tk_Canvas canvas; /* Canvas containing rectangle. */ - Tk_Item *itemPtr; /* Rectangle to be scaled. */ - double originX, originY; /* Origin about which to scale rect. */ - double scaleX; /* Amount to scale in X direction. */ - double scaleY; /* Amount to scale in Y direction. */ + Tk_Canvas canvas; /* Canvas containing rectangle. */ + Tk_Item *itemPtr; /* Rectangle to be scaled. */ + double originX, originY; /* Origin about which to scale rect. */ + double scaleX; /* Amount to scale in X direction. */ + double scaleY; /* Amount to scale in Y direction. */ { RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; @@ -1232,26 +1240,24 @@ ScaleRectOval(canvas, itemPtr, originX, originY, scaleX, scaleY) * * TranslateRectOval -- * - * This procedure is called to move a rectangle or oval by a - * given amount. + * This function is called to move a rectangle or oval by a given amount. * * Results: * None. * * Side effects: - * The position of the rectangle or oval is offset by - * (xDelta, yDelta), and the bounding box is updated in the - * generic part of the item structure. + * The position of the rectangle or oval is offset by (xDelta, yDelta), + * and the bounding box is updated in the generic part of the item + * structure. * *-------------------------------------------------------------- */ static void TranslateRectOval(canvas, itemPtr, deltaX, deltaY) - Tk_Canvas canvas; /* Canvas containing item. */ - Tk_Item *itemPtr; /* Item that is being moved. */ - double deltaX, deltaY; /* Amount by which item is to be - * moved. */ + Tk_Canvas canvas; /* Canvas containing item. */ + Tk_Item *itemPtr; /* Item that is being moved. */ + double deltaX, deltaY; /* Amount by which item is to be moved. */ { RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; @@ -1267,15 +1273,14 @@ TranslateRectOval(canvas, itemPtr, deltaX, deltaY) * * RectOvalToPostscript -- * - * This procedure is called to generate Postscript for - * rectangle and oval items. + * This function is called to generate Postscript for rectangle and oval + * items. * * Results: - * The return value is a standard Tcl result. If an error - * occurs in generating Postscript then an error message is - * left in the interp's result, replacing whatever used to be there. - * If no error occurs, then Postscript for the rectangle is - * appended to the result. + * The return value is a standard Tcl result. If an error occurs in + * generating Postscript then an error message is left in the interp's + * result, replacing whatever used to be there. If no error occurs, then + * Postscript for the rectangle is appended to the result. * * Side effects: * None. @@ -1285,13 +1290,12 @@ TranslateRectOval(canvas, itemPtr, deltaX, deltaY) static int RectOvalToPostscript(interp, canvas, itemPtr, prepass) - Tcl_Interp *interp; /* Interpreter for error reporting. */ - Tk_Canvas canvas; /* Information about overall canvas. */ - Tk_Item *itemPtr; /* Item for which Postscript is - * wanted. */ - int prepass; /* 1 means this is a prepass to - * collect font information; 0 means - * final Postscript is being created. */ + Tcl_Interp *interp; /* Interpreter for error reporting. */ + Tk_Canvas canvas; /* Information about overall canvas. */ + Tk_Item *itemPtr; /* Item for which Postscript is wanted. */ + int prepass; /* 1 means this is a prepass to collect font + * information; 0 means final Postscript is + * being created. */ { char pathCmd[500]; RectOvalItem *rectOvalPtr = (RectOvalItem *) itemPtr; @@ -1305,12 +1309,10 @@ RectOvalToPostscript(interp, canvas, itemPtr, prepass) y2 = Tk_CanvasPsY(canvas, rectOvalPtr->bbox[3]); /* - * Generate a string that creates a path for the rectangle or oval. - * This is the only part of the procedure's code that is type- - * specific. + * Generate a string that creates a path for the rectangle or oval. This + * is the only part of the function's code that is type-specific. */ - if (rectOvalPtr->header.typePtr == &tkRectangleType) { sprintf(pathCmd, "%.15g %.15g moveto %.15g 0 rlineto 0 %.15g rlineto %.15g 0 rlineto closepath\n", rectOvalPtr->bbox[0], y1, @@ -1322,7 +1324,7 @@ RectOvalToPostscript(interp, canvas, itemPtr, prepass) (rectOvalPtr->bbox[2] - rectOvalPtr->bbox[0])/2, (y1 - y2)/2); } - if(state == TK_STATE_NULL) { + if (state == TK_STATE_NULL) { state = ((TkCanvas *)canvas)->canvas_state; } color = rectOvalPtr->outline.color; @@ -1338,7 +1340,7 @@ RectOvalToPostscript(interp, canvas, itemPtr, prepass) if (rectOvalPtr->activeFillStipple!=None) { fillStipple = rectOvalPtr->activeFillStipple; } - } else if (state==TK_STATE_DISABLED) { + } else if (state == TK_STATE_DISABLED) { if (rectOvalPtr->outline.disabledColor!=NULL) { color = rectOvalPtr->outline.disabledColor; } @@ -1356,14 +1358,12 @@ RectOvalToPostscript(interp, canvas, itemPtr, prepass) if (fillColor != NULL) { Tcl_AppendResult(interp, pathCmd, (char *) NULL); - if (Tk_CanvasPsColor(interp, canvas, fillColor) - != TCL_OK) { + if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) { return TCL_ERROR; } if (fillStipple != None) { Tcl_AppendResult(interp, "clip ", (char *) NULL); - if (Tk_CanvasPsStipple(interp, canvas, fillStipple) - != TCL_OK) { + if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) { return TCL_ERROR; } if (color != NULL) { @@ -1388,3 +1388,11 @@ RectOvalToPostscript(interp, canvas, itemPtr, prepass) } return TCL_OK; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkText.c b/generic/tkText.c index f7dc176..bb4044b 100644 --- a/generic/tkText.c +++ b/generic/tkText.c @@ -1,20 +1,19 @@ -/* +/* * tkText.c -- * - * This module provides a big chunk of the implementation of - * multi-line editable text widgets for Tk. Among other things, it - * provides the Tcl command interfaces to text widgets. The B-tree - * representation of text and its actual display are implemented - * elsewhere. + * This module provides a big chunk of the implementation of multi-line + * editable text widgets for Tk. Among other things, it provides the Tcl + * command interfaces to text widgets. The B-tree representation of text + * and its actual display are implemented elsewhere. * * Copyright (c) 1992-1994 The Regents of the University of California. * Copyright (c) 1994-1996 Sun Microsystems, Inc. * Copyright (c) 1999 by Scriptics Corporation. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkText.c,v 1.57 2005/04/04 22:00:05 vincentdarley Exp $ + * RCS: @(#) $Id: tkText.c,v 1.58 2005/08/10 22:02:22 dkf Exp $ */ #include "default.h" @@ -29,26 +28,27 @@ /* * For compatibility with Tk 4.0 through 8.4.x, we allow tabs to be - * mis-specified with non-increasing values. These are converted into - * tabs which are the equivalent of at least a character width apart. + * mis-specified with non-increasing values. These are converted into tabs + * which are the equivalent of at least a character width apart. */ + #if (TK_MAJOR_VERSION < 9) #define _TK_ALLOW_DECREASING_TABS #endif #include "tkText.h" -/* - * Used to avoid having to allocate and deallocate arrays on the - * fly for commonly used procedures. Must be > 0. +/* + * Used to avoid having to allocate and deallocate arrays on the fly for + * commonly used functions. Must be > 0. */ #define PIXEL_CLIENTS 5 /* - * The 'TkTextState' enum in tkText.h is used to define a type for the - * -state option of the Text widget. These values are used as indices - * into the string table below. + * The 'TkTextState' enum in tkText.h is used to define a type for the -state + * option of the Text widget. These values are used as indices into the string + * table below. */ static char *stateStrings[] = { @@ -56,9 +56,9 @@ static char *stateStrings[] = { }; /* - * The 'TkWrapMode' enum in tkText.h is used to define a type for the - * -wrap option of the Text widget. These values are used as indices - * into the string table below. + * The 'TkWrapMode' enum in tkText.h is used to define a type for the -wrap + * option of the Text widget. These values are used as indices into the string + * table below. */ static char *wrapStrings[] = { @@ -69,22 +69,24 @@ static char *wrapStrings[] = { * The following functions and custom option type are used to define the * "line" option type, and thereby handle the text widget '-startline', * '-endline' configuration options which are of that type. - * - * We do not need a 'freeProc' because all changes to these two options - * are handled through the TK_TEXT_LINE_RANGE flag in the optionSpecs - * list, and the internal storage is just a pointer, which therefore - * doesn't need freeing. + * + * We do not need a 'freeProc' because all changes to these two options are + * handled through the TK_TEXT_LINE_RANGE flag in the optionSpecs list, and + * the internal storage is just a pointer, which therefore doesn't need + * freeing. */ -static int SetLineStartEnd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, Tk_Window tkwin, - Tcl_Obj **value, char *recordPtr, int internalOffset, - char *oldInternalPtr, int flags)); -static Tcl_Obj* GetLineStartEnd _ANSI_ARGS_((ClientData clientData, Tk_Window tkwin, - char *recordPtr, int internalOffset)); -static void RestoreLineStartEnd _ANSI_ARGS_((ClientData clientData, - Tk_Window tkwin, char *internalPtr, - char *oldInternalPtr)); -static int ObjectIsEmpty _ANSI_ARGS_((Tcl_Obj *objPtr)); + +static int SetLineStartEnd(ClientData clientData, + Tcl_Interp *interp, Tk_Window tkwin, + Tcl_Obj **value, char *recordPtr, + int internalOffset, char *oldInternalPtr, + int flags); +static Tcl_Obj* GetLineStartEnd(ClientData clientData, Tk_Window tkwin, + char *recordPtr, int internalOffset); +static void RestoreLineStartEnd(ClientData clientData, + Tk_Window tkwin, char *internalPtr, + char *oldInternalPtr); +static int ObjectIsEmpty(Tcl_Obj *objPtr); static Tk_ObjCustomOption lineOption = { "line", /* name */ @@ -101,21 +103,21 @@ static Tk_ObjCustomOption lineOption = { static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_BOOLEAN, "-autoseparators", "autoSeparators", - "AutoSeparators", DEF_TEXT_AUTO_SEPARATORS, -1, - Tk_Offset(TkText, autoSeparators), 0, 0, 0}, + "AutoSeparators", DEF_TEXT_AUTO_SEPARATORS, -1, + Tk_Offset(TkText, autoSeparators), 0, 0, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_TEXT_BG_COLOR, -1, Tk_Offset(TkText, border), 0, (ClientData) DEF_TEXT_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", (char *) NULL, (char *) NULL, - (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", + (char *) NULL, 0, -1, 0, (ClientData) "-borderwidth", TK_TEXT_LINE_GEOMETRY}, {TK_OPTION_SYNONYM, "-bg", (char *) NULL, (char *) NULL, (char *) NULL, 0, -1, 0, (ClientData) "-background", 0}, {TK_OPTION_BOOLEAN, "-blockcursor", "blockCursor", - "BlockCursor", DEF_TEXT_BLOCK_CURSOR, -1, + "BlockCursor", DEF_TEXT_BLOCK_CURSOR, -1, Tk_Offset(TkText, insertCursorType), 0, 0, 0}, {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth", - DEF_TEXT_BORDER_WIDTH, -1, Tk_Offset(TkText, borderWidth), + DEF_TEXT_BORDER_WIDTH, -1, Tk_Offset(TkText, borderWidth), 0, 0, TK_TEXT_LINE_GEOMETRY}, {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", DEF_TEXT_CURSOR, -1, Tk_Offset(TkText, cursor), @@ -124,70 +126,70 @@ static Tk_OptionSpec optionSpecs[] = { NULL, -1, Tk_Offset(TkText, end), TK_OPTION_NULL_OK, (ClientData) &lineOption, TK_TEXT_LINE_RANGE}, {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection", - "ExportSelection", DEF_TEXT_EXPORT_SELECTION, -1, + "ExportSelection", DEF_TEXT_EXPORT_SELECTION, -1, Tk_Offset(TkText, exportSelection), 0, 0, 0}, {TK_OPTION_SYNONYM, "-fg", "foreground", (char *) NULL, (char *) NULL, 0, -1, 0, (ClientData) "-foreground", 0}, {TK_OPTION_FONT, "-font", "font", "Font", - DEF_TEXT_FONT, -1, Tk_Offset(TkText, tkfont), 0, 0, + DEF_TEXT_FONT, -1, Tk_Offset(TkText, tkfont), 0, 0, TK_TEXT_LINE_GEOMETRY}, {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground", - DEF_TEXT_FG, -1, Tk_Offset(TkText, fgColor), 0, + DEF_TEXT_FG, -1, Tk_Offset(TkText, fgColor), 0, 0, 0}, {TK_OPTION_PIXELS, "-height", "height", "Height", DEF_TEXT_HEIGHT, -1, Tk_Offset(TkText, height), 0, 0, 0}, {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground", "HighlightBackground", DEF_TEXT_HIGHLIGHT_BG, - -1, Tk_Offset(TkText, highlightBgColorPtr), + -1, Tk_Offset(TkText, highlightBgColorPtr), 0, 0, 0}, {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor", DEF_TEXT_HIGHLIGHT, -1, Tk_Offset(TkText, highlightColorPtr), 0, 0, 0}, {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness", - "HighlightThickness", DEF_TEXT_HIGHLIGHT_WIDTH, -1, + "HighlightThickness", DEF_TEXT_HIGHLIGHT_WIDTH, -1, Tk_Offset(TkText, highlightWidth), 0, 0, TK_TEXT_LINE_GEOMETRY}, - {TK_OPTION_BORDER, "-inactiveselectbackground", "inactiveSelectBackground", - "Foreground", + {TK_OPTION_BORDER, "-inactiveselectbackground", "inactiveSelectBackground", + "Foreground", #ifdef ALWAYS_SHOW_SELECTION - DEF_TEXT_SELECT_COLOR, + DEF_TEXT_SELECT_COLOR, #else - NULL, + NULL, #endif -1, Tk_Offset(TkText, inactiveSelBorder), TK_OPTION_NULL_OK, (ClientData) DEF_TEXT_SELECT_MONO, 0}, {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground", DEF_TEXT_INSERT_BG, - -1, Tk_Offset(TkText, insertBorder), + -1, Tk_Offset(TkText, insertBorder), 0, 0, 0}, - {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth", - "BorderWidth", DEF_TEXT_INSERT_BD_COLOR, -1, - Tk_Offset(TkText, insertBorderWidth), 0, + {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth", + "BorderWidth", DEF_TEXT_INSERT_BD_COLOR, -1, + Tk_Offset(TkText, insertBorderWidth), 0, (ClientData) DEF_TEXT_INSERT_BD_MONO, 0}, {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime", - DEF_TEXT_INSERT_OFF_TIME, -1, Tk_Offset(TkText, insertOffTime), + DEF_TEXT_INSERT_OFF_TIME, -1, Tk_Offset(TkText, insertOffTime), 0, 0, 0}, {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime", - DEF_TEXT_INSERT_ON_TIME, -1, Tk_Offset(TkText, insertOnTime), + DEF_TEXT_INSERT_ON_TIME, -1, Tk_Offset(TkText, insertOnTime), 0, 0, 0}, {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth", - DEF_TEXT_INSERT_WIDTH, -1, Tk_Offset(TkText, insertWidth), + DEF_TEXT_INSERT_WIDTH, -1, Tk_Offset(TkText, insertWidth), 0, 0, 0}, {TK_OPTION_INT, "-maxundo", "maxUndo", "MaxUndo", DEF_TEXT_MAX_UNDO, -1, Tk_Offset(TkText, maxUndo), 0, 0, 0}, {TK_OPTION_PIXELS, "-padx", "padX", "Pad", - DEF_TEXT_PADX, -1, Tk_Offset(TkText, padX), 0, 0, + DEF_TEXT_PADX, -1, Tk_Offset(TkText, padX), 0, 0, TK_TEXT_LINE_GEOMETRY}, {TK_OPTION_PIXELS, "-pady", "padY", "Pad", DEF_TEXT_PADY, -1, Tk_Offset(TkText, padY), 0, 0, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", DEF_TEXT_RELIEF, -1, Tk_Offset(TkText, relief), 0, 0, 0}, {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground", - DEF_TEXT_SELECT_COLOR, -1, Tk_Offset(TkText, selBorder), + DEF_TEXT_SELECT_COLOR, -1, Tk_Offset(TkText, selBorder), 0, (ClientData) DEF_TEXT_SELECT_MONO, 0}, - {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", - "BorderWidth", DEF_TEXT_SELECT_BD_COLOR, - Tk_Offset(TkText, selBorderWidthPtr), - Tk_Offset(TkText, selBorderWidth), + {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth", + "BorderWidth", DEF_TEXT_SELECT_BD_COLOR, + Tk_Offset(TkText, selBorderWidthPtr), + Tk_Offset(TkText, selBorderWidth), TK_OPTION_NULL_OK, (ClientData) DEF_TEXT_SELECT_BD_MONO, 0}, {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background", DEF_TEXT_SELECT_FG_COLOR, -1, Tk_Offset(TkText, selFgColorPtr), @@ -207,234 +209,212 @@ static Tk_OptionSpec optionSpecs[] = { NULL, -1, Tk_Offset(TkText, start), TK_OPTION_NULL_OK, (ClientData) &lineOption, TK_TEXT_LINE_RANGE}, {TK_OPTION_STRING_TABLE, "-state", "state", "State", - DEF_TEXT_STATE, -1, Tk_Offset(TkText, state), + DEF_TEXT_STATE, -1, Tk_Offset(TkText, state), 0, (ClientData) stateStrings, 0}, {TK_OPTION_STRING, "-tabs", "tabs", "Tabs", DEF_TEXT_TABS, Tk_Offset(TkText, tabOptionPtr), -1, TK_OPTION_NULL_OK, 0, TK_TEXT_LINE_GEOMETRY}, {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", - DEF_TEXT_TAKE_FOCUS, -1, Tk_Offset(TkText, takeFocus), + DEF_TEXT_TAKE_FOCUS, -1, Tk_Offset(TkText, takeFocus), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_BOOLEAN, "-undo", "undo", "Undo", - DEF_TEXT_UNDO, -1, Tk_Offset(TkText, undo), 0, 0 , 0}, + DEF_TEXT_UNDO, -1, Tk_Offset(TkText, undo), 0, 0 , 0}, {TK_OPTION_INT, "-width", "width", "Width", - DEF_TEXT_WIDTH, -1, Tk_Offset(TkText, width), 0, 0, + DEF_TEXT_WIDTH, -1, Tk_Offset(TkText, width), 0, 0, TK_TEXT_LINE_GEOMETRY}, {TK_OPTION_STRING_TABLE, "-wrap", "wrap", "Wrap", - DEF_TEXT_WRAP, -1, Tk_Offset(TkText, wrapMode), + DEF_TEXT_WRAP, -1, Tk_Offset(TkText, wrapMode), 0, (ClientData) wrapStrings, TK_TEXT_LINE_GEOMETRY}, {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand", - DEF_TEXT_XSCROLL_COMMAND, -1, Tk_Offset(TkText, xScrollCmd), + DEF_TEXT_XSCROLL_COMMAND, -1, Tk_Offset(TkText, xScrollCmd), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand", - DEF_TEXT_YSCROLL_COMMAND, -1, Tk_Offset(TkText, yScrollCmd), + DEF_TEXT_YSCROLL_COMMAND, -1, Tk_Offset(TkText, yScrollCmd), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_END} }; /* * These three typedefs, the structure and the SearchPerform, SearchCore - * functions below are used for line-based searches of the text widget, - * and, in particular, to handle multi-line matching even though the text - * widget is a single-line based data structure. They are completely - * abstracted away from the Text widget internals, however, so could - * easily be re-used with any line-based entity to provide multi-line - * matching. - * - * We have abstracted this code away from the text widget to try to - * keep Tk as modular as possible. + * functions below are used for line-based searches of the text widget, and, + * in particular, to handle multi-line matching even though the text widget is + * a single-line based data structure. They are completely abstracted away + * from the Text widget internals, however, so could easily be re-used with + * any line-based entity to provide multi-line matching. + * + * We have abstracted this code away from the text widget to try to keep Tk as + * modular as possible. */ struct SearchSpec; /* Forward declaration. */ -typedef ClientData SearchAddLineProc _ANSI_ARGS_((int lineNum, - struct SearchSpec *searchSpecPtr, - Tcl_Obj *theLine, int *lenPtr, - int *extraLinesPtr)); -typedef int SearchMatchProc _ANSI_ARGS_((int lineNum, - struct SearchSpec *searchSpecPtr, - ClientData clientData, Tcl_Obj *theLine, - int matchOffset, int matchLength)); -typedef int SearchLineIndexProc _ANSI_ARGS_((Tcl_Interp *interp, +typedef ClientData SearchAddLineProc(int lineNum, + struct SearchSpec *searchSpecPtr, + Tcl_Obj *theLine, int *lenPtr, + int *extraLinesPtr); +typedef int SearchMatchProc(int lineNum, + struct SearchSpec *searchSpecPtr, + ClientData clientData, Tcl_Obj *theLine, + int matchOffset, int matchLength); +typedef int SearchLineIndexProc(Tcl_Interp *interp, Tcl_Obj *objPtr, struct SearchSpec *searchSpecPtr, - int *linePosPtr, int *offsetPosPtr)); + int *linePosPtr, int *offsetPosPtr); typedef struct SearchSpec { - int exact; /* Whether search is exact or regexp */ - int noCase; /* Case-insenstivive? */ - int noLineStop; /* If not set, a regexp search will - * use the TCL_REG_NLSTOP flag */ - int overlap; /* If set, results from multiple - * searches (-all) are allowed to - * overlap each other. */ - int strictLimits; /* If set, matches must be - * completely inside the from,to - * range. Otherwise the limits - * only apply to the start of each - * match. */ - int all; /* Whether all or the first match should - * be reported */ - int startLine; /* First line to examine */ - int startOffset; /* Index in first line to start at */ - int stopLine; /* Last line to examine, or -1 when we - * search all available text */ - int stopOffset; /* Index to stop at, provided stopLine - * is not -1 */ - int numLines; /* Total lines which are available */ - int backwards; /* Searching forwards or backwards */ - Tcl_Obj *varPtr; /* If non-NULL, store length(s) of - * match(es) in this variable */ - Tcl_Obj *countPtr; /* Keeps track of currently found - * lengths */ - Tcl_Obj *resPtr; /* Keeps track of currently found - * locations */ - int searchElide; /* Search in hidden text as well */ - SearchAddLineProc *addLineProc; /* Function to call when we need to - * add another line to the search string - * so far */ - SearchMatchProc *foundMatchProc; /* Function to call when we have - * found a match */ - SearchLineIndexProc *lineIndexProc;/* Function to call when we have - * found a match */ - ClientData clientData; /* Information about structure being - * searched, in this case a text - * widget. */ + int exact; /* Whether search is exact or regexp */ + int noCase; /* Case-insenstivive? */ + int noLineStop; /* If not set, a regexp search will use the + * TCL_REG_NLSTOP flag. */ + int overlap; /* If set, results from multiple searches + * (-all) are allowed to overlap each + * other. */ + int strictLimits; /* If set, matches must be completely inside + * the from,to range. Otherwise the limits + * only apply to the start of each match. */ + int all; /* Whether all or the first match should be + * reported. */ + int startLine; /* First line to examine. */ + int startOffset; /* Index in first line to start at. */ + int stopLine; /* Last line to examine, or -1 when we search + * all available text. */ + int stopOffset; /* Index to stop at, provided stopLine is not + * -1 */ + int numLines; /* Total lines which are available. */ + int backwards; /* Searching forwards or backwards. */ + Tcl_Obj *varPtr; /* If non-NULL, store length(s) of match(es) + * in this variable. */ + Tcl_Obj *countPtr; /* Keeps track of currently found lengths. */ + Tcl_Obj *resPtr; /* Keeps track of currently found locations */ + int searchElide; /* Search in hidden text as well. */ + SearchAddLineProc *addLineProc; + /* Function to call when we need to add + * another line to the search string so far */ + SearchMatchProc *foundMatchProc; + /* Function to call when we have found a + * match. */ + SearchLineIndexProc *lineIndexProc; + /* Function to call when we have found a + * match. */ + ClientData clientData; /* Information about structure being searched, + * in this case a text widget. */ } SearchSpec; -/* - * The text-widget-independent functions which actually perform - * the search, handling both regexp and exact searches. +/* + * The text-widget-independent functions which actually perform the search, + * handling both regexp and exact searches. */ -static int SearchCore _ANSI_ARGS_((Tcl_Interp *interp, - SearchSpec *searchSpecPtr, Tcl_Obj *patObj)); -static int SearchPerform _ANSI_ARGS_((Tcl_Interp *interp, + +static int SearchCore(Tcl_Interp *interp, + SearchSpec *searchSpecPtr, Tcl_Obj *patObj); +static int SearchPerform(Tcl_Interp *interp, SearchSpec *searchSpecPtr, Tcl_Obj *patObj, - Tcl_Obj *fromPtr, Tcl_Obj *toPtr)); + Tcl_Obj *fromPtr, Tcl_Obj *toPtr); /* - * Boolean variable indicating whether or not special debugging code - * should be executed. + * Boolean variable indicating whether or not special debugging code should be + * executed. */ int tkTextDebug = 0; /* - * Forward declarations for procedures defined later in this file: + * Forward declarations for functions defined later in this file: */ -static int ConfigureText _ANSI_ARGS_((Tcl_Interp *interp, - TkText *textPtr, int objc, Tcl_Obj *CONST objv[])); -static int DeleteChars _ANSI_ARGS_((TkSharedText *sharedPtr, - TkText *textPtr, - CONST TkTextIndex *indexPtr1, - CONST TkTextIndex *indexPtr2, int viewUpdate)); -static int CountIndices _ANSI_ARGS_((CONST TkText *textPtr, - CONST TkTextIndex *indexPtr1, - CONST TkTextIndex *indexPtr2, - TkTextCountType type)); -static void DestroyText _ANSI_ARGS_((TkText *textPtr)); -static int InsertChars _ANSI_ARGS_((TkSharedText *sharedTextPtr, - TkText *textPtr, - TkTextIndex *indexPtr, Tcl_Obj *stringPtr, - int viewUpdate)); -static void TextBlinkProc _ANSI_ARGS_((ClientData clientData)); -static void TextCmdDeletedProc _ANSI_ARGS_(( - ClientData clientData)); -static int CreateWidget _ANSI_ARGS_((TkSharedText *sharedPtr, - Tk_Window tkwin, Tcl_Interp *interp, - CONST TkText *parent, - int objc, Tcl_Obj *CONST objv[])); -static void TextEventProc _ANSI_ARGS_((ClientData clientData, - XEvent *eventPtr)); -static int TextFetchSelection _ANSI_ARGS_((ClientData clientData, - int offset, char *buffer, int maxBytes)); -static int TextIndexSortProc _ANSI_ARGS_((CONST VOID *first, - CONST VOID *second)); -static int TextInsertCmd _ANSI_ARGS_((TkSharedText *sharedTextPtr, - TkText *textPtr, - Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[], - CONST TkTextIndex *indexPtr, int viewUpdate)); -static int TextReplaceCmd _ANSI_ARGS_((TkText *textPtr, - Tcl_Interp *interp, +static int ConfigureText(Tcl_Interp *interp, + TkText *textPtr, int objc, Tcl_Obj *CONST objv[]); +static int DeleteChars(TkSharedText *sharedPtr, TkText *textPtr, + CONST TkTextIndex *indexPtr1, + CONST TkTextIndex *indexPtr2, int viewUpdate); +static int CountIndices(CONST TkText *textPtr, + CONST TkTextIndex *indexPtr1, + CONST TkTextIndex *indexPtr2, + TkTextCountType type); +static void DestroyText(TkText *textPtr); +static int InsertChars(TkSharedText *sharedTextPtr, + TkText *textPtr, TkTextIndex *indexPtr, + Tcl_Obj *stringPtr, int viewUpdate); +static void TextBlinkProc(ClientData clientData); +static void TextCmdDeletedProc(ClientData clientData); +static int CreateWidget(TkSharedText *sharedPtr, Tk_Window tkwin, + Tcl_Interp *interp, CONST TkText *parent, + int objc, Tcl_Obj *CONST objv[]); +static void TextEventProc(ClientData clientData, XEvent *eventPtr); +static int TextFetchSelection(ClientData clientData, int offset, + char *buffer, int maxBytes); +static int TextIndexSortProc(CONST VOID *first, + CONST VOID *second); +static int TextInsertCmd(TkSharedText *sharedTextPtr, + TkText *textPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[], + CONST TkTextIndex *indexPtr, int viewUpdate); +static int TextReplaceCmd(TkText *textPtr, Tcl_Interp *interp, CONST TkTextIndex *indexFromPtr, CONST TkTextIndex *indexToPtr, - int objc, Tcl_Obj *CONST objv[], - int viewUpdate)); -static int TextSearchCmd _ANSI_ARGS_((TkText *textPtr, - Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[])); -static int TextEditCmd _ANSI_ARGS_((TkText *textPtr, - Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[])); -static int TextWidgetObjCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[])); -static int SharedTextObjCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[])); -static void TextWorldChangedCallback _ANSI_ARGS_(( - ClientData instanceData)); -static void TextWorldChanged _ANSI_ARGS_((TkText *textPtr, - int mask)); -static int TextDumpCmd _ANSI_ARGS_((TkText *textPtr, - Tcl_Interp *interp, - int objc, Tcl_Obj *CONST objv[])); -static void DumpLine _ANSI_ARGS_((Tcl_Interp *interp, - TkText *textPtr, int what, TkTextLine *linePtr, - int start, int end, int lineno, - CONST char *command)); -static int DumpSegment _ANSI_ARGS_((TkText *textPtr, - Tcl_Interp *interp, - CONST char *key, - CONST char *value, CONST char * command, - CONST TkTextIndex *index, int what)); -static int TextEditUndo _ANSI_ARGS_((TkText *textPtr)); -static int TextEditRedo _ANSI_ARGS_((TkText *textPtr)); -static Tcl_Obj* TextGetText _ANSI_ARGS_((CONST TkText *textPtr, - CONST TkTextIndex * index1, - CONST TkTextIndex * index2, int visibleOnly)); -static void UpdateDirtyFlag _ANSI_ARGS_((TkSharedText *sharedPtr)); -static void TextPushUndoAction _ANSI_ARGS_((TkText *textPtr, - Tcl_Obj *undoString, int insert, + int objc, Tcl_Obj *CONST objv[], int viewUpdate); +static int TextSearchCmd(TkText *textPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); +static int TextEditCmd(TkText *textPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); +static int TextWidgetObjCmd(ClientData clientData, + Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); +static int SharedTextObjCmd(ClientData clientData, + Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); +static void TextWorldChangedCallback(ClientData instanceData); +static void TextWorldChanged(TkText *textPtr, int mask); +static int TextDumpCmd(TkText *textPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); +static void DumpLine(Tcl_Interp *interp, TkText *textPtr, int what, + TkTextLine *linePtr, int start, int end, + int lineno, CONST char *command); +static int DumpSegment(TkText *textPtr, Tcl_Interp *interp, + CONST char *key, CONST char *value, + CONST char *command, CONST TkTextIndex *index, + int what); +static int TextEditUndo(TkText *textPtr); +static int TextEditRedo(TkText *textPtr); +static Tcl_Obj * TextGetText(CONST TkText *textPtr, + CONST TkTextIndex *index1, + CONST TkTextIndex *index2, int visibleOnly); +static void UpdateDirtyFlag(TkSharedText *sharedPtr); +static void TextPushUndoAction(TkText *textPtr, + Tcl_Obj *undoString, int insert, CONST TkTextIndex *index1Ptr, - CONST TkTextIndex *index2Ptr)); -static int TextSearchIndexInLine _ANSI_ARGS_(( - CONST SearchSpec *searchSpecPtr, - TkTextLine *linePtr, int byteIndex)); -static int TextPeerCmd _ANSI_ARGS_((TkText *textPtr, - Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static TkUndoProc TextUndoRedoCallback; - -/* - * Declarations of the three search procs required by - * the multi-line search routines + CONST TkTextIndex *index2Ptr); +static int TextSearchIndexInLine(CONST SearchSpec *searchSpecPtr, + TkTextLine *linePtr, int byteIndex); +static int TextPeerCmd(TkText *textPtr, Tcl_Interp *interp, + int objc, Tcl_Obj *CONST objv[]); +static TkUndoProc TextUndoRedoCallback; + +/* + * Declarations of the three search procs required by the multi-line search + * routines. */ -static SearchMatchProc TextSearchFoundMatch; -static SearchAddLineProc TextSearchAddNextLine; -static SearchLineIndexProc TextSearchGetLineIndex; - +static SearchMatchProc TextSearchFoundMatch; +static SearchAddLineProc TextSearchAddNextLine; +static SearchLineIndexProc TextSearchGetLineIndex; /* - * The structure below defines text class behavior by means of procedures - * that can be invoked from generic window code. + * The structure below defines text class behavior by means of functions that + * can be invoked from generic window code. */ static Tk_ClassProcs textClass = { sizeof(Tk_ClassProcs), /* size */ TextWorldChangedCallback, /* worldChangedProc */ }; - /* *-------------------------------------------------------------- * * Tk_TextObjCmd -- * - * This procedure is invoked to process the "text" Tcl command. - * See the user documentation for details on what it does. + * This function is invoked to process the "text" Tcl command. See the + * user documentation for details on what it does. * * Results: * A standard Tcl result. @@ -447,8 +427,7 @@ static Tk_ClassProcs textClass = { int Tk_TextObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Main window associated with - * interpreter. */ + ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ @@ -468,15 +447,15 @@ Tk_TextObjCmd(clientData, interp, objc, objv) * * CreateWidget -- * - * This procedure is invoked to process the "text" Tcl command, - * (when called by Tk_TextObjCmd) and the "$text peer create" - * text widget sub-command (called from TextPeerCmd). - * + * This function is invoked to process the "text" Tcl command, (when + * called by Tk_TextObjCmd) and the "$text peer create" text widget + * sub-command (called from TextPeerCmd). + * * See the user documentation for details on what it does. * * Results: - * A standard Tcl result, places the name of the widget - * created into the interp's result. + * A standard Tcl result, places the name of the widget created into the + * interp's result. * * Side effects: * See the user documentation. @@ -487,11 +466,10 @@ Tk_TextObjCmd(clientData, interp, objc, objv) static int CreateWidget(sharedPtr, tkwin, interp, parent, objc, objv) TkSharedText *sharedPtr; /* Shared widget info, or null */ - Tk_Window tkwin; /* Main window associated with - * interpreter. */ + Tk_Window tkwin; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ - CONST TkText *parent; /* If non-NULL then take default - * start, end from this parent. */ + CONST TkText *parent; /* If non-NULL then take default start, end + * from this parent. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ { @@ -499,22 +477,21 @@ CreateWidget(sharedPtr, tkwin, interp, parent, objc, objv) Tk_OptionTable optionTable; TkTextIndex startIndex; Tk_Window new; - + /* * Create the window. */ - new = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]), - (char *) NULL); + new = Tk_CreateWindowFromPath(interp, tkwin, Tcl_GetString(objv[1]), + (char *) NULL); if (new == NULL) { return TCL_ERROR; } /* - * Create the text widget and initialize everything to zero, - * then set the necessary initial (non-NULL) values. It is - * important that the 'set' tag and 'insert', 'current' mark - * pointers are all NULL to start. + * Create the text widget and initialize everything to zero, then set the + * necessary initial (non-NULL) values. It is important that the 'set' tag + * and 'insert', 'current' mark pointers are all NULL to start. */ textPtr = (TkText *) ckalloc(sizeof(TkText)); @@ -530,11 +507,11 @@ CreateWidget(sharedPtr, tkwin, interp, parent, objc, objv) if (sharedPtr == NULL) { sharedPtr = (TkSharedText *) ckalloc(sizeof(TkSharedText)); memset((VOID *) sharedPtr, 0, sizeof(TkSharedText)); - + sharedPtr->refCount = 0; sharedPtr->peers = NULL; sharedPtr->tree = TkBTreeCreate(sharedPtr); - + Tcl_InitHashTable(&sharedPtr->tagTable, TCL_STRING_KEYS); Tcl_InitHashTable(&sharedPtr->markTable, TCL_STRING_KEYS); Tcl_InitHashTable(&sharedPtr->windowTable, TCL_STRING_KEYS); @@ -547,24 +524,28 @@ CreateWidget(sharedPtr, tkwin, interp, parent, objc, objv) sharedPtr->stateEpoch = 0; } - /* Add the new widget to the shared list */ + /* + * Add the new widget to the shared list. + */ + textPtr->sharedTextPtr = sharedPtr; sharedPtr->refCount++; textPtr->next = sharedPtr->peers; sharedPtr->peers = textPtr; - /* - * This refCount will be held until DestroyText is called. - * Note also that the later call to 'TkTextCreateDInfo' - * will add more refCounts. + + /* + * This refCount will be held until DestroyText is called. Note also that + * the later call to 'TkTextCreateDInfo' will add more refCounts. */ + textPtr->refCount = 1; - /* - * Specify start and end lines in the B-tree. The default - * is the same as the parent, but this can be adjusted to - * display more or less if the start, end where given - * as configuration options. + /* + * Specify start and end lines in the B-tree. The default is the same as + * the parent, but this can be adjusted to display more or less if the + * start, end where given as configuration options. */ + if (parent != NULL) { textPtr->start = parent->start; textPtr->end = parent->end; @@ -573,12 +554,12 @@ CreateWidget(sharedPtr, tkwin, interp, parent, objc, objv) textPtr->end = NULL; } - /* - * Register with the B-tree. In some sense it would be best - * if we could do this later (after configuration options), - * so that any changes to start,end do not require a total - * recalculation. + /* + * Register with the B-tree. In some sense it would be best if we could do + * this later (after configuration options), so that any changes to + * start,end do not require a total recalculation. */ + TkBTreeAddClient(sharedPtr->tree, textPtr, textPtr->charHeight); textPtr->state = TK_TEXT_STATE_NORMAL; @@ -589,10 +570,14 @@ CreateWidget(sharedPtr, tkwin, interp, parent, objc, objv) textPtr->wrapMode = TEXT_WRAPMODE_CHAR; textPtr->prevWidth = Tk_Width(new); textPtr->prevHeight = Tk_Height(new); - /* This will add refCounts to textPtr */ + + /* + * This will add refCounts to textPtr. + */ + TkTextCreateDInfo(textPtr); - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - 0, 0, &startIndex); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0, + &startIndex); TkTextSetYView(textPtr, &startIndex, 0); textPtr->exportSelection = 1; textPtr->pickEvent.type = LeaveNotify; @@ -600,7 +585,7 @@ CreateWidget(sharedPtr, tkwin, interp, parent, objc, objv) textPtr->maxUndo = textPtr->sharedTextPtr->maxUndo; textPtr->autoSeparators = textPtr->sharedTextPtr->autoSeparators; textPtr->tabOptionPtr = NULL; - + /* * Create the "sel" tag and the "current" and "insert" marks. */ @@ -610,21 +595,23 @@ CreateWidget(sharedPtr, tkwin, interp, parent, objc, objv) textPtr->selBorderWidth = 0; textPtr->selBorderWidthPtr = NULL; textPtr->selFgColorPtr = NULL; - /* - * Note: it is important that textPtr->selTagPtr is NULL before - * this initial call. + + /* + * Note: it is important that textPtr->selTagPtr is NULL before this + * initial call. */ + textPtr->selTagPtr = TkTextCreateTag(textPtr, "sel", NULL); - textPtr->selTagPtr->reliefString = - (char *) ckalloc(sizeof(DEF_TEXT_SELECT_RELIEF)); + textPtr->selTagPtr->reliefString = (char *) + ckalloc(sizeof(DEF_TEXT_SELECT_RELIEF)); strcpy(textPtr->selTagPtr->reliefString, DEF_TEXT_SELECT_RELIEF); textPtr->selTagPtr->relief = TK_RELIEF_RAISED; textPtr->currentMarkPtr = TkTextSetMark(textPtr, "current", &startIndex); textPtr->insertMarkPtr = TkTextSetMark(textPtr, "insert", &startIndex); /* - * Create the option table for this widget class. If it has already - * been created, the cached pointer will be returned. + * Create the option table for this widget class. If it has already been + * created, the cached pointer will be returned. */ optionTable = Tk_CreateOptionTable(interp, optionSpecs); @@ -642,7 +629,7 @@ CreateWidget(sharedPtr, tkwin, interp, parent, objc, objv) TkTextBindProc, (ClientData) textPtr); Tk_CreateSelHandler(textPtr->tkwin, XA_PRIMARY, XA_STRING, TextFetchSelection, (ClientData) textPtr, XA_STRING); - + if (Tk_InitOptions(interp, (char *) textPtr, optionTable, textPtr->tkwin) != TCL_OK) { Tk_DestroyWindow(textPtr->tkwin); @@ -653,8 +640,8 @@ CreateWidget(sharedPtr, tkwin, interp, parent, objc, objv) return TCL_ERROR; } - Tcl_SetObjResult(interp, - Tcl_NewStringObj(Tk_PathName(textPtr->tkwin),-1)); + Tcl_SetObjResult(interp, + Tcl_NewStringObj(Tk_PathName(textPtr->tkwin),-1)); return TCL_OK; } @@ -663,9 +650,9 @@ CreateWidget(sharedPtr, tkwin, interp, parent, objc, objv) * * TextWidgetObjCmd -- * - * This procedure is invoked to process the Tcl command - * that corresponds to a text widget. See the user - * documentation for details on what it does. + * This function is invoked to process the Tcl command that corresponds + * to a text widget. See the user documentation for details on what it + * does. * * Results: * A standard Tcl result. @@ -686,21 +673,21 @@ TextWidgetObjCmd(clientData, interp, objc, objv) register TkText *textPtr = (TkText *) clientData; int result = TCL_OK; int index; - + static CONST char *optionStrings[] = { - "bbox", "cget", "compare", "configure", "count", "debug", - "delete", "dlineinfo", "dump", "edit", "get", "image", "index", - "insert", "mark", "peer", "replace", "scan", "search", "see", - "tag", "window", "xview", "yview", (char *) NULL + "bbox", "cget", "compare", "configure", "count", "debug", + "delete", "dlineinfo", "dump", "edit", "get", "image", "index", + "insert", "mark", "peer", "replace", "scan", "search", "see", + "tag", "window", "xview", "yview", (char *) NULL }; enum options { - TEXT_BBOX, TEXT_CGET, TEXT_COMPARE, TEXT_CONFIGURE, TEXT_COUNT, - TEXT_DEBUG, TEXT_DELETE, TEXT_DLINEINFO, TEXT_DUMP, TEXT_EDIT, - TEXT_GET, TEXT_IMAGE, TEXT_INDEX, TEXT_INSERT, TEXT_MARK, - TEXT_PEER, TEXT_REPLACE, TEXT_SCAN, TEXT_SEARCH, TEXT_SEE, + TEXT_BBOX, TEXT_CGET, TEXT_COMPARE, TEXT_CONFIGURE, TEXT_COUNT, + TEXT_DEBUG, TEXT_DELETE, TEXT_DLINEINFO, TEXT_DUMP, TEXT_EDIT, + TEXT_GET, TEXT_IMAGE, TEXT_INDEX, TEXT_INSERT, TEXT_MARK, + TEXT_PEER, TEXT_REPLACE, TEXT_SCAN, TEXT_SEARCH, TEXT_SEE, TEXT_TAG, TEXT_WINDOW, TEXT_XVIEW, TEXT_YVIEW }; - + if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); return TCL_ERROR; @@ -713,783 +700,784 @@ TextWidgetObjCmd(clientData, interp, objc, objv) textPtr->refCount++; switch ((enum options) index) { - case TEXT_BBOX: { - int x, y, width, height; - CONST TkTextIndex *indexPtr; - - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "index"); - result = TCL_ERROR; - goto done; - } - indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); - if (indexPtr == NULL) { - result = TCL_ERROR; - goto done; - } - if (TkTextCharBbox(textPtr, indexPtr, &x, &y, - &width, &height, NULL) == 0) { - Tcl_Obj *listObj = Tcl_NewListObj(0, NULL); - - Tcl_ListObjAppendElement(interp, listObj, - Tcl_NewIntObj(x)); - Tcl_ListObjAppendElement(interp, listObj, - Tcl_NewIntObj(y)); - Tcl_ListObjAppendElement(interp, listObj, - Tcl_NewIntObj(width)); - Tcl_ListObjAppendElement(interp, listObj, - Tcl_NewIntObj(height)); - - Tcl_SetObjResult(interp, listObj); - } - break; + case TEXT_BBOX: { + int x, y, width, height; + CONST TkTextIndex *indexPtr; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "index"); + result = TCL_ERROR; + goto done; + } + indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); + if (indexPtr == NULL) { + result = TCL_ERROR; + goto done; + } + if (TkTextCharBbox(textPtr, indexPtr, &x, &y, &width, &height, + NULL) == 0) { + Tcl_Obj *listObj = Tcl_NewListObj(0, NULL); + + Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(x)); + Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(y)); + Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(width)); + Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(height)); + + Tcl_SetObjResult(interp, listObj); } - case TEXT_CGET: { - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "option"); + break; + } + case TEXT_CGET: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "option"); + result = TCL_ERROR; + goto done; + } else { + Tcl_Obj *objPtr = Tk_GetOptionValue(interp, (char *) textPtr, + textPtr->optionTable, objv[2], textPtr->tkwin); + if (objPtr == NULL) { result = TCL_ERROR; goto done; } else { - Tcl_Obj *objPtr = Tk_GetOptionValue(interp, (char *) textPtr, - textPtr->optionTable, objv[2], textPtr->tkwin); - if (objPtr == NULL) { - result = TCL_ERROR; - goto done; - } else { - Tcl_SetObjResult(interp, objPtr); - result = TCL_OK; - } + Tcl_SetObjResult(interp, objPtr); + result = TCL_OK; } - break; } - case TEXT_COMPARE: { - int relation, value; - CONST char *p; - CONST TkTextIndex *index1Ptr, *index2Ptr; - - if (objc != 5) { - Tcl_WrongNumArgs(interp, 2, objv, "index1 op index2"); - result = TCL_ERROR; - goto done; - } - index1Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); - index2Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[4]); - if (index1Ptr == NULL || index2Ptr == NULL) { + break; + case TEXT_COMPARE: { + int relation, value; + CONST char *p; + CONST TkTextIndex *index1Ptr, *index2Ptr; + + if (objc != 5) { + Tcl_WrongNumArgs(interp, 2, objv, "index1 op index2"); + result = TCL_ERROR; + goto done; + } + index1Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); + index2Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[4]); + if (index1Ptr == NULL || index2Ptr == NULL) { + result = TCL_ERROR; + goto done; + } + relation = TkTextIndexCmp(index1Ptr, index2Ptr); + p = Tcl_GetString(objv[3]); + if (p[0] == '<') { + value = (relation < 0); + if ((p[1] == '=') && (p[2] == 0)) { + value = (relation <= 0); + } else if (p[1] != 0) { + compareError: + Tcl_AppendResult(interp, "bad comparison operator \"", + Tcl_GetString(objv[3]), + "\": must be <, <=, ==, >=, >, or !=", + (char *) NULL); result = TCL_ERROR; goto done; } - relation = TkTextIndexCmp(index1Ptr, index2Ptr); - p = Tcl_GetString(objv[3]); - if (p[0] == '<') { - value = (relation < 0); - if ((p[1] == '=') && (p[2] == 0)) { - value = (relation <= 0); - } else if (p[1] != 0) { - compareError: - Tcl_AppendResult(interp, "bad comparison operator \"", - Tcl_GetString(objv[3]), - "\": must be <, <=, ==, >=, >, or !=", - (char *) NULL); - result = TCL_ERROR; - goto done; - } - } else if (p[0] == '>') { - value = (relation > 0); - if ((p[1] == '=') && (p[2] == 0)) { - value = (relation >= 0); - } else if (p[1] != 0) { - goto compareError; - } - } else if ((p[0] == '=') && (p[1] == '=') && (p[2] == 0)) { - value = (relation == 0); - } else if ((p[0] == '!') && (p[1] == '=') && (p[2] == 0)) { - value = (relation != 0); - } else { + } else if (p[0] == '>') { + value = (relation > 0); + if ((p[1] == '=') && (p[2] == 0)) { + value = (relation >= 0); + } else if (p[1] != 0) { goto compareError; } - Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value)); - break; - } - case TEXT_CONFIGURE: { - if (objc <= 3) { - Tcl_Obj* objPtr = Tk_GetOptionInfo(interp, (char *) textPtr, - textPtr->optionTable, - (objc == 3) ? objv[2] : (Tcl_Obj *) NULL, - textPtr->tkwin); - if (objPtr == NULL) { - result = TCL_ERROR; - goto done; - } else { - Tcl_SetObjResult(interp, objPtr); - } - } else { - result = ConfigureText(interp, textPtr, objc-2, objv+2); - } - break; + } else if ((p[0] == '=') && (p[1] == '=') && (p[2] == 0)) { + value = (relation == 0); + } else if ((p[0] == '!') && (p[1] == '=') && (p[2] == 0)) { + value = (relation != 0); + } else { + goto compareError; } - case TEXT_COUNT: { - CONST TkTextIndex *indexFromPtr, *indexToPtr; - int i, found = 0, update = 0; - Tcl_Obj *objPtr = NULL; - - if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, "?options? index1 index2"); + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value)); + break; + } + case TEXT_CONFIGURE: + if (objc <= 3) { + Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, (char *) textPtr, + textPtr->optionTable, + ((objc == 3) ? objv[2] : (Tcl_Obj *) NULL), + textPtr->tkwin); + if (objPtr == NULL) { result = TCL_ERROR; goto done; + } else { + Tcl_SetObjResult(interp, objPtr); } + } else { + result = ConfigureText(interp, textPtr, objc-2, objv+2); + } + break; + case TEXT_COUNT: { + CONST TkTextIndex *indexFromPtr, *indexToPtr; + int i, found = 0, update = 0; + Tcl_Obj *objPtr = NULL; + + if (objc < 4) { + Tcl_WrongNumArgs(interp, 2, objv, "?options? index1 index2"); + result = TCL_ERROR; + goto done; + } - indexFromPtr = TkTextGetIndexFromObj(interp, textPtr, objv[objc-2]); - if (indexFromPtr == NULL) { - result = TCL_ERROR; - goto done; - } - indexToPtr = TkTextGetIndexFromObj(interp, textPtr, objv[objc-1]); - if (indexToPtr == NULL) { - result = TCL_ERROR; - goto done; - } + indexFromPtr = TkTextGetIndexFromObj(interp, textPtr, objv[objc-2]); + if (indexFromPtr == NULL) { + result = TCL_ERROR; + goto done; + } + indexToPtr = TkTextGetIndexFromObj(interp, textPtr, objv[objc-1]); + if (indexToPtr == NULL) { + result = TCL_ERROR; + goto done; + } - for (i = 2; i < objc-2; i++) { - int value; - unsigned length; - CONST char *option = Tcl_GetStringFromObj(objv[i], - (int *)&length); - char c; - if (length < 2 || option[0] != '-') { - badOption: - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad option \"", - Tcl_GetString(objv[i]), + for (i = 2; i < objc-2; i++) { + int value, length; + CONST char *option = Tcl_GetStringFromObj(objv[i], &length); + char c; + + if (length < 2 || option[0] != '-') { + badOption: + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, "bad option \"", + Tcl_GetString(objv[i]), "\" must be -chars, -displaychars, -displayindices, ", "-displaylines, -indices, -lines, -update, ", "-xpixels, or -ypixels", NULL); - result = TCL_ERROR; - goto done; + result = TCL_ERROR; + goto done; + } + c = option[1]; + if (c == 'c' && !strncmp("-chars", option, (unsigned) length)) { + value = CountIndices(textPtr, indexFromPtr, indexToPtr, + COUNT_CHARS); + } else if (c == 'd' && (length > 8) + && !strncmp("-displaychars", option, (unsigned) length)) { + value = CountIndices(textPtr, indexFromPtr, indexToPtr, + COUNT_DISPLAY_CHARS); + } else if (c == 'd' && (length > 8) + && !strncmp("-displayindices", option, (unsigned)length)) { + value = CountIndices(textPtr, indexFromPtr, indexToPtr, + COUNT_DISPLAY_INDICES); + } else if (c == 'd' && (length > 8) + && !strncmp("-displaylines", option, (unsigned) length)) { + TkTextLine *fromPtr, *lastPtr; + TkTextIndex index; + + int compare = TkTextIndexCmp(indexFromPtr, indexToPtr); + value = 0; + + if (compare == 0) { + goto countDone; } - c = option[1]; - if (c == 'c' && !strncmp("-chars",option,length)) { - value = CountIndices(textPtr, indexFromPtr, indexToPtr, - COUNT_CHARS); - } else if (c == 'd' && !strncmp("-displaychars", option, - length) && (length > 8)) { - value = CountIndices(textPtr, indexFromPtr, indexToPtr, - COUNT_DISPLAY_CHARS); - } else if (c == 'd' && !strncmp("-displayindices", option, - length) && (length > 8)) { - value = CountIndices(textPtr, indexFromPtr, indexToPtr, - COUNT_DISPLAY_INDICES); - } else if (c == 'd' && !strncmp("-displaylines", option, - length) && (length > 8)) { - TkTextLine *fromPtr, *lastPtr; - TkTextIndex index; - - int compare = TkTextIndexCmp(indexFromPtr, indexToPtr); - value = 0; - - if (compare == 0) goto countDone; - - if (compare > 0) { - CONST TkTextIndex *tmpPtr = indexFromPtr; - indexFromPtr = indexToPtr; - indexToPtr = tmpPtr; - } - lastPtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, - textPtr, - TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr)); - fromPtr = indexFromPtr->linePtr; - if (fromPtr == lastPtr) { - goto countDone; - } + if (compare > 0) { + CONST TkTextIndex *tmpPtr = indexFromPtr; + + indexFromPtr = indexToPtr; + indexToPtr = tmpPtr; + } + + lastPtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, + textPtr, + TkBTreeNumLines(textPtr->sharedTextPtr->tree,textPtr)); + fromPtr = indexFromPtr->linePtr; + if (fromPtr == lastPtr) { + goto countDone; + } + + /* + * Caution: we must NEVER call TkTextUpdateOneLine with the + * last artificial line in the widget. + */ - /* - * Caution: we must NEVER call TkTextUpdateOneLine - * with the last artificial line in the widget. + index = *indexFromPtr; + while (index.linePtr != indexToPtr->linePtr) { + value += TkTextUpdateOneLine(textPtr, fromPtr, 0,&index,0); + + /* + * We might have skipped past indexToPtr, if we have + * multiple logical lines in a single display line. + * Therefore we iterate through each intermediate logical + * line, just to check. Another approach would be just to + * use TkTextIndexCmp on every while() iteration, but that + * would be less efficient. */ - index = *indexFromPtr; - while (index.linePtr != indexToPtr->linePtr) { - value += TkTextUpdateOneLine(textPtr, fromPtr, - 0, &index, 0); - /* - * We might have skipped past indexToPtr, if we - * have multiple logical lines in a single - * display line. Therefore we iterate through - * each intermediate logical line, just to - * check. Another approach would be just to use - * TkTextIndexCmp on every while() iteration, - * but that would be less efficient. - */ - while (fromPtr != index.linePtr) { - fromPtr = TkBTreeNextLine(textPtr, fromPtr); - if (fromPtr == indexToPtr->linePtr) { - break; - } + + while (fromPtr != index.linePtr) { + fromPtr = TkBTreeNextLine(textPtr, fromPtr); + if (fromPtr == indexToPtr->linePtr) { + break; } } - /* - * Now we need to adjust the count to add on the - * number of display lines in the last logical line, - * and subtract off the number of display lines - * overcounted in the first logical line. This logic - * is still ok if both indices are in the same - * logical line. - */ - index.linePtr = indexFromPtr->linePtr; + } + + /* + * Now we need to adjust the count to add on the number of + * display lines in the last logical line, and subtract off + * the number of display lines overcounted in the first + * logical line. This logic is still ok if both indices are in + * the same logical line. + */ + + index.linePtr = indexFromPtr->linePtr; + index.byteIndex = 0; + while (1) { + TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL); + if (index.byteIndex >= indexFromPtr->byteIndex) { + break; + } + TkTextIndexForwBytes(textPtr, &index, 1, &index); + value--; + + } + if (indexToPtr->linePtr != lastPtr) { + index.linePtr = indexToPtr->linePtr; index.byteIndex = 0; while (1) { TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL); - if (index.byteIndex >= indexFromPtr->byteIndex) { + if (index.byteIndex >= indexToPtr->byteIndex) { break; } TkTextIndexForwBytes(textPtr, &index, 1, &index); - value--; + value++; } - if (indexToPtr->linePtr != lastPtr) { - index.linePtr = indexToPtr->linePtr; - index.byteIndex = 0; - while (1) { - TkTextFindDisplayLineEnd(textPtr, &index, 1, NULL); - if (index.byteIndex >= indexToPtr->byteIndex) { - break; - } - TkTextIndexForwBytes(textPtr, &index, 1, &index); - value++; - } - } - - if (compare > 0) { - value = -value; - } - } else if (c == 'i' && !strncmp("-indices",option,length)) { - value = CountIndices(textPtr, indexFromPtr, indexToPtr, - COUNT_INDICES); - } else if (c == 'l' && !strncmp("-lines",option,length)) { - value = TkBTreeLinesTo(textPtr, indexToPtr->linePtr) - - TkBTreeLinesTo(textPtr, indexFromPtr->linePtr); - } else if (c == 'u' && !strncmp("-update",option,length)) { - update = 1; - continue; - } else if (c == 'x' && !strncmp("-xpixels",option,length)) { - int x1, x2; - TkTextIndex index; - index = *indexFromPtr; - TkTextFindDisplayLineEnd(textPtr, &index, 0, &x1); - index = *indexToPtr; - TkTextFindDisplayLineEnd(textPtr, &index, 0, &x2); - value = x2 - x1; - } else if (c == 'y' && !strncmp("-ypixels",option,length)) { - if (update) { - TkTextUpdateLineMetrics(textPtr, - TkBTreeLinesTo(textPtr, indexFromPtr->linePtr), - TkBTreeLinesTo(textPtr, indexToPtr->linePtr), -1); - } - value = TkTextIndexYPixels(textPtr, indexToPtr) - - TkTextIndexYPixels(textPtr, indexFromPtr); - } else { - goto badOption; } - countDone: - found++; - if (found == 1) { - Tcl_SetObjResult(interp, Tcl_NewIntObj(value)); - } else { - if (found == 2) { - /* - * Move the first item we put into the result into - * the first element of the list object. - */ - objPtr = Tcl_NewObj(); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_GetObjResult(interp)); - } - Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewIntObj(value)); + + if (compare > 0) { + value = -value; + } + } else if (c == 'i' + && !strncmp("-indices", option, (unsigned) length)) { + value = CountIndices(textPtr, indexFromPtr, indexToPtr, + COUNT_INDICES); + } else if (c == 'l' + && !strncmp("-lines", option, (unsigned) length)) { + value = TkBTreeLinesTo(textPtr, indexToPtr->linePtr) + - TkBTreeLinesTo(textPtr, indexFromPtr->linePtr); + } else if (c == 'u' + && !strncmp("-update", option, (unsigned) length)) { + update = 1; + continue; + } else if (c == 'x' + && !strncmp("-xpixels", option, (unsigned) length)) { + int x1, x2; + TkTextIndex index; + + index = *indexFromPtr; + TkTextFindDisplayLineEnd(textPtr, &index, 0, &x1); + index = *indexToPtr; + TkTextFindDisplayLineEnd(textPtr, &index, 0, &x2); + value = x2 - x1; + } else if (c == 'y' + && !strncmp("-ypixels", option, (unsigned) length)) { + if (update) { + TkTextUpdateLineMetrics(textPtr, + TkBTreeLinesTo(textPtr, indexFromPtr->linePtr), + TkBTreeLinesTo(textPtr, indexToPtr->linePtr), -1); } + value = TkTextIndexYPixels(textPtr, indexToPtr) + - TkTextIndexYPixels(textPtr, indexFromPtr); + } else { + goto badOption; } - if (found == 0) { - /* Use the default '-indices' */ - int value = CountIndices(textPtr, indexFromPtr, indexToPtr, - COUNT_INDICES); + + countDone: + found++; + if (found == 1) { Tcl_SetObjResult(interp, Tcl_NewIntObj(value)); - } else if (found > 1) { - Tcl_SetObjResult(interp, objPtr); - } - break; - } - case TEXT_DEBUG: { - if (objc > 3) { - Tcl_WrongNumArgs(interp, 2, objv, "boolean"); - result = TCL_ERROR; - goto done; - } - if (objc == 2) { - Tcl_SetObjResult(interp, Tcl_NewBooleanObj(tkBTreeDebug)); } else { - if (Tcl_GetBooleanFromObj(interp, objv[2], - &tkBTreeDebug) != TCL_OK) { - result = TCL_ERROR; - goto done; + if (found == 2) { + /* + * Move the first item we put into the result into + * the first element of the list object. + */ + objPtr = Tcl_NewObj(); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_GetObjResult(interp)); } - tkTextDebug = tkBTreeDebug; + Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewIntObj(value)); } - break; } - case TEXT_DELETE: { - if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "index1 ?index2 ...?"); + + if (found == 0) { + /* + * Use the default '-indices'. + */ + + int value = CountIndices(textPtr, indexFromPtr, indexToPtr, + COUNT_INDICES); + Tcl_SetObjResult(interp, Tcl_NewIntObj(value)); + } else if (found > 1) { + Tcl_SetObjResult(interp, objPtr); + } + break; + } + case TEXT_DEBUG: + if (objc > 3) { + Tcl_WrongNumArgs(interp, 2, objv, "boolean"); + result = TCL_ERROR; + goto done; + } + if (objc == 2) { + Tcl_SetObjResult(interp, Tcl_NewBooleanObj(tkBTreeDebug)); + } else { + if (Tcl_GetBooleanFromObj(interp, objv[2], + &tkBTreeDebug) != TCL_OK) { result = TCL_ERROR; goto done; } - if (textPtr->state == TK_TEXT_STATE_NORMAL) { - if (objc < 5) { - /* - * Simple case requires no predetermination of indices. - */ - CONST TkTextIndex *indexPtr1, *indexPtr2; - - /* - * Parse the starting and stopping indices. - */ + tkTextDebug = tkBTreeDebug; + } + break; + case TEXT_DELETE: + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "index1 ?index2 ...?"); + result = TCL_ERROR; + goto done; + } + if (textPtr->state == TK_TEXT_STATE_NORMAL) { + if (objc < 5) { + /* + * Simple case requires no predetermination of indices. + */ + + CONST TkTextIndex *indexPtr1, *indexPtr2; + + /* + * Parse the starting and stopping indices. + */ - indexPtr1 = TkTextGetIndexFromObj(textPtr->interp, - textPtr, objv[2]); - if (indexPtr1 == NULL) { + indexPtr1 = TkTextGetIndexFromObj(textPtr->interp, textPtr, + objv[2]); + if (indexPtr1 == NULL) { + result = TCL_ERROR; + goto done; + } + if (objc == 4) { + indexPtr2 = TkTextGetIndexFromObj(textPtr->interp, textPtr, + objv[3]); + if (indexPtr2 == NULL) { result = TCL_ERROR; goto done; - } - if (objc == 4) { - indexPtr2 = TkTextGetIndexFromObj(textPtr->interp, - textPtr, objv[3]); - if (indexPtr2 == NULL) { - result = TCL_ERROR; - goto done; - } - } else { - indexPtr2 = NULL; } - DeleteChars(NULL, textPtr, indexPtr1, indexPtr2, 1); } else { - int i; - /* - * Multi-index pair case requires that we prevalidate - * the indices and sort from last to first so that - * deletes occur in the exact (unshifted) text. It - * also needs to handle partial and fully overlapping - * ranges. We have to do this with multiple passes. - */ - TkTextIndex *indices, *ixStart, *ixEnd, *lastStart; - char *useIdx; + indexPtr2 = NULL; + } + DeleteChars(NULL, textPtr, indexPtr1, indexPtr2, 1); + } else { + /* + * Multi-index pair case requires that we prevalidate the + * indices and sort from last to first so that deletes occur + * in the exact (unshifted) text. It also needs to handle + * partial and fully overlapping ranges. We have to do this + * with multiple passes. + */ + + TkTextIndex *indices, *ixStart, *ixEnd, *lastStart; + char *useIdx; + int i; - objc -= 2; - objv += 2; - indices = (TkTextIndex *) + objc -= 2; + objv += 2; + indices = (TkTextIndex *) ckalloc((objc + 1) * sizeof(TkTextIndex)); - /* - * First pass verifies that all indices are valid. - */ - for (i = 0; i < objc; i++) { - CONST TkTextIndex *indexPtr = - TkTextGetIndexFromObj(interp, textPtr, objv[i]); - - if (indexPtr == NULL) { - result = TCL_ERROR; - ckfree((char *) indices); - goto done; - } - indices[i] = *indexPtr; + /* + * First pass verifies that all indices are valid. + */ + + for (i = 0; i < objc; i++) { + CONST TkTextIndex *indexPtr = + TkTextGetIndexFromObj(interp, textPtr, objv[i]); + + if (indexPtr == NULL) { + result = TCL_ERROR; + ckfree((char *) indices); + goto done; } - /* - * Pad out the pairs evenly to make later code easier. - */ - if (objc & 1) { - indices[i] = indices[i-1]; - TkTextIndexForwChars(NULL, &indices[i], 1, &indices[i], - COUNT_INDICES); - objc++; + indices[i] = *indexPtr; + } + + /* + * Pad out the pairs evenly to make later code easier. + */ + + if (objc & 1) { + indices[i] = indices[i-1]; + TkTextIndexForwChars(NULL, &indices[i], 1, &indices[i], + COUNT_INDICES); + objc++; + } + useIdx = (char *) ckalloc((unsigned) objc); + memset(useIdx, 0, (unsigned) objc); + + /* + * Do a decreasing order sort so that we delete the end ranges + * first to maintain index consistency. + */ + + qsort((VOID *) indices, (unsigned) (objc / 2), + 2 * sizeof(TkTextIndex), TextIndexSortProc); + lastStart = NULL; + + /* + * Second pass will handle bogus ranges (end < start) and + * overlapping ranges. + */ + + for (i = 0; i < objc; i += 2) { + ixStart = &indices[i]; + ixEnd = &indices[i+1]; + if (TkTextIndexCmp(ixEnd, ixStart) <= 0) { + continue; } - useIdx = (char *) ckalloc((unsigned) objc); - memset(useIdx, 0, (unsigned) objc); - /* - * Do a decreasing order sort so that we delete the end - * ranges first to maintain index consistency. - */ - qsort((VOID *) indices, (unsigned) (objc / 2), - 2 * sizeof(TkTextIndex), TextIndexSortProc); - lastStart = NULL; - /* - * Second pass will handle bogus ranges (end < start) and - * overlapping ranges. - */ - for (i = 0; i < objc; i += 2) { - ixStart = &indices[i]; - ixEnd = &indices[i+1]; - if (TkTextIndexCmp(ixEnd, ixStart) <= 0) { + if (lastStart) { + if (TkTextIndexCmp(ixStart, lastStart) == 0) { + /* + * Start indices were equal, and the sort placed + * the longest range first, so skip this one. + */ + continue; - } - if (lastStart) { - if (TkTextIndexCmp(ixStart, lastStart) == 0) { - /* - * Start indices were equal, and the sort - * placed the longest range first, so - * skip this one. - */ + } else if (TkTextIndexCmp(lastStart, ixEnd) < 0) { + /* + * The next pair has a start range before the end + * point of the last range. Constrain the delete + * range, but use the pointer values. + */ + + *ixEnd = *lastStart; + if (TkTextIndexCmp(ixEnd, ixStart) <= 0) { continue; - } else if (TkTextIndexCmp(lastStart, ixEnd) < 0) { - /* - * The next pair has a start range before - * the end point of the last range. - * Constrain the delete range, but use - * the pointer values. - */ - *ixEnd = *lastStart; - if (TkTextIndexCmp(ixEnd, ixStart) <= 0) { - continue; - } } } - lastStart = ixStart; - useIdx[i] = 1; } - /* - * Final pass take the input from the previous and - * deletes the ranges which are flagged to be - * deleted. - */ - for (i = 0; i < objc; i += 2) { - if (useIdx[i]) { - /* - * We don't need to check the return value - * because all indices are preparsed above. - */ - DeleteChars(NULL, textPtr, &indices[i], - &indices[i+1], 1); - } + lastStart = ixStart; + useIdx[i] = 1; + } + + /* + * Final pass take the input from the previous and deletes the + * ranges which are flagged to be deleted. + */ + + for (i = 0; i < objc; i += 2) { + if (useIdx[i]) { + /* + * We don't need to check the return value because all + * indices are preparsed above. + */ + + DeleteChars(NULL, textPtr, &indices[i], &indices[i+1], + 1); } - ckfree((char *) indices); } + ckfree((char *) indices); } - break; } - case TEXT_DLINEINFO: { - int x, y, width, height, base; - CONST TkTextIndex *indexPtr; - - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "index"); - result = TCL_ERROR; - goto done; - } - indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); - if (indexPtr == NULL) { - result = TCL_ERROR; - goto done; - } - if (TkTextDLineInfo(textPtr, indexPtr, &x, &y, &width, - &height, &base) == 0) { - Tcl_Obj *listObj = Tcl_NewListObj(0, NULL); - - Tcl_ListObjAppendElement(interp, listObj, - Tcl_NewIntObj(x)); - Tcl_ListObjAppendElement(interp, listObj, - Tcl_NewIntObj(y)); - Tcl_ListObjAppendElement(interp, listObj, - Tcl_NewIntObj(width)); - Tcl_ListObjAppendElement(interp, listObj, - Tcl_NewIntObj(height)); - Tcl_ListObjAppendElement(interp, listObj, - Tcl_NewIntObj(base)); - - Tcl_SetObjResult(interp, listObj); - } - break; + break; + case TEXT_DLINEINFO: { + int x, y, width, height, base; + CONST TkTextIndex *indexPtr; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "index"); + result = TCL_ERROR; + goto done; } - case TEXT_DUMP: { - result = TextDumpCmd(textPtr, interp, objc, objv); - break; + indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); + if (indexPtr == NULL) { + result = TCL_ERROR; + goto done; } - case TEXT_EDIT: { - result = TextEditCmd(textPtr, interp, objc, objv); - break; + if (TkTextDLineInfo(textPtr, indexPtr, &x, &y, &width, &height, + &base) == 0) { + Tcl_Obj *listObj = Tcl_NewListObj(0, NULL); + + Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(x)); + Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(y)); + Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(width)); + Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(height)); + Tcl_ListObjAppendElement(interp, listObj, Tcl_NewIntObj(base)); + + Tcl_SetObjResult(interp, listObj); } - case TEXT_GET: { - Tcl_Obj *objPtr = NULL; - int i, found = 0, visible = 0; - CONST char *name; - int length; - - if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, - "?-displaychars? ?--? index1 ?index2 ...?"); - result = TCL_ERROR; - goto done; + break; + } + case TEXT_DUMP: + result = TextDumpCmd(textPtr, interp, objc, objv); + break; + case TEXT_EDIT: + result = TextEditCmd(textPtr, interp, objc, objv); + break; + case TEXT_GET: { + Tcl_Obj *objPtr = NULL; + int i, found = 0, visible = 0; + CONST char *name; + int length; + + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, + "?-displaychars? ?--? index1 ?index2 ...?"); + result = TCL_ERROR; + goto done; + } + + /* + * Simple, restrictive argument parsing. The only options are -- and + * -displaychars (or any unique prefix). + */ + + i = 2; + if (objc > 3) { + name = Tcl_GetStringFromObj(objv[i], &length); + if (length > 1 && name[0] == '-') { + if (strncmp("-displaychars", name, (unsigned)length)==0) { + i++; + visible = 1; + name = Tcl_GetStringFromObj(objv[i], &length); + } + if ((i < objc-1) && (length == 2) && !strcmp("--", name)) { + i++; + } } - - /* - * Simple, restrictive argument parsing. The only options are -- - * and -displaychars (or any unique prefix). - */ - i = 2; - if (objc > 3) { - name = Tcl_GetStringFromObj(objv[i], &length); - if (length > 1 && name[0] == '-') { - if (strncmp("-displaychars", name, (unsigned)length)==0) { - i++; - visible = 1; - name = Tcl_GetStringFromObj(objv[i], &length); - } - if ((i < objc-1) && (length == 2) - && (strcmp("--", name) == 0)) { - i++; - } + } + + for (; i < objc; i += 2) { + CONST TkTextIndex *index1Ptr, *index2Ptr; + TkTextIndex index2; + + index1Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[i]); + if (index1Ptr == NULL) { + if (objPtr) { + Tcl_DecrRefCount(objPtr); } + result = TCL_ERROR; + goto done; } - for (; i < objc; i += 2) { - CONST TkTextIndex *index1Ptr, *index2Ptr; - TkTextIndex index2; - - index1Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[i]); - if (index1Ptr == NULL) { + + if (i+1 == objc) { + TkTextIndexForwChars(NULL, index1Ptr, 1, &index2, + COUNT_INDICES); + index2Ptr = &index2; + } else { + index2Ptr = TkTextGetIndexFromObj(interp, textPtr, objv[i+1]); + if (index2Ptr == NULL) { if (objPtr) { Tcl_DecrRefCount(objPtr); } result = TCL_ERROR; goto done; } - if (i+1 == objc) { - TkTextIndexForwChars(NULL, index1Ptr, - 1, &index2, COUNT_INDICES); - index2Ptr = &index2; + } + + if (TkTextIndexCmp(index1Ptr, index2Ptr) < 0) { + /* + * We want to move the text we get from the window into the + * result, but since this could in principle be a megabyte or + * more, we want to do it efficiently! + */ + + Tcl_Obj *get = TextGetText(textPtr, index1Ptr, index2Ptr, + visible); + + found++; + if (found == 1) { + Tcl_SetObjResult(interp, get); } else { - index2Ptr = TkTextGetIndexFromObj(interp, textPtr, - objv[i+1]); - if (index2Ptr == NULL) { - if (objPtr) { - Tcl_DecrRefCount(objPtr); - } - result = TCL_ERROR; - goto done; - } - } - if (TkTextIndexCmp(index1Ptr, index2Ptr) < 0) { - /* - * We want to move the text we get from the window - * into the result, but since this could in principle - * be a megabyte or more, we want to do it - * efficiently! - */ - Tcl_Obj *get = TextGetText(textPtr, index1Ptr, - index2Ptr, visible); - found++; - if (found == 1) { - Tcl_SetObjResult(interp, get); - } else { - if (found == 2) { - /* - * Move the first item we put into the result into - * the first element of the list object. - */ - objPtr = Tcl_NewObj(); - Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_GetObjResult(interp)); - } - Tcl_ListObjAppendElement(NULL, objPtr, get); + if (found == 2) { + /* + * Move the first item we put into the result into the + * first element of the list object. + */ + + objPtr = Tcl_NewObj(); + Tcl_ListObjAppendElement(NULL, objPtr, + Tcl_GetObjResult(interp)); } + Tcl_ListObjAppendElement(NULL, objPtr, get); } } - if (found > 1) { - Tcl_SetObjResult(interp, objPtr); - } - break; } - case TEXT_IMAGE: { - result = TkTextImageCmd(textPtr, interp, objc, objv); - break; + if (found > 1) { + Tcl_SetObjResult(interp, objPtr); + } + break; + } + case TEXT_IMAGE: + result = TkTextImageCmd(textPtr, interp, objc, objv); + break; + case TEXT_INDEX: { + CONST TkTextIndex *indexPtr; + + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "index"); + result = TCL_ERROR; + goto done; } - case TEXT_INDEX: { - CONST TkTextIndex *indexPtr; - if (objc != 3) { - Tcl_WrongNumArgs(interp, 2, objv, "index"); - result = TCL_ERROR; - goto done; - } - - indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); - if (indexPtr == NULL) { - result = TCL_ERROR; - goto done; - } - Tcl_SetObjResult(interp, TkTextNewIndexObj(textPtr, indexPtr)); - break; + indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); + if (indexPtr == NULL) { + result = TCL_ERROR; + goto done; } - case TEXT_INSERT: { - CONST TkTextIndex *indexPtr; + Tcl_SetObjResult(interp, TkTextNewIndexObj(textPtr, indexPtr)); + break; + } + case TEXT_INSERT: { + CONST TkTextIndex *indexPtr; - if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, - "index chars ?tagList chars tagList ...?"); - result = TCL_ERROR; - goto done; - } - indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); - if (indexPtr == NULL) { - result = TCL_ERROR; - goto done; - } - if (textPtr->state == TK_TEXT_STATE_NORMAL) { - result = TextInsertCmd(NULL, textPtr, interp, - objc-3, objv+3, - indexPtr, 1); - } - break; + if (objc < 4) { + Tcl_WrongNumArgs(interp, 2, objv, + "index chars ?tagList chars tagList ...?"); + result = TCL_ERROR; + goto done; } - case TEXT_MARK: { - result = TkTextMarkCmd(textPtr, interp, objc, objv); - break; + indexPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); + if (indexPtr == NULL) { + result = TCL_ERROR; + goto done; } - case TEXT_PEER: { - result = TextPeerCmd(textPtr, interp, objc, objv); - break; + if (textPtr->state == TK_TEXT_STATE_NORMAL) { + result = TextInsertCmd(NULL, textPtr, interp, objc-3, objv+3, + indexPtr, 1); + } + break; + } + case TEXT_MARK: + result = TkTextMarkCmd(textPtr, interp, objc, objv); + break; + case TEXT_PEER: + result = TextPeerCmd(textPtr, interp, objc, objv); + break; + case TEXT_REPLACE: { + CONST TkTextIndex *indexFromPtr, *indexToPtr; + + if (objc < 5) { + Tcl_WrongNumArgs(interp, 2, objv, + "index1 index2 chars ?tagList chars tagList ...?"); + result = TCL_ERROR; + goto done; + } + indexFromPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); + if (indexFromPtr == NULL) { + result = TCL_ERROR; + goto done; } - case TEXT_REPLACE: { - CONST TkTextIndex *indexFromPtr, *indexToPtr; + indexToPtr = TkTextGetIndexFromObj(interp, textPtr, objv[3]); + if (indexToPtr == NULL) { + result = TCL_ERROR; + goto done; + } + if (TkTextIndexCmp(indexFromPtr, indexToPtr) > 0) { + Tcl_AppendResult(interp, "Index \"", Tcl_GetString(objv[3]), + "\" before \"", Tcl_GetString(objv[2]), + "\" in the text", NULL); + result = TCL_ERROR; + goto done; + } + if (textPtr->state == TK_TEXT_STATE_NORMAL) { + int lineNum, byteIndex; + TkTextIndex index; - if (objc < 5) { - Tcl_WrongNumArgs(interp, 2, objv, - "index1 index2 chars ?tagList chars tagList ...?"); - result = TCL_ERROR; - goto done; - } - indexFromPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); - if (indexFromPtr == NULL) { - result = TCL_ERROR; - goto done; - } - indexToPtr = TkTextGetIndexFromObj(interp, textPtr, objv[3]); - if (indexToPtr == NULL) { - result = TCL_ERROR; - goto done; - } - if (TkTextIndexCmp(indexFromPtr, indexToPtr) > 0) { - Tcl_AppendResult(interp, "Index \"", Tcl_GetString(objv[3]), - "\" before \"", Tcl_GetString(objv[2]), - "\" in the text.", NULL); - result = TCL_ERROR; - goto done; - } - if (textPtr->state == TK_TEXT_STATE_NORMAL) { - int lineNum, byteIndex; - TkTextIndex index; + /* + * The 'replace' operation is quite complex to do correctly, + * because we want a number of criteria to hold: + * + * 1. The insertion point shouldn't move, unless it is within the + * deleted range. In this case it should end up after the new + * text. + * + * 2. The window should not change the text it shows - should not + * scroll vertically - unless the result of the replace is + * that the insertion position which used to be on-screen is + * now off-screen. + */ + + byteIndex = textPtr->topIndex.byteIndex; + lineNum = TkBTreeLinesTo(textPtr, textPtr->topIndex.linePtr); + + TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index); + if ((TkTextIndexCmp(indexFromPtr, &index) < 0) + && (TkTextIndexCmp(indexToPtr, &index) > 0)) { /* - * The 'replace' operation is quite complex to do - * correctly, because we want a number of criteria - * to hold: - * - * 1. The insertion point shouldn't move, unless - * it is within the deleted range. In this case - * it should end up after the new text. - * - * 2. The window should not change the text it - * shows -- should not scroll vertically -- unless - * the result of the replace is that the insertion - * position which used to be on-screen is now - * off-screen. + * The insertion point is inside the range to be replaced, so + * we have to do some calculations to ensure it doesn't move + * unnecessarily. */ - byteIndex = textPtr->topIndex.byteIndex; - lineNum = TkBTreeLinesTo(textPtr, textPtr->topIndex.linePtr); - TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, - &index); - if ((TkTextIndexCmp(indexFromPtr, &index) < 0) - && (TkTextIndexCmp(indexToPtr, &index) > 0)) { - /* - * The insertion point is inside the range to be - * replaced, so we have to do some calculations to - * ensure it doesn't move unnecessarily. - */ - int deleteInsertOffset, insertLength, j; - - insertLength = 0; - for (j = 4; j < objc; j += 2) { - insertLength += Tcl_GetCharLength(objv[j]); - } - - /* - * Calculate 'deleteInsertOffset' as an offset we - * will apply to the insertion point after this - * operation. - */ - deleteInsertOffset = CountIndices(textPtr, indexFromPtr, - &index, COUNT_CHARS); - if (deleteInsertOffset > insertLength) { - deleteInsertOffset = insertLength; - } - - result = TextReplaceCmd(textPtr, interp, - indexFromPtr, indexToPtr, - objc, objv, 0); - - if (result == TCL_OK) { - /* - * Move the insertion position to the correct - * place - */ - TkTextIndexForwChars(NULL, indexFromPtr, - deleteInsertOffset, - &index, COUNT_INDICES); - TkBTreeUnlinkSegment(textPtr->insertMarkPtr, - textPtr->insertMarkPtr->body.mark.linePtr); - TkBTreeLinkSegment(textPtr->insertMarkPtr, &index); - } - } else { - result = TextReplaceCmd(textPtr, interp, - indexFromPtr, indexToPtr, - objc, objv, 1); + int deleteInsertOffset, insertLength, j; + + insertLength = 0; + for (j = 4; j < objc; j += 2) { + insertLength += Tcl_GetCharLength(objv[j]); + } + + /* + * Calculate 'deleteInsertOffset' as an offset we will apply + * to the insertion point after this operation. + */ + + deleteInsertOffset = CountIndices(textPtr, indexFromPtr, + &index, COUNT_CHARS); + if (deleteInsertOffset > insertLength) { + deleteInsertOffset = insertLength; } + + result = TextReplaceCmd(textPtr, interp, indexFromPtr, + indexToPtr, objc, objv, 0); + if (result == TCL_OK) { - /* - * Now ensure the top-line is in the right - * place + /* + * Move the insertion position to the correct place. */ - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, - textPtr, lineNum, - byteIndex, &index); - TkTextSetYView(textPtr, &index, TK_TEXT_NOPIXELADJUST); + + TkTextIndexForwChars(NULL, indexFromPtr, + deleteInsertOffset, &index, COUNT_INDICES); + TkBTreeUnlinkSegment(textPtr->insertMarkPtr, + textPtr->insertMarkPtr->body.mark.linePtr); + TkBTreeLinkSegment(textPtr->insertMarkPtr, &index); } + } else { + result = TextReplaceCmd(textPtr, interp, indexFromPtr, + indexToPtr, objc, objv, 1); + } + if (result == TCL_OK) { + /* + * Now ensure the top-line is in the right place. + */ + + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, + lineNum, byteIndex, &index); + TkTextSetYView(textPtr, &index, TK_TEXT_NOPIXELADJUST); } - break; - } - case TEXT_SCAN: { - result = TkTextScanCmd(textPtr, interp, objc, objv); - break; - } - case TEXT_SEARCH: { - result = TextSearchCmd(textPtr, interp, objc, objv); - break; - } - case TEXT_SEE: { - result = TkTextSeeCmd(textPtr, interp, objc, objv); - break; - } - case TEXT_TAG: { - result = TkTextTagCmd(textPtr, interp, objc, objv); - break; - } - case TEXT_WINDOW: { - result = TkTextWindowCmd(textPtr, interp, objc, objv); - break; - } - case TEXT_XVIEW: { - result = TkTextXviewCmd(textPtr, interp, objc, objv); - break; - } - case TEXT_YVIEW: { - result = TkTextYviewCmd(textPtr, interp, objc, objv); - break; } - } - - done: + break; + } + case TEXT_SCAN: + result = TkTextScanCmd(textPtr, interp, objc, objv); + break; + case TEXT_SEARCH: + result = TextSearchCmd(textPtr, interp, objc, objv); + break; + case TEXT_SEE: + result = TkTextSeeCmd(textPtr, interp, objc, objv); + break; + case TEXT_TAG: + result = TkTextTagCmd(textPtr, interp, objc, objv); + break; + case TEXT_WINDOW: + result = TkTextWindowCmd(textPtr, interp, objc, objv); + break; + case TEXT_XVIEW: + result = TkTextXviewCmd(textPtr, interp, objc, objv); + break; + case TEXT_YVIEW: + result = TkTextYviewCmd(textPtr, interp, objc, objv); + break; + } + + done: textPtr->refCount--; if (textPtr->refCount == 0) { ckfree((char *) textPtr); @@ -1502,12 +1490,11 @@ TextWidgetObjCmd(clientData, interp, objc, objv) * * SharedTextObjCmd -- * - * This procedure is invoked to process commands on the shared - * portion of a text widget. Currently it is not actually exported - * as a Tcl command, and is only used internally to process parts - * of undo/redo scripts. See the user documentation for 'text' for - * details on what it does - the only subcommands it currently - * supports are 'insert' and 'delete'. + * This function is invoked to process commands on the shared portion of + * a text widget. Currently it is not actually exported as a Tcl command, + * and is only used internally to process parts of undo/redo scripts. + * See the user documentation for 'text' for details on what it does - + * the only subcommands it currently supports are 'insert' and 'delete'. * * Results: * A standard Tcl result. @@ -1520,8 +1507,7 @@ TextWidgetObjCmd(clientData, interp, objc, objv) static int SharedTextObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Information about shared test - * B-tree. */ + ClientData clientData; /* Information about shared test B-tree. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ @@ -1529,14 +1515,14 @@ SharedTextObjCmd(clientData, interp, objc, objv) register TkSharedText *sharedPtr = (TkSharedText *) clientData; int result = TCL_OK; int index; - + static CONST char *optionStrings[] = { - "delete", "insert", (char *) NULL + "delete", "insert", (char *) NULL }; enum options { TEXT_DELETE, TEXT_INSERT }; - + if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg ...?"); return TCL_ERROR; @@ -1548,65 +1534,64 @@ SharedTextObjCmd(clientData, interp, objc, objv) } switch ((enum options) index) { - case TEXT_DELETE: { - if (objc < 3) { - Tcl_WrongNumArgs(interp, 2, objv, "index1 ?index2 ...?"); - result = TCL_ERROR; - goto done; + case TEXT_DELETE: + if (objc < 3) { + Tcl_WrongNumArgs(interp, 2, objv, "index1 ?index2 ...?"); + return TCL_ERROR; + } + if (objc < 5) { + /* + * Simple case requires no predetermination of indices. + */ + + TkTextIndex index1; + + /* + * Parse the starting and stopping indices. + */ + + result = TkTextSharedGetObjIndex(interp, sharedPtr, objv[2], + &index1); + if (result != TCL_OK) { + return result; } - if (objc < 5) { - /* - * Simple case requires no predetermination of indices. - */ - TkTextIndex index1; - - /* - * Parse the starting and stopping indices. - */ + if (objc == 4) { + TkTextIndex index2; - result = TkTextSharedGetObjIndex(interp, sharedPtr, - objv[2], &index1); + result = TkTextSharedGetObjIndex(interp, sharedPtr, objv[3], + &index2); if (result != TCL_OK) { - goto done; - } - if (objc == 4) { - TkTextIndex index2; - result = TkTextSharedGetObjIndex(interp, sharedPtr, - objv[3], &index2); - if (result != TCL_OK) { - goto done; - } - DeleteChars(sharedPtr, NULL, &index1, &index2, 1); - } else { - DeleteChars(sharedPtr, NULL, &index1, NULL, 1); + return result; } + DeleteChars(sharedPtr, NULL, &index1, &index2, 1); } else { - /* Too many arguments */ - result = TCL_ERROR; + DeleteChars(sharedPtr, NULL, &index1, NULL, 1); } - break; + return TCL_OK; + } else { + /* Too many arguments */ + return TCL_ERROR; } - case TEXT_INSERT: { - TkTextIndex index1; - if (objc < 4) { - Tcl_WrongNumArgs(interp, 2, objv, - "index chars ?tagList chars tagList ...?"); - result = TCL_ERROR; - goto done; - } - result = TkTextSharedGetObjIndex(interp, sharedPtr, - objv[2], &index1); - if (result != TCL_OK) { - goto done; - } - result = TextInsertCmd(sharedPtr, NULL, interp, objc-3, objv+3, - &index1, 1); - break; + break; + case TEXT_INSERT: { + TkTextIndex index1; + + if (objc < 4) { + Tcl_WrongNumArgs(interp, 2, objv, + "index chars ?tagList chars tagList ...?"); + return TCL_ERROR; } + result = TkTextSharedGetObjIndex(interp, sharedPtr, objv[2], + &index1); + if (result != TCL_OK) { + return result; + } + return TextInsertCmd(sharedPtr, NULL, interp, objc-3, objv+3, &index1, + 1); + } + default: + return TCL_OK; } - - done: - return result; } /* @@ -1614,9 +1599,8 @@ SharedTextObjCmd(clientData, interp, objc, objv) * * TextPeerCmd -- * - * This procedure is invoked to process the "text peer" Tcl - * command. See the user documentation for details on what it - * does. + * This function is invoked to process the "text peer" Tcl command. See + * the user documentation for details on what it does. * * Results: * A standard Tcl result. @@ -1629,16 +1613,16 @@ SharedTextObjCmd(clientData, interp, objc, objv) static int TextPeerCmd(textPtr, interp, objc, objv) - TkText *textPtr; /* Information about text widget. */ + TkText *textPtr; /* Information about text widget. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ { Tk_Window tkwin = textPtr->tkwin; int index; - + static CONST char *peerOptionStrings[] = { - "create", "names", (char *) NULL + "create", "names", (char *) NULL }; enum peerOptions { PEER_CREATE, PEER_NAMES @@ -1648,35 +1632,35 @@ TextPeerCmd(textPtr, interp, objc, objv) Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); return TCL_ERROR; } - - if (Tcl_GetIndexFromObj(interp, objv[2], peerOptionStrings, - "peer option", 0, &index) != TCL_OK) { + + if (Tcl_GetIndexFromObj(interp, objv[2], peerOptionStrings, + "peer option", 0, &index) != TCL_OK) { return TCL_ERROR; } - + switch ((enum peerOptions)index) { - case PEER_CREATE: { - if (objc < 4) { - Tcl_WrongNumArgs(interp, 3, objv, "pathName ?options?"); - return TCL_ERROR; - } - return CreateWidget(textPtr->sharedTextPtr, tkwin, - interp, textPtr, objc-2, objv+2); + case PEER_CREATE: + if (objc < 4) { + Tcl_WrongNumArgs(interp, 3, objv, "pathName ?options?"); + return TCL_ERROR; } - case PEER_NAMES: { - TkText *tPtr = textPtr->sharedTextPtr->peers; - if (objc > 3) { - Tcl_WrongNumArgs(interp, 3, objv, NULL); - return TCL_ERROR; - } - while (tPtr != NULL) { - if (tPtr != textPtr) { - Tcl_AppendElement(interp, Tk_PathName(tPtr->tkwin)); - } - tPtr = tPtr->next; + return CreateWidget(textPtr->sharedTextPtr, tkwin, interp, textPtr, + objc-2, objv+2); + case PEER_NAMES: { + TkText *tPtr = textPtr->sharedTextPtr->peers; + + if (objc > 3) { + Tcl_WrongNumArgs(interp, 3, objv, NULL); + return TCL_ERROR; + } + while (tPtr != NULL) { + if (tPtr != textPtr) { + Tcl_AppendElement(interp, Tk_PathName(tPtr->tkwin)); } + tPtr = tPtr->next; } } + } return TCL_OK; } @@ -1686,7 +1670,7 @@ TextPeerCmd(textPtr, interp, objc, objv) * * TextReplaceCmd -- * - * This procedure is invoked to process part of the "replace" widget + * This function is invoked to process part of the "replace" widget * command for text widgets. * * Results: @@ -1694,53 +1678,55 @@ TextPeerCmd(textPtr, interp, objc, objv) * * Side effects: * See the user documentation. - * - * If 'viewUpdate' is false, then textPtr->topIndex may no longer - * be a valid index after this function returns. The caller is - * responsible for ensuring a correct index is in place. + * + * If 'viewUpdate' is false, then textPtr->topIndex may no longer be a + * valid index after this function returns. The caller is responsible for + * ensuring a correct index is in place. * *---------------------------------------------------------------------- */ static int -TextReplaceCmd(textPtr, interp, indexFromPtr, indexToPtr, - objc, objv, viewUpdate) - TkText *textPtr; /* Information about text widget. */ - Tcl_Interp *interp; /* Current interpreter. */ - CONST TkTextIndex *indexFromPtr;/* Index from which to replace */ - CONST TkTextIndex *indexToPtr; /* Index to which to replace */ - int objc; /* Number of arguments. */ - Tcl_Obj *CONST objv[]; /* Argument objects. */ - int viewUpdate; /* Update vertical view if set. */ +TextReplaceCmd(textPtr, interp, indexFromPtr, indexToPtr, objc, objv, + viewUpdate) + TkText *textPtr; /* Information about text widget. */ + Tcl_Interp *interp; /* Current interpreter. */ + CONST TkTextIndex *indexFromPtr; + /* Index from which to replace */ + CONST TkTextIndex *indexToPtr; + /* Index to which to replace */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ + int viewUpdate; /* Update vertical view if set. */ { - int result; /* - * Perform the deletion and insertion, but ensure - * no undo-separator is placed between the two - * operations. Since we are using the helper procedures - * 'DeleteChars' and 'TextInsertCmd' we have to pretend - * that the autoSeparators setting is off, so that we don't - * get an undo-separator between the delete and insert. + * Perform the deletion and insertion, but ensure no undo-separator is + * placed between the two operations. Since we are using the helper + * functions 'DeleteChars' and 'TextInsertCmd' we have to pretend that the + * autoSeparators setting is off, so that we don't get an undo-separator + * between the delete and insert. */ + int origAutoSep = textPtr->sharedTextPtr->autoSeparators; + int result; if (textPtr->sharedTextPtr->undo) { textPtr->sharedTextPtr->autoSeparators = 0; - if (origAutoSep - && textPtr->sharedTextPtr->lastEditMode != TK_TEXT_EDIT_REPLACE) { + if (origAutoSep && + textPtr->sharedTextPtr->lastEditMode != TK_TEXT_EDIT_REPLACE) { TkUndoInsertUndoSeparator(textPtr->sharedTextPtr->undoStack); } } DeleteChars(NULL, textPtr, indexFromPtr, indexToPtr, viewUpdate); - result = TextInsertCmd(NULL, textPtr, interp, objc-4, objv+4, - indexFromPtr, viewUpdate); + result = TextInsertCmd(NULL, textPtr, interp, objc-4, objv+4, + indexFromPtr, viewUpdate); if (textPtr->sharedTextPtr->undo) { - textPtr->sharedTextPtr->lastEditMode = TK_TEXT_EDIT_REPLACE; + textPtr->sharedTextPtr->lastEditMode = TK_TEXT_EDIT_REPLACE; textPtr->sharedTextPtr->autoSeparators = origAutoSep; } - + return result; } @@ -1749,13 +1735,13 @@ TextReplaceCmd(textPtr, interp, indexFromPtr, indexToPtr, * * TextIndexSortProc -- * - * This procedure is called by qsort when sorting an array of - * indices in *decreasing* order (last to first). + * This function is called by qsort when sorting an array of indices in + * *decreasing* order (last to first). * * Results: - * The return value is -1 if the first argument should be before - * the second element, 0 if it's equivalent, and 1 if it should be - * after the second element. + * The return value is -1 if the first argument should be before the + * second element, 0 if it's equivalent, and 1 if it should be after the + * second element. * * Side effects: * None. @@ -1774,9 +1760,10 @@ TextIndexSortProc(first, second) if (cmp == 0) { /* * If the first indices were equal, we want the second index of the - * pair also to be the greater. Use pointer magic to access the - * second index pair. + * pair also to be the greater. Use pointer magic to access the second + * index pair. */ + cmp = TkTextIndexCmp(&pair1[0], &pair2[0]); } if (cmp > 0) { @@ -1792,20 +1779,20 @@ TextIndexSortProc(first, second) * * DestroyText -- * - * This procedure is invoked when we receive a destroy event - * to clean up the internal structure of a text widget. We will - * free up most of the internal structure and delete the - * associated Tcl command. If there are no outstanding - * references to the widget, we also free up the textPtr itself. - * + * This function is invoked when we receive a destroy event to clean up + * the internal structure of a text widget. We will free up most of the + * internal structure and delete the associated Tcl command. If there are + * no outstanding references to the widget, we also free up the textPtr + * itself. + * * The widget has already been flagged as deleted. * * Results: * None. * * Side effects: - * Either everything or almost everything associated with the - * text is freed up. + * Either everything or almost everything associated with the text is + * freed up. * *---------------------------------------------------------------------- */ @@ -1818,22 +1805,22 @@ DestroyText(textPtr) Tcl_HashEntry *hPtr; TkTextTag *tagPtr; TkSharedText *sharedTextPtr = textPtr->sharedTextPtr; - + /* - * Free up all the stuff that requires special handling. We have - * already called let Tk_FreeConfigOptions to handle all the standard - * option-related stuff (and so none of that exists when we are - * called). Special note: free up display-related information before - * deleting the B-tree, since display-related stuff may refer to - * stuff in the B-tree. + * Free up all the stuff that requires special handling. We have already + * called let Tk_FreeConfigOptions to handle all the standard + * option-related stuff (and so none of that exists when we are called). + * Special note: free up display-related information before deleting the + * B-tree, since display-related stuff may refer to stuff in the B-tree. */ TkTextFreeDInfo(textPtr); textPtr->dInfoPtr = NULL; - + /* * Remove ourselves from the peer list */ + if (sharedTextPtr->peers == textPtr) { sharedTextPtr->peers = textPtr->next; } else { @@ -1847,52 +1834,55 @@ DestroyText(textPtr) } } - /* - * Always clean up the widget-specific tags first. Common tags - * (i.e. most) will only be cleaned up when the shared structure - * is cleaned up. - * - * We also need to clean up widget-specific marks ('insert', - * 'current'), since otherwise marks will never disappear from - * the B-tree. + /* + * Always clean up the widget-specific tags first. Common tags (i.e. most) + * will only be cleaned up when the shared structure is cleaned up. + * + * We also need to clean up widget-specific marks ('insert', 'current'), + * since otherwise marks will never disappear from the B-tree. */ - + TkTextDeleteTag(textPtr, textPtr->selTagPtr); TkBTreeUnlinkSegment(textPtr->insertMarkPtr, - textPtr->insertMarkPtr->body.mark.linePtr); + textPtr->insertMarkPtr->body.mark.linePtr); ckfree((char *) textPtr->insertMarkPtr); TkBTreeUnlinkSegment(textPtr->currentMarkPtr, - textPtr->currentMarkPtr->body.mark.linePtr); + textPtr->currentMarkPtr->body.mark.linePtr); ckfree((char *) textPtr->currentMarkPtr); - /* - * Now we've cleaned up everything of relevance to us in the B-tree, - * so we disassociate outselves from it. - * - * When the refCount reaches zero, it's time to clean up - * the shared portion of the text widget - */ + /* + * Now we've cleaned up everything of relevance to us in the B-tree, so we + * disassociate outselves from it. + * + * When the refCount reaches zero, it's time to clean up the shared + * portion of the text widget + */ + sharedTextPtr->refCount--; - + if (sharedTextPtr->refCount > 0) { TkBTreeRemoveClient(sharedTextPtr->tree, textPtr); - - /* Free up any embedded windows which belong to this widget. */ + + /* + * Free up any embedded windows which belong to this widget. + */ + for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->windowTable, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { TkTextEmbWindowClient *loop; TkTextSegment *ewPtr = (TkTextSegment *) Tcl_GetHashValue(hPtr); - + loop = ewPtr->body.ew.clients; if (loop->textPtr == textPtr) { ewPtr->body.ew.clients = loop->next; TkTextWinFreeClient(hPtr, loop); } else { TkTextEmbWindowClient *client = ewPtr->body.ew.clients; + client = loop->next; while (client != NULL) { if (client->textPtr == textPtr) { - loop->next = client->next; + loop->next = client->next; TkTextWinFreeClient(hPtr, client); break; } else { @@ -1903,19 +1893,22 @@ DestroyText(textPtr) } } } else { - /* - * No need to call 'TkBTreeRemoveClient' first, since this - * will do everything in one go, more quickly. + /* + * No need to call 'TkBTreeRemoveClient' first, since this will do + * everything in one go, more quickly. */ + TkBTreeDestroy(sharedTextPtr->tree); - + for (hPtr = Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); - /* - * No need to use 'TkTextDeleteTag' since we've already - * removed the B-tree completely + + /* + * No need to use 'TkTextDeleteTag' since we've already removed + * the B-tree completely */ + TkTextFreeTag(textPtr, tagPtr); } Tcl_DeleteHashTable(&sharedTextPtr->tagTable); @@ -1925,15 +1918,15 @@ DestroyText(textPtr) } Tcl_DeleteHashTable(&sharedTextPtr->markTable); TkUndoFreeStack(sharedTextPtr->undoStack); - + Tcl_DeleteHashTable(&sharedTextPtr->windowTable); Tcl_DeleteHashTable(&sharedTextPtr->imageTable); - + if (sharedTextPtr->bindingTable != NULL) { Tk_DeleteBindingTable(sharedTextPtr->bindingTable); } } - + if (textPtr->tabArrayPtr != NULL) { ckfree((char *) textPtr->tabArrayPtr); } @@ -1945,7 +1938,7 @@ DestroyText(textPtr) textPtr->refCount--; Tcl_DeleteCommandFromToken(textPtr->interp, textPtr->widgetCmd); if (textPtr->refCount == 0) { - ckfree((char *) textPtr); + ckfree((char *) textPtr); } } @@ -1954,18 +1947,16 @@ DestroyText(textPtr) * * ConfigureText -- * - * This procedure is called to process an objv/objc list, plus - * the Tk option database, in order to configure (or - * reconfigure) a text widget. + * This function is called to process an objv/objc list, plus the Tk + * option database, in order to configure (or reconfigure) a text widget. * * Results: - * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then the interp's result contains an error message. + * The return value is a standard Tcl result. If TCL_ERROR is returned, + * then the interp's result contains an error message. * * Side effects: - * Configuration information, such as text string, colors, font, - * etc. get set for textPtr; old resources get freed, if there - * were any. + * Configuration information, such as text string, colors, font, etc. get + * set for textPtr; old resources get freed, if there were any. * *---------------------------------------------------------------------- */ @@ -1973,8 +1964,8 @@ DestroyText(textPtr) static int ConfigureText(interp, textPtr, objc, objv) Tcl_Interp *interp; /* Used for error reporting. */ - register TkText *textPtr; /* Information about widget; may or may - * not already have values for some fields. */ + register TkText *textPtr; /* Information about widget; may or may not + * already have values for some fields. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ { @@ -1987,32 +1978,34 @@ ConfigureText(interp, textPtr, objc, objv) return TCL_ERROR; } - /* - * Copy down shared flags + /* + * Copy down shared flags. */ + textPtr->sharedTextPtr->undo = textPtr->undo; textPtr->sharedTextPtr->maxUndo = textPtr->maxUndo; textPtr->sharedTextPtr->autoSeparators = textPtr->autoSeparators; - TkUndoSetDepth(textPtr->sharedTextPtr->undoStack, - textPtr->sharedTextPtr->maxUndo); + TkUndoSetDepth(textPtr->sharedTextPtr->undoStack, + textPtr->sharedTextPtr->maxUndo); /* - * A few other options also need special processing, such as parsing - * the geometry and setting the background from a 3-D border. + * A few other options also need special processing, such as parsing the + * geometry and setting the background from a 3-D border. */ Tk_SetBackgroundFromBorder(textPtr->tkwin, textPtr->border); if (mask & TK_TEXT_LINE_RANGE) { int start, end, current; - - /* - * Line start and/or end have been adjusted. We need to validate - * the first displayed line and arrange for re-layout. + + /* + * Line start and/or end have been adjusted. We need to validate the + * first displayed line and arrange for re-layout. */ + TkBTreeClientRangeChanged(textPtr, textPtr->charHeight); - + if (textPtr->start != NULL) { start = TkBTreeLinesTo(NULL, textPtr->start); } else { @@ -2024,7 +2017,8 @@ ConfigureText(interp, textPtr, objc, objv) end = TkBTreeNumLines(textPtr->sharedTextPtr->tree, NULL); } if (start > end) { - Tcl_AppendResult(interp, "-startline must be less than or equal to -endline", NULL); + Tcl_AppendResult(interp, + "-startline must be less than or equal to -endline", NULL); Tk_RestoreSavedOptions(&savedOptions); return TCL_ERROR; } @@ -2033,22 +2027,25 @@ ConfigureText(interp, textPtr, objc, objv) TkTextSearch search; TkTextIndex index1, first, last; int selChanged = 0; - - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, - start, 0, &index1); + + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, start, 0, + &index1); TkTextSetYView(textPtr, &index1, 0); - /* - * We may need to adjust the selection. So we have to - * check whether the "sel" tag was applied to anything - * outside the current start,end. + + /* + * We may need to adjust the selection. So we have to check + * whether the "sel" tag was applied to anything outside the + * current start,end. */ - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, 0, 0, &first); - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, - TkBTreeNumLines(textPtr->sharedTextPtr->tree, NULL), - 0, &last); + + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, 0, 0, + &first); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, NULL, + TkBTreeNumLines(textPtr->sharedTextPtr->tree, NULL), + &last); TkBTreeStartSearch(&first, &last, textPtr->selTagPtr, &search); - if (!TkBTreeCharTagged(&first, textPtr->selTagPtr) - && !TkBTreeNextTag(&search)) { + if (!TkBTreeCharTagged(&first, textPtr->selTagPtr) + && !TkBTreeNextTag(&search)) { /* Nothing tagged with "sel" */ } else { int line = TkBTreeLinesTo(NULL, search.curIndex.linePtr); @@ -2056,26 +2053,28 @@ ConfigureText(interp, textPtr, objc, objv) selChanged = 1; } else { TkTextLine *linePtr = search.curIndex.linePtr; + while (TkBTreeNextTag(&search)) { linePtr = search.curIndex.linePtr; } line = TkBTreeLinesTo(NULL, linePtr); if (line >= end) { - selChanged = 1; + selChanged = 1; } } } if (selChanged) { - /* - * Send an event that the selection has changed, and - * abort any partial-selections in progress. + /* + * Send an event that the selection has changed, and abort any + * partial-selections in progress. */ + TkTextSelectionEvent(textPtr); textPtr->abortSelections = 1; } } } - + /* * Don't allow negative spacings. */ @@ -2109,11 +2108,10 @@ ConfigureText(interp, textPtr, objc, objv) } /* - * Make sure that configuration options are properly mirrored - * between the widget record and the "sel" tags. NOTE: we don't - * have to free up information during the mirroring; old - * information was freed when it was replaced in the widget - * record. + * Make sure that configuration options are properly mirrored between the + * widget record and the "sel" tags. NOTE: we don't have to free up + * information during the mirroring; old information was freed when it was + * replaced in the widget record. */ textPtr->selTagPtr->border = textPtr->selBorder; @@ -2160,9 +2158,11 @@ ConfigureText(interp, textPtr, objc, objv) TkTextSearch search; TkTextIndex first, last; - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0, &first); - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), 0, &last); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0, + &first); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, + TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), + 0, &last); TkBTreeStartSearch(&first, &last, textPtr->selTagPtr, &search); if (TkBTreeCharTagged(&first, textPtr->selTagPtr) || TkBTreeNextTag(&search)) { @@ -2183,8 +2183,8 @@ ConfigureText(interp, textPtr, objc, objv) } /* - * Register the desired geometry for the window, and arrange for - * the window to be redisplayed. + * Register the desired geometry for the window, and arrange for the + * window to be redisplayed. */ if (textPtr->width <= 0) { @@ -2203,21 +2203,21 @@ ConfigureText(interp, textPtr, objc, objv) * * TextWorldChangedCallback -- * - * This procedure is called when the world has changed in some - * way and the widget needs to recompute all its graphics contexts - * and determine its new geometry. + * This function is called when the world has changed in some way and the + * widget needs to recompute all its graphics contexts and determine its + * new geometry. * * Results: - * None. + * None. * * Side effects: - * Configures all tags in the Text with a empty objc/objv, for - * the side effect of causing all the items to recompute their - * geometry and to be redisplayed. + * Configures all tags in the Text with a empty objc/objv, for the side + * effect of causing all the items to recompute their geometry and to be + * redisplayed. * *--------------------------------------------------------------------------- */ - + static void TextWorldChangedCallback(instanceData) ClientData instanceData; /* Information about widget. */ @@ -2233,30 +2233,29 @@ TextWorldChangedCallback(instanceData) * * TextWorldChanged -- * - * This procedure is called when the world has changed in some - * way and the widget needs to recompute all its graphics contexts - * and determine its new geometry. + * This function is called when the world has changed in some way and the + * widget needs to recompute all its graphics contexts and determine its + * new geometry. * * Results: - * None. + * None. * * Side effects: - * Configures all tags in the Text with a empty objc/objv, for - * the side effect of causing all the items to recompute their - * geometry and to be redisplayed. + * Configures all tags in the Text with a empty objc/objv, for the side + * effect of causing all the items to recompute their geometry and to be + * redisplayed. * *--------------------------------------------------------------------------- */ - + static void TextWorldChanged(textPtr, mask) TkText *textPtr; /* Information about widget. */ - int mask; /* OR'd collection of bits showing what - * has changed */ + int mask; /* OR'd collection of bits showing what has changed */ { Tk_FontMetrics fm; int border; - + textPtr->charWidth = Tk_TextWidth(textPtr->tkfont, "0", 1); if (textPtr->charWidth <= 0) { textPtr->charWidth = 1; @@ -2269,15 +2268,13 @@ TextWorldChanged(textPtr, mask) } border = textPtr->borderWidth + textPtr->highlightWidth; Tk_GeometryRequest(textPtr->tkwin, - textPtr->width * textPtr->charWidth - + 2*textPtr->padX + 2*border, - textPtr->height * (fm.linespace + textPtr->spacing1 - + textPtr->spacing3) + textPtr->width * textPtr->charWidth + 2*textPtr->padX + 2*border, + textPtr->height* (fm.linespace+textPtr->spacing1+textPtr->spacing3) + 2*textPtr->padY + 2*border); - Tk_SetInternalBorderEx(textPtr->tkwin, - border + textPtr->padX, border + textPtr->padX, - border + textPtr->padY, border + textPtr->padY); + Tk_SetInternalBorderEx(textPtr->tkwin, + border + textPtr->padX, border + textPtr->padX, + border + textPtr->padY, border + textPtr->padY); if (textPtr->setGrid) { Tk_SetGrid(textPtr->tkwin, textPtr->width, textPtr->height, textPtr->charWidth, textPtr->charHeight); @@ -2293,16 +2290,16 @@ TextWorldChanged(textPtr, mask) * * TextEventProc -- * - * This procedure is invoked by the Tk dispatcher on - * structure changes to a text. For texts with 3D - * borders, this procedure is also invoked for exposures. + * This function is invoked by the Tk dispatcher on structure changes to + * a text. For texts with 3D borders, this function is also invoked for + * exposures. * * Results: * None. * * Side effects: - * When the window gets deleted, internal structures get - * cleaned up. When it gets exposed, it is redisplayed. + * When the window gets deleted, internal structures get cleaned up. + * When it gets exposed, it is redisplayed. * *-------------------------------------------------------------- */ @@ -2323,8 +2320,9 @@ TextEventProc(clientData, eventPtr) if ((textPtr->prevWidth != Tk_Width(textPtr->tkwin)) || (textPtr->prevHeight != Tk_Height(textPtr->tkwin))) { int mask = 0; + if (textPtr->prevWidth != Tk_Width(textPtr->tkwin)) { - mask = TK_TEXT_LINE_GEOMETRY; + mask = TK_TEXT_LINE_GEOMETRY; } TkTextRelayoutWindow(textPtr, mask); textPtr->prevWidth = Tk_Width(textPtr->tkwin); @@ -2333,12 +2331,12 @@ TextEventProc(clientData, eventPtr) } else if (eventPtr->type == DestroyNotify) { /* * NOTE: we must zero out selBorder, selBorderWidthPtr and - * selFgColorPtr: they are duplicates of information in the - * "sel" tag, which will be freed up when we delete all tags. - * Hence we don't want the automatic config options freeing - * process to delete them as well. + * selFgColorPtr: they are duplicates of information in the "sel" tag, + * which will be freed up when we delete all tags. Hence we don't want + * the automatic config options freeing process to delete them as + * well. */ - + textPtr->selBorder = NULL; textPtr->selBorderWidthPtr = NULL; textPtr->selBorderWidth = 0; @@ -2349,24 +2347,23 @@ TextEventProc(clientData, eventPtr) } if (!(textPtr->flags & OPTIONS_FREED)) { Tk_FreeConfigOptions((char *) textPtr, textPtr->optionTable, - textPtr->tkwin); + textPtr->tkwin); textPtr->flags |= OPTIONS_FREED; } textPtr->flags |= DESTROYED; - - /* - * Call 'DestroyTest' to handle the deletion for us. The - * actual textPtr may still exist after this, if there are - * some outstanding references. But we have flagged it - * as DESTROYED just above, so nothing will try to make use - * of it very extensively. + + /* + * Call 'DestroyTest' to handle the deletion for us. The actual + * textPtr may still exist after this, if there are some outstanding + * references. But we have flagged it as DESTROYED just above, so + * nothing will try to make use of it very extensively. */ + DestroyText(textPtr); } else if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { if (eventPtr->xfocus.detail == NotifyInferior - || eventPtr->xfocus.detail == NotifyAncestor - || eventPtr->xfocus.detail == NotifyNonlinear - ) { + || eventPtr->xfocus.detail == NotifyAncestor + || eventPtr->xfocus.detail == NotifyNonlinear) { Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler); if (eventPtr->type == FocusIn) { textPtr->flags |= GOT_FOCUS | INSERT_ON; @@ -2380,18 +2377,21 @@ TextEventProc(clientData, eventPtr) textPtr->insertBlinkHandler = (Tcl_TimerToken) NULL; } if (textPtr->inactiveSelBorder != textPtr->selBorder) { - TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr, 1); + TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr, + 1); } TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index); TkTextIndexForwChars(NULL, &index, 1, &index2, COUNT_INDICES); - /* - * While we wish to redisplay, no heights have changed, so - * no need to call TkTextInvalidateLineMetrics + + /* + * While we wish to redisplay, no heights have changed, so no need + * to call TkTextInvalidateLineMetrics */ + TkTextChanged(NULL, textPtr, &index, &index2); if (textPtr->highlightWidth > 0) { TkTextRedrawRegion(textPtr, 0, 0, textPtr->highlightWidth, - textPtr->highlightWidth); + textPtr->highlightWidth); } } } @@ -2402,9 +2402,9 @@ TextEventProc(clientData, eventPtr) * * TextCmdDeletedProc -- * - * 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. + * This function 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. @@ -2423,10 +2423,10 @@ TextCmdDeletedProc(clientData) Tk_Window tkwin = textPtr->tkwin; /* - * This procedure could be invoked either because the window was - * destroyed and the command was then deleted (in which this flag is - * already set) or because the command was deleted, and then this - * procedure destroys the widget. + * This function could be invoked either because the window was destroyed + * and the command was then deleted (in which this flag is already set) or + * because the command was deleted, and then this function destroys the + * widget. */ if (!(textPtr->flags & DESTROYED)) { @@ -2444,18 +2444,18 @@ TextCmdDeletedProc(clientData) * * InsertChars -- * - * This procedure implements most of the functionality of the - * "insert" widget command. + * This function implements most of the functionality of the "insert" + * widget command. * * Results: * The length of the inserted string. * * Side effects: - * The characters in "stringPtr" get added to the text just before - * the character indicated by "indexPtr". - * - * If 'viewUpdate' is true, we may adjust the window - * contents' y-position, and scrollbar setting. + * The characters in "stringPtr" get added to the text just before the + * character indicated by "indexPtr". + * + * If 'viewUpdate' is true, we may adjust the window contents' + * y-position, and scrollbar setting. * *---------------------------------------------------------------------- */ @@ -2464,58 +2464,56 @@ static int InsertChars(sharedTextPtr, textPtr, indexPtr, stringPtr, viewUpdate) TkSharedText *sharedTextPtr; TkText *textPtr; /* Overall information about text widget. */ - TkTextIndex *indexPtr; /* Where to insert new characters. May be - * modified if the index is not valid - * for insertion (e.g. if at "end"). */ + TkTextIndex *indexPtr; /* Where to insert new characters. May be + * modified if the index is not valid for + * insertion (e.g. if at "end"). */ Tcl_Obj *stringPtr; /* Null-terminated string containing new * information to add to text. */ - int viewUpdate; /* Update the view if set */ + int viewUpdate; /* Update the view if set */ { int lineIndex, length; TkText *tPtr; int *lineAndByteIndex; int resetViewCount; int pixels[2*PIXEL_CLIENTS]; - + CONST char *string = Tcl_GetStringFromObj(stringPtr, &length); if (sharedTextPtr == NULL) { sharedTextPtr = textPtr->sharedTextPtr; } - + /* - * Don't allow insertions on the last (dummy) line of the text. - * This is the only place in this function where the indexPtr is - * modified. + * Don't allow insertions on the last (dummy) line of the text. This is + * the only place in this function where the indexPtr is modified. */ lineIndex = TkBTreeLinesTo(textPtr, indexPtr->linePtr); if (lineIndex == TkBTreeNumLines(sharedTextPtr->tree, textPtr)) { lineIndex--; - TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, lineIndex, - 1000000, indexPtr); + TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, lineIndex, 1000000, + indexPtr); } - + /* - * Notify the display module that lines are about to change, then do - * the insertion. If the insertion occurs on the top line of the - * widget (textPtr->topIndex), then we have to recompute topIndex - * after the insertion, since the insertion could invalidate it. + * Notify the display module that lines are about to change, then do the + * insertion. If the insertion occurs on the top line of the widget + * (textPtr->topIndex), then we have to recompute topIndex after the + * insertion, since the insertion could invalidate it. */ resetViewCount = 0; if (sharedTextPtr->refCount > PIXEL_CLIENTS) { - lineAndByteIndex = (int*)ckalloc(sizeof(int)* - 2*sharedTextPtr->refCount); + lineAndByteIndex = (int *) + ckalloc(sizeof(int) * 2 * sharedTextPtr->refCount); } else { lineAndByteIndex = pixels; } - for (tPtr = sharedTextPtr->peers; tPtr != NULL ; - tPtr = tPtr->next) { + for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) { lineAndByteIndex[resetViewCount] = -1; if (indexPtr->linePtr == tPtr->topIndex.linePtr) { - lineAndByteIndex[resetViewCount] = - TkBTreeLinesTo(tPtr, indexPtr->linePtr); + lineAndByteIndex[resetViewCount] = + TkBTreeLinesTo(tPtr, indexPtr->linePtr); lineAndByteIndex[resetViewCount+1] = tPtr->topIndex.byteIndex; if (lineAndByteIndex[resetViewCount+1] > indexPtr->byteIndex) { lineAndByteIndex[resetViewCount+1] += length; @@ -2523,11 +2521,11 @@ InsertChars(sharedTextPtr, textPtr, indexPtr, stringPtr, viewUpdate) } resetViewCount += 2; } - + TkTextChanged(sharedTextPtr, NULL, indexPtr, indexPtr); - + sharedTextPtr->stateEpoch++; - + TkBTreeInsertChars(sharedTextPtr->tree, indexPtr, string); /* @@ -2535,33 +2533,31 @@ InsertChars(sharedTextPtr, textPtr, indexPtr, stringPtr, viewUpdate) */ if (sharedTextPtr->undo) { - TkTextIndex toIndex; - - if (sharedTextPtr->autoSeparators && - sharedTextPtr->lastEditMode != TK_TEXT_EDIT_INSERT) { - TkUndoInsertUndoSeparator(sharedTextPtr->undoStack); - } - - sharedTextPtr->lastEditMode = TK_TEXT_EDIT_INSERT; + TkTextIndex toIndex; + + if (sharedTextPtr->autoSeparators && + sharedTextPtr->lastEditMode != TK_TEXT_EDIT_INSERT) { + TkUndoInsertUndoSeparator(sharedTextPtr->undoStack); + } + + sharedTextPtr->lastEditMode = TK_TEXT_EDIT_INSERT; TkTextIndexForwBytes(textPtr, indexPtr, length, &toIndex); TextPushUndoAction(textPtr, stringPtr, 1, indexPtr, &toIndex); } - + UpdateDirtyFlag(sharedTextPtr); resetViewCount = 0; - for (tPtr = sharedTextPtr->peers; tPtr != NULL ; - tPtr = tPtr->next) { + for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) { if (lineAndByteIndex[resetViewCount] != -1) { if ((tPtr != textPtr) || viewUpdate) { TkTextIndex newTop; - TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, - lineAndByteIndex[resetViewCount], - 0, &newTop); - TkTextIndexForwBytes(tPtr, &newTop, - lineAndByteIndex[resetViewCount+1], - &newTop); + + TkTextMakeByteIndex(sharedTextPtr->tree, tPtr, + lineAndByteIndex[resetViewCount], 0, &newTop); + TkTextIndexForwBytes(tPtr, &newTop, + lineAndByteIndex[resetViewCount+1], &newTop); TkTextSetYView(tPtr, &newTop, 0); } } @@ -2570,17 +2566,19 @@ InsertChars(sharedTextPtr, textPtr, indexPtr, stringPtr, viewUpdate) if (sharedTextPtr->refCount > PIXEL_CLIENTS) { ckfree((char*)lineAndByteIndex); } - + /* * Invalidate any selection retrievals in progress. */ - for (tPtr = sharedTextPtr->peers; tPtr != NULL ; - tPtr = tPtr->next) { + for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) { tPtr->abortSelections = 1; } - - /* For convenience, return the length of the string */ + + /* + * For convenience, return the length of the string. + */ + return length; } @@ -2589,10 +2587,10 @@ InsertChars(sharedTextPtr, textPtr, indexPtr, stringPtr, viewUpdate) * * TextPushUndoAction -- * - * Shared by insert and delete actions. Stores the appropriate - * scripts into our undo stack. We will add a single refCount to - * the 'undoString' object, so, if it previously had a refCount of - * zero, the caller should not free it. + * Shared by insert and delete actions. Stores the appropriate scripts + * into our undo stack. We will add a single refCount to the 'undoString' + * object, so, if it previously had a refCount of zero, the caller should + * not free it. * * Results: * None. @@ -2605,50 +2603,66 @@ InsertChars(sharedTextPtr, textPtr, indexPtr, stringPtr, viewUpdate) static void TextPushUndoAction (textPtr, undoString, insert, index1Ptr, index2Ptr) - TkText *textPtr; /* Overall information about text widget. */ - Tcl_Obj *undoString; /* New text */ - int insert; /* 1 if insert, else delete */ - CONST TkTextIndex *index1Ptr;/* Index describing first location */ - CONST TkTextIndex *index2Ptr;/* Index describing second location */ + TkText *textPtr; /* Overall information about text widget. */ + Tcl_Obj *undoString; /* New text */ + int insert; /* 1 if insert, else delete */ + CONST TkTextIndex *index1Ptr; + /* Index describing first location */ + CONST TkTextIndex *index2Ptr; + /* Index describing second location */ { TkUndoSubAtom *iAtom, *dAtom; - - /* Create the helpers */ + + /* + * Create the helpers. + */ + Tcl_Obj *seeInsertObj = Tcl_NewObj(); Tcl_Obj *markSet1InsertObj = Tcl_NewObj(); Tcl_Obj *markSet2InsertObj = Tcl_NewObj(); Tcl_Obj *insertCmdObj = Tcl_NewObj(); Tcl_Obj *deleteCmdObj = Tcl_NewObj(); - - /* Get the index positions */ + + /* + * Get the index positions. + */ + Tcl_Obj *index1Obj = TkTextNewIndexObj(NULL, index1Ptr); Tcl_Obj *index2Obj = TkTextNewIndexObj(NULL, index2Ptr); - /* These need refCounts, because they are used more than once below */ + /* + * These need refCounts, because they are used more than once below. + */ + Tcl_IncrRefCount(seeInsertObj); Tcl_IncrRefCount(index1Obj); Tcl_IncrRefCount(index2Obj); - Tcl_ListObjAppendElement(NULL, seeInsertObj, - Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1)); - Tcl_ListObjAppendElement(NULL, seeInsertObj, Tcl_NewStringObj("see",3)); - Tcl_ListObjAppendElement(NULL, seeInsertObj, Tcl_NewStringObj("insert",6)); - - Tcl_ListObjAppendElement(NULL, markSet1InsertObj, - Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1)); - Tcl_ListObjAppendElement(NULL, markSet1InsertObj, - Tcl_NewStringObj("mark",4)); - Tcl_ListObjAppendElement(NULL, markSet1InsertObj, - Tcl_NewStringObj("set",3)); - Tcl_ListObjAppendElement(NULL, markSet1InsertObj, - Tcl_NewStringObj("insert",6)); + Tcl_ListObjAppendElement(NULL, seeInsertObj, + Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1)); + Tcl_ListObjAppendElement(NULL, seeInsertObj, Tcl_NewStringObj("see", 3)); + Tcl_ListObjAppendElement(NULL, seeInsertObj, + Tcl_NewStringObj("insert", 6)); + + Tcl_ListObjAppendElement(NULL, markSet1InsertObj, + Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1)); + Tcl_ListObjAppendElement(NULL, markSet1InsertObj, + Tcl_NewStringObj("mark", 4)); + Tcl_ListObjAppendElement(NULL, markSet1InsertObj, + Tcl_NewStringObj("set", 3)); + Tcl_ListObjAppendElement(NULL, markSet1InsertObj, + Tcl_NewStringObj("insert", 6)); markSet2InsertObj = Tcl_DuplicateObj(markSet1InsertObj); Tcl_ListObjAppendElement(NULL, markSet1InsertObj, index1Obj); Tcl_ListObjAppendElement(NULL, markSet2InsertObj, index2Obj); Tcl_ListObjAppendElement(NULL, insertCmdObj, Tcl_NewStringObj("insert",6)); Tcl_ListObjAppendElement(NULL, insertCmdObj, index1Obj); - /* Only use of 'undoString' is here */ + + /* + * Only use of 'undoString' is here. + */ + Tcl_ListObjAppendElement(NULL, insertCmdObj, undoString); Tcl_ListObjAppendElement(NULL, deleteCmdObj, Tcl_NewStringObj("delete",6)); @@ -2657,47 +2671,42 @@ TextPushUndoAction (textPtr, undoString, insert, index1Ptr, index2Ptr) /* * Note: we don't wish to use textPtr->widgetCmd in these callbacks - * because if we delete the textPtr, but peers still exist, we will - * then have references to a non-existent Tcl_Command in the undo - * stack, which will lead to crashes later. Also, the behaviour of - * the widget wrt bindings (%W substitutions) always uses the widget - * path name, so there is no good reason the undo stack should do - * otherwise. - * - * For the 'insert' and 'delete' actions, we have to register a - * functional callback, because these actions are defined to - * operate on the underlying data shared by all peers. + * because if we delete the textPtr, but peers still exist, we will then + * have references to a non-existent Tcl_Command in the undo stack, which + * will lead to crashes later. Also, the behaviour of the widget wrt + * bindings (%W substitutions) always uses the widget path name, so there + * is no good reason the undo stack should do otherwise. + * + * For the 'insert' and 'delete' actions, we have to register a functional + * callback, because these actions are defined to operate on the + * underlying data shared by all peers. */ - iAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, - (ClientData)textPtr->sharedTextPtr, - insertCmdObj, NULL); + + iAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, + (ClientData)textPtr->sharedTextPtr, insertCmdObj, NULL); TkUndoMakeCmdSubAtom(NULL, markSet2InsertObj, iAtom); TkUndoMakeCmdSubAtom(NULL, seeInsertObj, iAtom); - - dAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, - (ClientData)textPtr->sharedTextPtr, - deleteCmdObj, NULL); + + dAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, + (ClientData)textPtr->sharedTextPtr, deleteCmdObj, NULL); TkUndoMakeCmdSubAtom(NULL, markSet1InsertObj, dAtom); TkUndoMakeCmdSubAtom(NULL, seeInsertObj, dAtom); - + Tcl_DecrRefCount(seeInsertObj); Tcl_DecrRefCount(index1Obj); Tcl_DecrRefCount(index2Obj); - /* - * Depending whether the action is to insert or delete, we provide - * the appropriate second and third arguments to TkUndoPushAction. - * (The first is the 'actionCommand', and the second the - * 'revertCommand'). + /* + * Depending whether the action is to insert or delete, we provide the + * appropriate second and third arguments to TkUndoPushAction. (The first + * is the 'actionCommand', and the second the 'revertCommand'). */ + if (insert) { - TkUndoPushAction(textPtr->sharedTextPtr->undoStack, - iAtom, dAtom); + TkUndoPushAction(textPtr->sharedTextPtr->undoStack, iAtom, dAtom); } else { - TkUndoPushAction(textPtr->sharedTextPtr->undoStack, - dAtom, iAtom); + TkUndoPushAction(textPtr->sharedTextPtr->undoStack, dAtom, iAtom); } - } /* @@ -2705,96 +2714,95 @@ TextPushUndoAction (textPtr, undoString, insert, index1Ptr, index2Ptr) * * TextUndoRedoCallback -- * - * This procedure is registered with the generic undo/redo code - * to handle 'insert' and 'delete' actions on all text widgets. - * We cannot perform those actions on any particular text widget, - * because that text widget might have been deleted by the time - * we get here. + * This function is registered with the generic undo/redo code to handle + * 'insert' and 'delete' actions on all text widgets. We cannot perform + * those actions on any particular text widget, because that text widget + * might have been deleted by the time we get here. * * Results: * A standard Tcl result. * * Side effects: - * Will insert or delete text, depending on the first word - * contained in objPtr. - * + * Will insert or delete text, depending on the first word contained in + * objPtr. + * *---------------------------------------------------------------------- */ int TextUndoRedoCallback(interp, clientData, objPtr) - Tcl_Interp *interp; /* Current interpreter. */ - ClientData clientData; /* Passed from undo code, but - * contains our shared text - * data structure. */ - Tcl_Obj *objPtr; /* Arguments of a command to - * be handled by the shared - * text data structure. */ + Tcl_Interp *interp; /* Current interpreter. */ + ClientData clientData; /* Passed from undo code, but contains our + * shared text data structure. */ + Tcl_Obj *objPtr; /* Arguments of a command to be handled by the + * shared text data structure. */ { TkSharedText *sharedPtr = (TkSharedText*)clientData; int objc; Tcl_Obj **objv; int res; TkText *textPtr; - + res = Tcl_ListObjGetElements(interp, objPtr, &objc, &objv); if (res != TCL_OK) { return res; } - /* - * If possible, use a real text widget to perform the undo/redo - * action (i.e. insertion or deletion of text). This provides - * maximum compatibility with older versions of Tk, in which the - * user may rename the text widget to allow capture of undo or - * redo actions. - * - * In particular, this sorting of capture is useful in text editors - * based on the Tk text widget, which need to know which new text - * needs re-coloring. - * - * It would be better if the text widget provided some other - * mechanism to allow capture of this information ("What has - * just changed in the text widget?"). What we have here is - * not entirely satisfactory under all circumstances. + /* + * If possible, use a real text widget to perform the undo/redo action + * (i.e. insertion or deletion of text). This provides maximum + * compatibility with older versions of Tk, in which the user may rename + * the text widget to allow capture of undo or redo actions. + * + * In particular, this sorting of capture is useful in text editors based + * on the Tk text widget, which need to know which new text needs + * re-coloring. + * + * It would be better if the text widget provided some other mechanism to + * allow capture of this information ("What has just changed in the text + * widget?"). What we have here is not entirely satisfactory under all + * circumstances. */ + textPtr = sharedPtr->peers; while (textPtr != NULL) { - if (textPtr->start == NULL && textPtr->end == NULL) { + if (textPtr->start == NULL && textPtr->end == NULL) { Tcl_Obj *cmdNameObj, *evalObj; - + evalObj = Tcl_NewObj(); Tcl_IncrRefCount(evalObj); + /* - * We might wish to use the real, current command-name - * for the widget, but this will break any code that has - * over-ridden the widget, and is expecting to observe - * the insert/delete actions which are caused by undo/redo - * operations. - * + * We might wish to use the real, current command-name for the + * widget, but this will break any code that has over-ridden the + * widget, and is expecting to observe the insert/delete actions + * which are caused by undo/redo operations. + * * cmdNameObj = Tcl_NewObj(); - * Tcl_GetCommandFullName(interp, textPtr->widgetCmd, - * cmdNameObj); - * + * Tcl_GetCommandFullName(interp, textPtr->widgetCmd, cmdNameObj); + * * While such interception is not explicitly documented as - * supported, it does occur, and so until we can provide - * some alternative mechanism for such code to do what - * it needs, we allow it to take place here. + * supported, it does occur, and so until we can provide some + * alternative mechanism for such code to do what it needs, we + * allow it to take place here. */ + cmdNameObj = Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1); Tcl_ListObjAppendElement(NULL, evalObj, cmdNameObj); Tcl_ListObjAppendList(NULL, evalObj, objPtr); res = Tcl_EvalObjEx(interp, evalObj, TCL_EVAL_GLOBAL); Tcl_DecrRefCount(evalObj); - return res; - } - textPtr = textPtr->next; + return res; + } + textPtr = textPtr->next; } + /* - * If there's no current text widget which shows everything, then - * we fall back on acting directly. This means there is no way to - * intercept from the Tcl level. + * If there's no current text widget which shows everything, then we fall + * back on acting directly. This means there is no way to intercept from + * the Tcl level. */ + return SharedTextObjCmd((ClientData)sharedPtr, interp, objc+1, objv-1); } @@ -2803,12 +2811,12 @@ TextUndoRedoCallback(interp, clientData, objPtr) * * CountIndices -- * - * This procedure implements most of the functionality of the - * "count" widget command. + * This function implements most of the functionality of the "count" + * widget command. * * Note that 'textPtr' is only used if we need to check for elided * attributes, i.e. if type is COUNT_DISPLAY_INDICES or - * COUNT_DISPLAY_CHARS. + * COUNT_DISPLAY_CHARS * * Results: * Returns the number of characters in the range. @@ -2821,23 +2829,24 @@ TextUndoRedoCallback(interp, clientData, objPtr) static int CountIndices(textPtr, indexPtr1, indexPtr2, type) - CONST TkText *textPtr; /* Overall information about text widget. */ - CONST TkTextIndex *indexPtr1;/* Index describing location of first - * character to delete. */ - CONST TkTextIndex *indexPtr2;/* Index describing location of last - * character to delete. NULL means just - * delete the one character given by - * indexPtr1. */ - TkTextCountType type; /* The kind of indices to count */ + CONST TkText *textPtr; /* Overall information about text widget. */ + CONST TkTextIndex *indexPtr1; + /* Index describing location of first + * character to delete. */ + CONST TkTextIndex *indexPtr2; + /* Index describing location of last character + * to delete. NULL means just delete the one + * character given by indexPtr1. */ + TkTextCountType type; /* The kind of indices to count */ { /* * Order the starting and stopping indices. */ int compare = TkTextIndexCmp(indexPtr1, indexPtr2); - + if (compare == 0) { - return 0; + return 0; } else if (compare > 0) { return -TkTextIndexCount(textPtr, indexPtr2, indexPtr1, type); } else { @@ -2850,39 +2859,40 @@ CountIndices(textPtr, indexPtr1, indexPtr2, type) * * DeleteChars -- * - * This procedure implements most of the functionality of the - * "delete" widget command. + * This function implements most of the functionality of the "delete" + * widget command. * * Results: * Returns a standard Tcl result, currently always TCL_OK. * * Side effects: * Characters get deleted from the text. - * - * If 'viewUpdate' is true, we may adjust the window - * contents' y-position, and scrollbar setting. - * - * If 'viewUpdate' is false, true we can guarantee that - * textPtr->topIndex points to a valid TkTextLine after this - * procedure returns. However, if 'viewUpdate' is false, then - * there is no such guarantee (topIndex.linePtr can be garbage). - * The caller is expected to take actions to ensure the topIndex - * is validated before laying out the window again. + * + * If 'viewUpdate' is true, we may adjust the window contents' + * y-position, and scrollbar setting. + * + * If 'viewUpdate' is false, true we can guarantee that textPtr->topIndex + * points to a valid TkTextLine after this function returns. However, if + * 'viewUpdate' is false, then there is no such guarantee (since + * topIndex.linePtr can be garbage). The caller is expected to take + * actions to ensure the topIndex is validated before laying out the + * window again. * *---------------------------------------------------------------------- */ static int DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) - TkSharedText *sharedTextPtr; /* Shared portion of peer widgets. */ - TkText *textPtr; /* Overall information about text widget. */ - CONST TkTextIndex *indexPtr1;/* Index describing location of first - * character to delete. */ - CONST TkTextIndex *indexPtr2;/* Index describing location of last - * character to delete. NULL means just - * delete the one character given by - * indexPtr1. */ - int viewUpdate; /* Update vertical view if set. */ + TkSharedText *sharedTextPtr;/* Shared portion of peer widgets. */ + TkText *textPtr; /* Overall information about text widget. */ + CONST TkTextIndex *indexPtr1; + /* Index describing location of first + * character to delete. */ + CONST TkTextIndex *indexPtr2; + /* Index describing location of last character + * to delete. NULL means just delete the one + * character given by indexPtr1. */ + int viewUpdate; /* Update vertical view if set. */ { int line1, line2; TkTextIndex index1, index2; @@ -2894,7 +2904,7 @@ DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) if (sharedTextPtr == NULL) { sharedTextPtr = textPtr->sharedTextPtr; } - + /* * Prepare the starting and stopping indices. */ @@ -2916,15 +2926,15 @@ DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) } /* - * The code below is ugly, but it's needed to make sure there - * is always a dummy empty line at the end of the text. If the - * final newline of the file (just before the dummy line) is being - * deleted, then back up index to just before the newline. If - * there is a newline just before the first character being deleted, - * then back up the first index too, so that an even number of lines - * gets deleted. Furthermore, remove any tags that are present on - * the newline that isn't going to be deleted after all (this simulates - * deleting the newline and then adding a "clean" one back again). + * The code below is ugly, but it's needed to make sure there is always a + * dummy empty line at the end of the text. If the final newline of the + * file (just before the dummy line) is being deleted, then back up index + * to just before the newline. If there is a newline just before the first + * character being deleted, then back up the first index too, so that an + * even number of lines gets deleted. Furthermore, remove any tags that + * are present on the newline that isn't going to be deleted after all + * (this simulates deleting the newline and then adding a "clean" one back + * again). */ line1 = TkBTreeLinesTo(textPtr, index1.linePtr); @@ -2952,71 +2962,69 @@ DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) if (line1 < line2) { /* - * We are deleting more than one line. For speed, - * we remove all tags from the range first. If we - * don't do this, the code below can (when there are - * many tags) grow non-linearly in execution time. + * We are deleting more than one line. For speed, we remove all tags + * from the range first. If we don't do this, the code below can (when + * there are many tags) grow non-linearly in execution time. */ + Tcl_HashSearch search; Tcl_HashEntry *hPtr; int i; - - for (i = 0, hPtr = Tcl_FirstHashEntry(&sharedTextPtr->tagTable, - &search); + + for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search); hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) { - TkTextTag *tagPtr; - tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); + TkTextTag *tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); + TkBTreeTag(&index1, &index2, tagPtr, 0); } + /* - * Special case for the sel tag which is not in the hash table. - * We need to do this once for each peer text widget. + * Special case for the sel tag which is not in the hash table. We + * need to do this once for each peer text widget. */ - - for (tPtr = sharedTextPtr->peers; tPtr != NULL ; - tPtr = tPtr->next) { + + for (tPtr = sharedTextPtr->peers; tPtr != NULL ; + tPtr = tPtr->next) { if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) { /* - * Send an event that the selection changed. - * This is equivalent to - * "event generate $textWidget <<Selection>>" + * Send an event that the selection changed. This is + * equivalent to: + * event generate $textWidget <<Selection>> */ TkTextSelectionEvent(textPtr); - tPtr->abortSelections = 1; } } } - + /* - * Tell the display what's about to happen so it can discard - * obsolete display information, then do the deletion. Also, - * if the deletion involves the top line on the screen, then - * we have to reset the view (the deletion will invalidate - * textPtr->topIndex). Compute what the new first character - * will be, then do the deletion, then reset the view. + * Tell the display what's about to happen so it can discard obsolete + * display information, then do the deletion. Also, if the deletion + * involves the top line on the screen, then we have to reset the view + * (the deletion will invalidate textPtr->topIndex). Compute what the new + * first character will be, then do the deletion, then reset the view. */ TkTextChanged(sharedTextPtr, NULL, &index1, &index2); - + resetViewCount = 0; if (sharedTextPtr->refCount > PIXEL_CLIENTS) { - lineAndByteIndex = (int*)ckalloc(sizeof(int)* - 2*sharedTextPtr->refCount); + lineAndByteIndex = (int *) + ckalloc(sizeof(int) * 2 * sharedTextPtr->refCount); } else { lineAndByteIndex = pixels; } - for (tPtr = sharedTextPtr->peers; tPtr != NULL ; - tPtr = tPtr->next) { + for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) { int line = 0; int byteIndex = 0; int resetView = 0; + if (TkTextIndexCmp(&index2, &tPtr->topIndex) >= 0) { if (TkTextIndexCmp(&index1, &tPtr->topIndex) <= 0) { /* - * Deletion range straddles topIndex: use the beginning - * of the range as the new topIndex. + * Deletion range straddles topIndex: use the beginning of the + * range as the new topIndex. */ resetView = 1; @@ -3024,8 +3032,8 @@ DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) byteIndex = index1.byteIndex; } else if (index1.linePtr == tPtr->topIndex.linePtr) { /* - * Deletion range starts on top line but after topIndex. - * Use the current topIndex as the new one. + * Deletion range starts on top line but after topIndex. Use + * the current topIndex as the new one. */ resetView = 1; @@ -3034,9 +3042,9 @@ DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) } } else if (index2.linePtr == tPtr->topIndex.linePtr) { /* - * Deletion range ends on top line but before topIndex. - * Figure out what will be the new character index for - * the character currently pointed to by topIndex. + * Deletion range ends on top line but before topIndex. Figure out + * what will be the new character index for the character + * currently pointed to by topIndex. */ resetView = 1; @@ -3056,17 +3064,17 @@ DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) } resetViewCount+=2; } - + /* * Push the deletion on the undo stack */ if (sharedTextPtr->undo) { Tcl_Obj *get; - + if (sharedTextPtr->autoSeparators && (sharedTextPtr->lastEditMode != TK_TEXT_EDIT_DELETE)) { - TkUndoInsertUndoSeparator(sharedTextPtr->undoStack); + TkUndoInsertUndoSeparator(sharedTextPtr->undoStack); } sharedTextPtr->lastEditMode = TK_TEXT_EDIT_DELETE; @@ -3081,20 +3089,21 @@ DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) TkBTreeDeleteChars(sharedTextPtr->tree, &index1, &index2); resetViewCount = 0; - for (tPtr = sharedTextPtr->peers; tPtr != NULL ; - tPtr = tPtr->next) { + for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) { int line = lineAndByteIndex[resetViewCount]; + if (line != -1) { int byteIndex = lineAndByteIndex[resetViewCount+1]; + if (tPtr == textPtr) { if (viewUpdate) { - TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, - line, byteIndex, &index1); + TkTextMakeByteIndex(sharedTextPtr->tree, textPtr, line, + byteIndex, &index1); TkTextSetYView(tPtr, &index1, 0); } } else { - TkTextMakeByteIndex(sharedTextPtr->tree, NULL, - line, byteIndex, &index1); + TkTextMakeByteIndex(sharedTextPtr->tree, NULL, line, byteIndex, + &index1); TkTextSetYView(tPtr, &index1, 0); } } @@ -3103,20 +3112,19 @@ DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) if (sharedTextPtr->refCount > PIXEL_CLIENTS) { ckfree((char*)lineAndByteIndex); } - + if (line1 >= line2) { - + /* - * Invalidate any selection retrievals in progress, assuming - * we didn't check for this case above. + * Invalidate any selection retrievals in progress, assuming we didn't + * check for this case above. */ - for (tPtr = sharedTextPtr->peers; tPtr != NULL ; - tPtr = tPtr->next) { + for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) { tPtr->abortSelections = 1; } } - + return TCL_OK; } @@ -3125,15 +3133,15 @@ DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) * * TextFetchSelection -- * - * This procedure is called back by Tk when the selection is - * requested by someone. It returns part or all of the selection - * in a buffer provided by the caller. + * This function is called back by Tk when the selection is requested by + * someone. It returns part or all of the selection in a buffer provided + * by the caller. * * Results: - * The return value is the number of non-NULL bytes stored - * at buffer. Buffer is filled (or partially filled) with a - * NULL-terminated string containing part or all of the selection, - * as given by offset and maxBytes. + * The return value is the number of non-NULL bytes stored at buffer. + * Buffer is filled (or partially filled) with a NULL-terminated string + * containing part or all of the selection, as given by offset and + * maxBytes. * * Side effects: * None. @@ -3143,14 +3151,13 @@ DeleteChars(sharedTextPtr, textPtr, indexPtr1, indexPtr2, viewUpdate) static int TextFetchSelection(clientData, offset, buffer, maxBytes) - ClientData clientData; /* Information about text widget. */ - int offset; /* Offset within selection of first - * character to be returned. */ - char *buffer; /* Location in which to place - * selection. */ - int maxBytes; /* Maximum number of bytes to place - * at buffer, not including terminating - * NULL character. */ + ClientData clientData; /* Information about text widget. */ + int offset; /* Offset within selection of first character + * to be returned. */ + char *buffer; /* Location in which to place selection. */ + int maxBytes; /* Maximum number of bytes to place at buffer, + * not including terminating NULL + * character. */ { register TkText *textPtr = (TkText *) clientData; TkTextIndex eof; @@ -3163,23 +3170,21 @@ TextFetchSelection(clientData, offset, buffer, maxBytes) } /* - * Find the beginning of the next range of selected text. Note: if - * the selection is being retrieved in multiple pieces (offset != 0) - * and some modification has been made to the text that affects the - * selection then reject the selection request (make 'em start over - * again). + * Find the beginning of the next range of selected text. Note: if the + * selection is being retrieved in multiple pieces (offset != 0) and some + * modification has been made to the text that affects the selection then + * reject the selection request (make 'em start over again). */ if (offset == 0) { - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - 0, 0, &textPtr->selIndex); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0, + &textPtr->selIndex); textPtr->abortSelections = 0; } else if (textPtr->abortSelections) { return 0; } - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), - 0, &eof); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, + TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), 0, &eof); TkBTreeStartSearch(&textPtr->selIndex, &eof, textPtr->selTagPtr, &search); if (!TkBTreeCharTagged(&textPtr->selIndex, textPtr->selTagPtr)) { if (!TkBTreeNextTag(&search)) { @@ -3194,8 +3199,8 @@ TextFetchSelection(clientData, offset, buffer, maxBytes) /* * Each iteration through the outer loop below scans one selected range. - * Each iteration through the inner loop scans one segment in the - * selected range. + * Each iteration through the inner loop scans one segment in the selected + * range. */ count = 0; @@ -3209,9 +3214,9 @@ TextFetchSelection(clientData, offset, buffer, maxBytes) } /* - * Copy information from character segments into the buffer - * until either we run out of space in the buffer or we get - * to the end of this range of text. + * Copy information from character segments into the buffer until + * either we run out of space in the buffer or we get to the end of + * this range of text. */ while (1) { @@ -3257,7 +3262,7 @@ TextFetchSelection(clientData, offset, buffer, maxBytes) textPtr->selIndex = search.curIndex; } - fetchDone: + fetchDone: *buffer = 0; return count; } @@ -3267,11 +3272,10 @@ TextFetchSelection(clientData, offset, buffer, maxBytes) * * TkTextLostSelection -- * - * This procedure is called back by Tk when the selection is - * grabbed away from a text widget. On Windows and Mac systems, we - * want to remember the selection for the next time the focus - * enters the window. On Unix, just remove the "sel" tag from - * everything in the widget. + * This function is called back by Tk when the selection is grabbed away + * from a text widget. On Windows and Mac systems, we want to remember + * the selection for the next time the focus enters the window. On Unix, + * just remove the "sel" tag from everything in the widget. * * Results: * None. @@ -3284,7 +3288,7 @@ TextFetchSelection(clientData, offset, buffer, maxBytes) void TkTextLostSelection(clientData) - ClientData clientData; /* Information about text widget. */ + ClientData clientData; /* Information about text widget. */ { register TkText *textPtr = (TkText *) clientData; #ifdef ALWAYS_SHOW_SELECTION @@ -3295,23 +3299,23 @@ TkTextLostSelection(clientData) } /* - * On Windows and Mac systems, we want to remember the selection - * for the next time the focus enters the window. On Unix, - * just remove the "sel" tag from everything in the widget. + * On Windows and Mac systems, we want to remember the selection for the + * next time the focus enters the window. On Unix, just remove the "sel" + * tag from everything in the widget. */ TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0, &start); - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), - 0, &end); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, + TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), 0, &end); TkTextRedrawTag(NULL, textPtr, &start, &end, textPtr->selTagPtr, 1); TkBTreeTag(&start, &end, textPtr->selTagPtr, 0); #endif - + /* - * Send an event that the selection changed. This is equivalent to - * "event generate $textWidget <<Selection>>" + * Send an event that the selection changed. This is equivalent to: + * event generate $textWidget <<Selection>> */ + TkTextSelectionEvent(textPtr); textPtr->flags &= ~GOT_SELECTION; @@ -3322,8 +3326,8 @@ TkTextLostSelection(clientData) * * TkTextSelectionEvent -- * - * When anything relevant to the "sel" tag has been changed, - * call this procedure to generate a <<Selection>> event. + * When anything relevant to the "sel" tag has been changed, call this + * function to generate a <<Selection>> event. * * Results: * None. @@ -3334,15 +3338,17 @@ TkTextLostSelection(clientData) *---------------------------------------------------------------------- */ -void -TkTextSelectionEvent(textPtr) +void +TkTextSelectionEvent(textPtr) TkText *textPtr; { /* - * Send an event that the selection changed. This is equivalent to - * "event generate $textWidget <<Selection>>" + * Send an event that the selection changed. This is equivalent to: + * event generate $textWidget <<Selection>> */ + XEvent event; + memset((VOID *) &event, 0, sizeof(event)); event.xany.type = VirtualEvent; event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); @@ -3358,15 +3364,15 @@ TkTextSelectionEvent(textPtr) * * TextBlinkProc -- * - * This procedure is called as a timer handler to blink the - * insertion cursor off and on. + * This function is called as a timer handler to blink the insertion + * cursor off and on. * * Results: * None. * * Side effects: - * The cursor gets turned on or off, redisplay gets invoked, - * and this procedure reschedules itself. + * The cursor gets turned on or off, redisplay gets invoked, and this + * function reschedules itself. * *---------------------------------------------------------------------- */ @@ -3383,10 +3389,10 @@ TextBlinkProc(clientData) !(textPtr->flags & GOT_FOCUS) || (textPtr->insertOffTime == 0)) { if ((textPtr->insertOffTime == 0) && !(textPtr->flags & INSERT_ON)) { /* - * The widget was configured to have zero offtime while - * the insertion point was not displayed. We have to - * display it once. + * The widget was configured to have zero offtime while the + * insertion point was not displayed. We have to display it once. */ + textPtr->flags |= INSERT_ON; goto redrawInsert; } @@ -3407,12 +3413,12 @@ TextBlinkProc(clientData) if (textPtr->insertCursorType) { /* Block cursor */ TkTextRedrawRegion(textPtr, x - textPtr->width / 2, y, - charWidth + textPtr->insertWidth / 2, h); + charWidth + textPtr->insertWidth / 2, h); } else { /* I-beam cursor */ TkTextRedrawRegion(textPtr, x - textPtr->insertWidth / 2, y, - textPtr->insertWidth, h); - } + textPtr->insertWidth, h); + } } } @@ -3421,8 +3427,8 @@ TextBlinkProc(clientData) * * TextInsertCmd -- * - * This procedure is invoked to process the "insert" and "replace" - * widget commands for text widgets. + * This function is invoked to process the "insert" and "replace" widget + * commands for text widgets. * * Results: * A standard Tcl result. @@ -3430,21 +3436,21 @@ TextBlinkProc(clientData) * Side effects: * See the user documentation. * - * If 'viewUpdate' is true, we may adjust the window - * contents' y-position, and scrollbar setting. - * + * If 'viewUpdate' is true, we may adjust the window contents' + * y-position, and scrollbar setting. + * *---------------------------------------------------------------------- */ static int TextInsertCmd(sharedTextPtr, textPtr, interp, objc, objv, indexPtr, viewUpdate) - TkSharedText *sharedTextPtr; /* Shared portion of peer widgets. */ - TkText *textPtr; /* Information about text widget. */ - Tcl_Interp *interp; /* Current interpreter. */ - int objc; /* Number of arguments. */ - Tcl_Obj *CONST objv[]; /* Argument objects. */ - CONST TkTextIndex *indexPtr; /* Index at which to insert */ - int viewUpdate; /* Update the view if set */ + TkSharedText *sharedTextPtr;/* Shared portion of peer widgets. */ + TkText *textPtr; /* Information about text widget. */ + Tcl_Interp *interp; /* Current interpreter. */ + int objc; /* Number of arguments. */ + Tcl_Obj *CONST objv[]; /* Argument objects. */ + CONST TkTextIndex *indexPtr;/* Index at which to insert */ + int viewUpdate; /* Update the view if set */ { TkTextIndex index1, index2; int j; @@ -3452,44 +3458,45 @@ TextInsertCmd(sharedTextPtr, textPtr, interp, objc, objv, indexPtr, viewUpdate) if (sharedTextPtr == NULL) { sharedTextPtr = textPtr->sharedTextPtr; } - + index1 = *indexPtr; - for (j = 0; j < objc; j += 2) { + for (j = 0; j < objc; j += 2) { /* - * Here we rely on this call to modify index1 if - * it is outside the acceptable range. In particular, - * if index1 is "end", it must be set to the last - * allowable index for insertion, otherwise - * subsequent tag insertions will fail. + * Here we rely on this call to modify index1 if it is outside the + * acceptable range. In particular, if index1 is "end", it must be set + * to the last allowable index for insertion, otherwise subsequent tag + * insertions will fail. */ - int length = InsertChars(sharedTextPtr, textPtr, &index1, - objv[j], viewUpdate); + + int length = InsertChars(sharedTextPtr, textPtr, &index1, objv[j], + viewUpdate); + if (objc > (j+1)) { Tcl_Obj **tagNamePtrs; TkTextTag **oldTagArrayPtr; int numTags; - + TkTextIndexForwBytes(textPtr, &index1, length, &index2); oldTagArrayPtr = TkBTreeGetTags(&index1, NULL, &numTags); if (oldTagArrayPtr != NULL) { int i; + for (i = 0; i < numTags; i++) { - TkBTreeTag(&index1, &index2, - oldTagArrayPtr[i], 0); + TkBTreeTag(&index1, &index2, oldTagArrayPtr[i], 0); } ckfree((char *) oldTagArrayPtr); } - if (Tcl_ListObjGetElements(interp, objv[j+1], - &numTags, &tagNamePtrs) - != TCL_OK) { + if (Tcl_ListObjGetElements(interp, objv[j+1], &numTags, + &tagNamePtrs) != TCL_OK) { return TCL_ERROR; } else { int i; - + for (i = 0; i < numTags; i++) { CONST char *strTag = Tcl_GetString(tagNamePtrs[i]); - TkBTreeTag(&index1, &index2, - TkTextCreateTag(textPtr, strTag, NULL), 1); + + TkBTreeTag(&index1, &index2, + TkTextCreateTag(textPtr, strTag, NULL), 1); } index1 = index2; } @@ -3503,9 +3510,8 @@ TextInsertCmd(sharedTextPtr, textPtr, interp, objc, objv, indexPtr, viewUpdate) * * TextSearchCmd -- * - * This procedure is invoked to process the "search" widget command - * for text widgets. See the user documentation for details on what - * it does. + * This function is invoked to process the "search" widget command for + * text widgets. See the user documentation for details on what it does. * * Results: * A standard Tcl result. @@ -3528,7 +3534,7 @@ TextSearchCmd(textPtr, interp, objc, objv) static CONST char *switchStrings[] = { "--", "-all", "-backwards", "-count", "-elide", "-exact", - "-forwards", "-hidden", "-nocase", "-nolinestop", + "-forwards", "-hidden", "-nocase", "-nolinestop", "-overlap", "-regexp", "-strictlimits", NULL }; enum SearchSwitches { @@ -3538,10 +3544,11 @@ TextSearchCmd(textPtr, interp, objc, objv) SEARCH_STRICTLIMITS }; - /* - * Set up the search specification, including - * the last 4 fields which are text widget specific + /* + * Set up the search specification, including the last 4 fields which are + * text widget specific. */ + searchSpec.exact = 1; searchSpec.noCase = 0; searchSpec.all = 0; @@ -3553,12 +3560,13 @@ TextSearchCmd(textPtr, interp, objc, objv) searchSpec.noLineStop = 0; searchSpec.overlap = 0; searchSpec.strictLimits = 0; - searchSpec.numLines = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr); + searchSpec.numLines = + TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr); searchSpec.clientData = (ClientData)textPtr; searchSpec.addLineProc = &TextSearchAddNextLine; searchSpec.foundMatchProc = &TextSearchFoundMatch; searchSpec.lineIndexProc = &TextSearchGetLineIndex; - + /* * Parse switches and other arguments. */ @@ -3574,6 +3582,7 @@ TextSearchCmd(textPtr, interp, objc, objv) /* * Hide the -hidden option */ + Tcl_ResetResult(interp); Tcl_AppendResult(interp, "bad switch \"", Tcl_GetString(objv[i]), "\": must be --, -all, -backward, -count, -elide, ", @@ -3600,10 +3609,12 @@ TextSearchCmd(textPtr, interp, objc, objv) return TCL_ERROR; } i++; - /* - * Assumption objv[i] isn't going to disappear on us during - * this procedure, which is fair. + + /* + * Assumption objv[i] isn't going to disappear on us during this + * function, which is fair. */ + searchSpec.varPtr = objv[i]; break; case SEARCH_ELIDE: @@ -3657,13 +3668,12 @@ TextSearchCmd(textPtr, interp, objc, objv) } /* - * Scan through all of the lines of the text circularly, starting - * at the given index. 'objv[i]' is the pattern which may be an - * exact string or a regexp pattern depending on the flags set - * above. + * Scan through all of the lines of the text circularly, starting at the + * given index. 'objv[i]' is the pattern which may be an exact string or a + * regexp pattern depending on the flags set above. */ - code = SearchPerform(interp, &searchSpec, objv[i], objv[i+1], + code = SearchPerform(interp, &searchSpec, objv[i], objv[i+1], (argsLeft == 1 ? objv[i+2] : NULL)); if (code != TCL_OK) { goto cleanup; @@ -3672,9 +3682,10 @@ TextSearchCmd(textPtr, interp, objc, objv) /* * Set the '-count' variable, if given. */ + if (searchSpec.varPtr != NULL && searchSpec.countPtr != NULL) { Tcl_IncrRefCount(searchSpec.countPtr); - if (Tcl_ObjSetVar2(interp, searchSpec.varPtr, NULL, + if (Tcl_ObjSetVar2(interp, searchSpec.varPtr, NULL, searchSpec.countPtr, TCL_LEAVE_ERR_MSG) == NULL) { code = TCL_ERROR; goto cleanup; @@ -3684,12 +3695,13 @@ TextSearchCmd(textPtr, interp, objc, objv) /* * Set the result */ + if (searchSpec.resPtr != NULL) { Tcl_SetObjResult(interp, searchSpec.resPtr); searchSpec.resPtr = NULL; } - cleanup: + cleanup: if (searchSpec.countPtr != NULL) { Tcl_DecrRefCount(searchSpec.countPtr); } @@ -3705,20 +3717,19 @@ TextSearchCmd(textPtr, interp, objc, objv) * TextSearchGetLineIndex -- * * Extract a row, text offset index position from an objPtr - * - * This means we ignore any embedded windows/images and - * elidden text (unless we are searching that). + * + * This means we ignore any embedded windows/images and elidden text + * (unless we are searching that). * * Results: - * Standard Tcl error code (with a message in the interpreter - * on error conditions). - * + * Standard Tcl error code (with a message in the interpreter on error + * conditions). + * * The offset placed in offsetPosPtr is a utf-8 char* byte index for - * exact searches, and a Unicode character index for regexp - * searches. - * - * The line number should start at zero (searches which wrap - * around assume the first line is numbered 0). + * exact searches, and a Unicode character index for regexp searches. + * + * The line number should start at zero (searches which wrap around + * assume the first line is numbered 0). * * Side effects: * None. @@ -3727,43 +3738,44 @@ TextSearchCmd(textPtr, interp, objc, objv) */ static int TextSearchGetLineIndex(interp, objPtr, searchSpecPtr, linePosPtr, offsetPosPtr) - Tcl_Interp *interp; /* For error messages */ - Tcl_Obj *objPtr; /* Contains a textual index - * like "1.2" */ - SearchSpec *searchSpecPtr; /* Contains other search - * parameters */ - int *linePosPtr; /* For returning the line number */ - int *offsetPosPtr; /* For returning the text offset in - * the line */ + Tcl_Interp *interp; /* For error messages */ + Tcl_Obj *objPtr; /* Contains a textual index like "1.2" */ + SearchSpec *searchSpecPtr; /* Contains other search parameters */ + int *linePosPtr; /* For returning the line number. */ + int *offsetPosPtr; /* For returning the text offset in the + * line. */ { CONST TkTextIndex *indexPtr; int line; TkText *textPtr = (TkText*)(searchSpecPtr->clientData); - + indexPtr = TkTextGetIndexFromObj(interp, textPtr, objPtr); if (indexPtr == NULL) { return TCL_ERROR; } - + line = TkBTreeLinesTo(textPtr, indexPtr->linePtr); if (line >= searchSpecPtr->numLines) { TkTextLine *linePtr; int count = 0; TkTextSegment *segPtr; - + line = searchSpecPtr->numLines-1; linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr, line); - /* Count the number of bytes in this line */ - for (segPtr = linePtr->segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { + + /* + * Count the number of bytes in this line. + */ + + for (segPtr=linePtr->segPtr ; segPtr!=NULL ; segPtr=segPtr->nextPtr) { count += segPtr->size; } - *offsetPosPtr = TextSearchIndexInLine(searchSpecPtr, linePtr, - count); + *offsetPosPtr = TextSearchIndexInLine(searchSpecPtr, linePtr, count); } else { - *offsetPosPtr = TextSearchIndexInLine(searchSpecPtr, - indexPtr->linePtr, indexPtr->byteIndex); + *offsetPosPtr = TextSearchIndexInLine(searchSpecPtr, indexPtr->linePtr, + indexPtr->byteIndex); } - + *linePosPtr = line; return TCL_OK; @@ -3774,15 +3786,15 @@ TextSearchGetLineIndex(interp, objPtr, searchSpecPtr, linePosPtr, offsetPosPtr) * * TextSearchIndexInLine -- * - * Find textual index of 'byteIndex' in the searchable - * characters of 'linePtr'. - * - * This means we ignore any embedded windows/images and - * elidden text (unless we are searching that). + * Find textual index of 'byteIndex' in the searchable characters of + * 'linePtr'. + * + * This means we ignore any embedded windows/images and elidden text + * (unless we are searching that). * * Results: - * The returned index is a utf-8 char* byte index for exact - * searches, and a Unicode character index for regexp searches. + * The returned index is a utf-8 char* byte index for exact searches, and + * a Unicode character index for regexp searches. * * Side effects: * None. @@ -3792,9 +3804,10 @@ TextSearchGetLineIndex(interp, objPtr, searchSpecPtr, linePosPtr, offsetPosPtr) static int TextSearchIndexInLine(searchSpecPtr, linePtr, byteIndex) - CONST SearchSpec *searchSpecPtr; /* Search parameters */ - TkTextLine *linePtr; /* The line we're looking at */ - int byteIndex; /* Index into the line */ + CONST SearchSpec *searchSpecPtr; + /* Search parameters */ + TkTextLine *linePtr; /* The line we're looking at */ + int byteIndex; /* Index into the line */ { TkTextSegment *segPtr; TkTextIndex curIndex; @@ -3805,23 +3818,21 @@ TextSearchIndexInLine(searchSpecPtr, linePtr, byteIndex) curIndex.tree = textPtr->sharedTextPtr->tree; curIndex.linePtr = linePtr; curIndex.byteIndex = 0; for (segPtr = linePtr->segPtr, leftToScan = byteIndex; - leftToScan > 0; - curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) { - if ((segPtr->typePtr == &tkTextCharType) - && (searchSpecPtr->searchElide || - !TkTextIsElided(textPtr, &curIndex, NULL))) { + leftToScan > 0; + curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) { + if ((segPtr->typePtr == &tkTextCharType) && + (searchSpecPtr->searchElide + || !TkTextIsElided(textPtr, &curIndex, NULL))) { if (leftToScan < segPtr->size) { if (searchSpecPtr->exact) { index += leftToScan; } else { index += Tcl_NumUtfChars(segPtr->body.chars, leftToScan); } + } else if (searchSpecPtr->exact) { + index += segPtr->size; } else { - if (searchSpecPtr->exact) { - index += segPtr->size; - } else { - index += Tcl_NumUtfChars(segPtr->body.chars, -1); - } + index += Tcl_NumUtfChars(segPtr->body.chars, -1); } } leftToScan -= segPtr->size; @@ -3837,18 +3848,18 @@ TextSearchIndexInLine(searchSpecPtr, linePtr, byteIndex) * Adds a line from the text widget to the object 'theLine'. * * Results: - * A pointer to the TkTextLine corresponding to the given line, - * or NULL if there was no available line. - * + * A pointer to the TkTextLine corresponding to the given line, or NULL + * if there was no available line. + * * Also 'lenPtr' (if non-NULL) is filled in with the total length of - * 'theLine' (not just what we added to it, but the length including - * what was already in there). This is in bytes for an exact search - * and in chars for a regexp search. - * - * Also 'extraLinesPtr' (if non-NULL) will have its value - * incremented by 1 for each additional logical line we have - * added because a newline is elided (this will only ever happen - * if we have chosen not to search elided text, of course). + * 'theLine' (not just what we added to it, but the length including what + * was already in there). This is in bytes for an exact search and in + * chars for a regexp search. + * + * Also 'extraLinesPtr' (if non-NULL) will have its value incremented by + * 1 for each additional logical line we have added because a newline is + * elided (this will only ever happen if we have chosen not to search + * elided text, of course). * * Side effects: * Memory may be allocated or re-allocated for theLine's string @@ -3857,26 +3868,25 @@ TextSearchIndexInLine(searchSpecPtr, linePtr, byteIndex) *---------------------------------------------------------------------- */ -static ClientData +static ClientData TextSearchAddNextLine(lineNum, searchSpecPtr, theLine, lenPtr, extraLinesPtr) - int lineNum; /* Line we must add */ - SearchSpec *searchSpecPtr; /* Search parameters */ - Tcl_Obj *theLine; /* Object to append to */ - int *lenPtr; /* For returning the total length */ - int *extraLinesPtr; /* If non-NULL, will have its value - * incremented by the number of - * additional logical lines which are - * merged into this one by newlines - * being elided */ + int lineNum; /* Line we must add */ + SearchSpec *searchSpecPtr; /* Search parameters */ + Tcl_Obj *theLine; /* Object to append to */ + int *lenPtr; /* For returning the total length */ + int *extraLinesPtr; /* If non-NULL, will have its value + * incremented by the number of additional + * logical lines which are merged into this + * one by newlines being elided */ { TkTextLine *linePtr, *thisLinePtr; TkTextIndex curIndex; TkTextSegment *segPtr; TkText *textPtr = (TkText*)(searchSpecPtr->clientData); int nothingYet = 1; - + /* - * Extract the text from the line. + * Extract the text from the line. */ linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr, lineNum); @@ -3885,24 +3895,25 @@ TextSearchAddNextLine(lineNum, searchSpecPtr, theLine, lenPtr, extraLinesPtr) } curIndex.tree = textPtr->sharedTextPtr->tree; thisLinePtr = linePtr; - + while (thisLinePtr != NULL) { int elideWraps = 0; + curIndex.linePtr = thisLinePtr; curIndex.byteIndex = 0; for (segPtr = thisLinePtr->segPtr; segPtr != NULL; curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) { - if (!searchSpecPtr->searchElide - && TkTextIsElided(textPtr, &curIndex, NULL)) { - /* - * If we reach the end of the logical line, and if we - * have at least one character in the string, then we - * continue wrapping to the next logical line. If - * there are no characters yet, then the entire line - * of characters is elided and there's no need to - * complicate matters by wrapping - we'll look at the - * next line in due course. + if (!searchSpecPtr->searchElide + && TkTextIsElided(textPtr, &curIndex, NULL)) { + /* + * If we reach the end of the logical line, and if we have at + * least one character in the string, then we continue + * wrapping to the next logical line. If there are no + * characters yet, then the entire line of characters is + * elided and there's no need to complicate matters by + * wrapping - we'll look at the next line in due course. */ + if (segPtr->nextPtr == NULL && !nothingYet) { elideWraps = 1; } @@ -3923,22 +3934,26 @@ TextSearchAddNextLine(lineNum, searchSpecPtr, theLine, lenPtr, extraLinesPtr) } thisLinePtr = TkBTreeNextLine(textPtr, thisLinePtr); if (thisLinePtr != NULL && extraLinesPtr != NULL) { - /* Tell our caller we have an extra line merged in */ + /* + * Tell our caller we have an extra line merged in. + */ + *extraLinesPtr = (*extraLinesPtr) + 1; } } - + /* - * If we're ignoring case, convert the line to lower case. - * There is no need to do this for regexp searches, since - * they handle a flag for this purpose. + * If we're ignoring case, convert the line to lower case. There is no + * need to do this for regexp searches, since they handle a flag for this + * purpose. */ + if (searchSpecPtr->exact && searchSpecPtr->noCase) { Tcl_SetObjLength(theLine, Tcl_UtfToLower(Tcl_GetString(theLine))); } - + if (lenPtr != NULL) { - if (searchSpecPtr->exact) { + if (searchSpecPtr->exact) { Tcl_GetStringFromObj(theLine, lenPtr); } else { *lenPtr = Tcl_GetCharLength(theLine); @@ -3955,38 +3970,34 @@ TextSearchAddNextLine(lineNum, searchSpecPtr, theLine, lenPtr, extraLinesPtr) * Stores information from a successful search. * * Results: - * 1 if the information was stored, 0 if the position at which - * the match was found actually falls outside the allowable - * search region (and therefore the search is actually - * complete). + * 1 if the information was stored, 0 if the position at which the match + * was found actually falls outside the allowable search region (and + * therefore the search is actually complete). * * Side effects: - * Memory may be allocated in the 'countPtr' and 'resPtr' fields - * of 'searchSpecPtr'. Each of those objects will have refCount - * zero and must eventually be freed or stored elsewhere as - * appropriate. + * Memory may be allocated in the 'countPtr' and 'resPtr' fields of + * 'searchSpecPtr'. Each of those objects will have refCount zero and + * must eventually be freed or stored elsewhere as appropriate. * *---------------------------------------------------------------------- */ -static int -TextSearchFoundMatch(lineNum, searchSpecPtr, clientData, theLine, - matchOffset, matchLength) - int lineNum; /* Line on which match was found */ - SearchSpec *searchSpecPtr; /* Search parameters */ - ClientData clientData; /* Token returned by the 'addNextLineProc', - * TextSearchAddNextLine. May be - * NULL, in which we case we must - * generate it (from lineNum) */ - Tcl_Obj *theLine; /* Text from current line, only - * accessed for exact searches, and - * is allowed to be NULL for regexp - * searches. */ - int matchOffset; /* Offset of found item in utf-8 bytes - * for exact search, Unicode chars - * for regexp */ - int matchLength; /* Length also in bytes/chars as per - * search type. */ +static int +TextSearchFoundMatch(lineNum, searchSpecPtr, clientData, theLine, matchOffset, + matchLength) + int lineNum; /* Line on which match was found. */ + SearchSpec *searchSpecPtr; /* Search parameters. */ + ClientData clientData; /* Token returned by the 'addNextLineProc', + * TextSearchAddNextLine. May be NULL, in + * which we case we must generate it (from + * lineNum). */ + Tcl_Obj *theLine; /* Text from current line, only accessed for + * exact searches, and is allowed to be NULL + * for regexp searches. */ + int matchOffset; /* Offset of found item in utf-8 bytes for + * exact search, Unicode chars for regexp */ + int matchLength; /* Length also in bytes/chars as per search + * type. */ { int numChars; int leftToScan; @@ -3996,63 +4007,70 @@ TextSearchFoundMatch(lineNum, searchSpecPtr, clientData, theLine, TkText *textPtr = (TkText*)(searchSpecPtr->clientData); if (lineNum == searchSpecPtr->stopLine) { - /* - * If the current index is on the wrong side of the stopIndex, - * then the item we just found is actually outside the acceptable - * range, and the search is over. + /* + * If the current index is on the wrong side of the stopIndex, then + * the item we just found is actually outside the acceptable range, + * and the search is over. */ - if (searchSpecPtr->backwards ^ - (matchOffset >= searchSpecPtr->stopOffset)) { + + if (searchSpecPtr->backwards ^ + (matchOffset >= searchSpecPtr->stopOffset)) { return 0; } } - + /* - * Calculate the character count, which may need augmenting - * if there are embedded windows or elidden text. + * Calculate the character count, which may need augmenting if there are + * embedded windows or elidden text. */ if (searchSpecPtr->exact) { CONST char *startOfLine = Tcl_GetString(theLine); + numChars = Tcl_NumUtfChars(startOfLine + matchOffset, matchLength); } else { numChars = matchLength; } - + /* - * The index information returned by the regular expression - * parser only considers textual information: it doesn't - * account for embedded windows, elided text (when we are not - * searching elided text) or any other non-textual info. - * Scan through the line's segments again to adjust both + * The index information returned by the regular expression parser only + * considers textual information: it doesn't account for embedded windows, + * elided text (when we are not searching elided text) or any other + * non-textual info. Scan through the line's segments again to adjust both * matchChar and matchCount. * - * We will walk through the segments of this line until we - * have either reached the end of the match or we have - * reached the end of the line. + * We will walk through the segments of this line until we have either + * reached the end of the match or we have reached the end of the line. */ linePtr = (TkTextLine *)clientData; if (linePtr == NULL) { - linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr, lineNum); + linePtr = TkBTreeFindLine(textPtr->sharedTextPtr->tree, textPtr, + lineNum); } - + curIndex.tree = textPtr->sharedTextPtr->tree; - /* Find the starting point */ + + /* + * Find the starting point. + */ + leftToScan = matchOffset; while (1) { - curIndex.linePtr = linePtr; + curIndex.linePtr = linePtr; curIndex.byteIndex = 0; - /* - * Note that we allow leftToScan to be zero because we want - * to skip over any preceding non-textual items. + + /* + * Note that we allow leftToScan to be zero because we want to skip + * over any preceding non-textual items. */ - for (segPtr = linePtr->segPtr; - leftToScan >= 0 && segPtr; segPtr = segPtr->nextPtr) { + + for (segPtr = linePtr->segPtr; leftToScan >= 0 && segPtr; + segPtr = segPtr->nextPtr) { if (segPtr->typePtr != &tkTextCharType) { matchOffset += segPtr->size; - } else if (!searchSpecPtr->searchElide - && TkTextIsElided(textPtr, &curIndex, NULL)) { + } else if (!searchSpecPtr->searchElide + && TkTextIsElided(textPtr, &curIndex, NULL)) { if (searchSpecPtr->exact) { matchOffset += segPtr->size; } else { @@ -4064,73 +4082,85 @@ TextSearchFoundMatch(lineNum, searchSpecPtr, clientData, theLine, curIndex.byteIndex += segPtr->size; } if (segPtr == NULL && leftToScan >= 0) { - /* This will only happen if we are eliding newlines */ + /* + * This will only happen if we are eliding newlines. + */ + linePtr = TkBTreeNextLine(textPtr, linePtr); if (linePtr == NULL) { - /* - * If we reach the end of the text, we have a serious - * problem, unless there's actually nothing left to look - * for. + /* + * If we reach the end of the text, we have a serious problem, + * unless there's actually nothing left to look for. */ + if (leftToScan == 0) { break; } else { Tcl_Panic("Reached end of text in a match"); } } - /* - * We've wrapped to the beginning of the next logical line, - * which has been merged with the previous one whose newline - * was elided. + + /* + * We've wrapped to the beginning of the next logical line, which + * has been merged with the previous one whose newline was elided. */ + lineNum++; matchOffset = 0; } else { break; } } - /* Calculate and store the found index in the result */ + + /* + * Calculate and store the found index in the result. + */ + if (searchSpecPtr->exact) { - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, lineNum, - matchOffset, &foundIndex); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, lineNum, + matchOffset, &foundIndex); } else { - TkTextMakeCharIndex(textPtr->sharedTextPtr->tree, textPtr, lineNum, - matchOffset, &foundIndex); + TkTextMakeCharIndex(textPtr->sharedTextPtr->tree, textPtr, lineNum, + matchOffset, &foundIndex); } + if (searchSpecPtr->all) { if (searchSpecPtr->resPtr == NULL) { searchSpecPtr->resPtr = Tcl_NewObj(); } - Tcl_ListObjAppendElement(NULL, searchSpecPtr->resPtr, + Tcl_ListObjAppendElement(NULL, searchSpecPtr->resPtr, TkTextNewIndexObj(textPtr, &foundIndex)); } else { - searchSpecPtr->resPtr = - TkTextNewIndexObj(textPtr, &foundIndex); - } - /* - * Find the end point. Here 'leftToScan' could be negative already - * as a result of the above loop if the segment we reached spanned - * the start of the string. When we add matchLength it will become - * non-negative. + searchSpecPtr->resPtr = TkTextNewIndexObj(textPtr, &foundIndex); + } + + /* + * Find the end point. Here 'leftToScan' could be negative already as a + * result of the above loop if the segment we reached spanned the start of + * the string. When we add matchLength it will become non-negative. */ + for (leftToScan += matchLength; leftToScan > 0; - curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) { + curIndex.byteIndex += segPtr->size, segPtr = segPtr->nextPtr) { if (segPtr == NULL) { - /* - * We are on the next line -- this of course should only - * ever happen with searches which have matched across - * multiple lines + /* + * We are on the next line - this of course should only ever + * happen with searches which have matched across multiple lines. */ + linePtr = TkBTreeNextLine(textPtr, linePtr); segPtr = linePtr->segPtr; curIndex.linePtr = linePtr; curIndex.byteIndex = 0; } if (segPtr->typePtr != &tkTextCharType) { - /* Anything we didn't count in the search needs adding */ + /* + * Anything we didn't count in the search needs adding. + */ + numChars += segPtr->size; continue; - } else if (!searchSpecPtr->searchElide - && TkTextIsElided(textPtr, &curIndex, NULL)) { + } else if (!searchSpecPtr->searchElide + && TkTextIsElided(textPtr, &curIndex, NULL)) { numChars += Tcl_NumUtfChars(segPtr->body.chars, -1); continue; } @@ -4140,9 +4170,11 @@ TextSearchFoundMatch(lineNum, searchSpecPtr, clientData, theLine, leftToScan -= Tcl_NumUtfChars(segPtr->body.chars, -1); } } - /* - * Now store the count result, if it is wanted + + /* + * Now store the count result, if it is wanted. */ + if (searchSpecPtr->varPtr != NULL) { Tcl_Obj *tmpPtr = Tcl_NewIntObj(numChars); if (searchSpecPtr->all) { @@ -4165,27 +4197,23 @@ TextSearchFoundMatch(lineNum, searchSpecPtr, clientData, theLine, * Parses a string description of a set of tab stops. * * Results: - * The return value is a pointer to a malloc'ed structure holding - * parsed information about the tab stops. If an error occurred - * then the return value is NULL and an error message is left in - * the interp's result. + * The return value is a pointer to a malloc'ed structure holding parsed + * information about the tab stops. If an error occurred then the return + * value is NULL and an error message is left in the interp's result. * * Side effects: - * Memory is allocated for the structure that is returned. It is - * up to the caller to free this structure when it is no longer - * needed. + * Memory is allocated for the structure that is returned. It is up to + * the caller to free this structure when it is no longer needed. * *---------------------------------------------------------------------- */ TkTextTabArray * TkTextGetTabs(interp, textPtr, stringPtr) - Tcl_Interp *interp; /* Used for error reporting. */ - TkText *textPtr; /* Information about the - * text widget. */ - Tcl_Obj *stringPtr; /* Description of the tab stops. - * See the text manual entry for - * details. */ + Tcl_Interp *interp; /* Used for error reporting. */ + TkText *textPtr; /* Information about the text widget. */ + Tcl_Obj *stringPtr; /* Description of the tab stops. See the text + * manual entry for details. */ { int objc, i, count; Tcl_Obj **objv; @@ -4193,20 +4221,19 @@ TkTextGetTabs(interp, textPtr, stringPtr) TkTextTab *tabPtr; Tcl_UniChar ch; double prevStop, lastStop; - - /* Map these strings to TkTextTabAlign values */ - + /* + * Map these strings to TkTextTabAlign values. + */ static CONST char *tabOptionStrings[] = { - "left", "right", "center", "numeric", (char *) NULL + "left", "right", "center", "numeric", (char *) NULL }; - + if (Tcl_ListObjGetElements(interp, stringPtr, &objc, &objv) != TCL_OK) { return NULL; } /* - * First find out how many entries we need to allocate in the - * tab array. + * First find out how many entries we need to allocate in the tab array. */ count = 0; @@ -4218,8 +4245,7 @@ TkTextGetTabs(interp, textPtr, stringPtr) } /* - * Parse the elements of the list one at a time to fill in the - * array. + * Parse the elements of the list one at a time to fill in the array. */ tabArrayPtr = (TkTextTabArray *) ckalloc((unsigned) @@ -4227,99 +4253,103 @@ TkTextGetTabs(interp, textPtr, stringPtr) tabArrayPtr->numTabs = 0; prevStop = 0.0; lastStop = 0.0; - for (i = 0, tabPtr = &tabArrayPtr->tabs[0]; i < objc; i++, tabPtr++) { + for (i = 0, tabPtr = &tabArrayPtr->tabs[0]; i < objc; i++, tabPtr++) { int index; - - /* - * This will round fractional pixels above 0.5 upwards, and - * otherwise downwards, to find the right integer pixel - * position. + + /* + * This will round fractional pixels above 0.5 upwards, and otherwise + * downwards, to find the right integer pixel position. */ - if (Tk_GetPixelsFromObj(interp, textPtr->tkwin, objv[i], - &tabPtr->location) != TCL_OK) { + + if (Tk_GetPixelsFromObj(interp, textPtr->tkwin, objv[i], + &tabPtr->location) != TCL_OK) { goto error; } if (tabPtr->location <= 0) { - Tcl_AppendResult(interp, - "tab stop \"", Tcl_GetString(objv[i]), - "\" is not at a positive distance", NULL); + Tcl_AppendResult(interp, "tab stop \"", Tcl_GetString(objv[i]), + "\" is not at a positive distance", NULL); goto error; } - + prevStop = lastStop; - if (Tk_GetMMFromObj(interp, textPtr->tkwin, objv[i], - &lastStop) != TCL_OK) { + if (Tk_GetMMFromObj(interp, textPtr->tkwin, objv[i], + &lastStop) != TCL_OK) { goto error; } lastStop *= WidthOfScreen(Tk_Screen(textPtr->tkwin)); lastStop /= WidthMMOfScreen(Tk_Screen(textPtr->tkwin)); - + if (i > 0 && (tabPtr->location <= (tabPtr-1)->location)) { - /* - * This tab is actually to the left of the previous - * one, which is illegal. + /* + * This tab is actually to the left of the previous one, which is + * illegal. */ + #ifdef _TK_ALLOW_DECREASING_TABS - /* - * Force the tab to be a typical character width to the - * right of the previous one, and update the 'lastStop' - * with the changed position. + /* + * Force the tab to be a typical character width to the right of + * the previous one, and update the 'lastStop' with the changed + * position. */ + if (textPtr->charWidth > 0) { - tabPtr->location = (tabPtr-1)->location + textPtr->charWidth; + tabPtr->location = (tabPtr-1)->location + textPtr->charWidth; } else { tabPtr->location = (tabPtr-1)->location + 8; } lastStop = tabPtr->location; #else - Tcl_AppendResult(interp, - "tabs must be monotonically increasing, but \"", - Tcl_GetString(objv[i]), - "\" is smaller than or equal to the previous tab", - NULL); + Tcl_AppendResult(interp, + "tabs must be monotonically increasing, but \"", + Tcl_GetString(objv[i]), + "\" is smaller than or equal to the previous tab", + NULL); goto error; -#endif +#endif /* _TK_ALLOW_DECREASING_TABS */ } - + tabArrayPtr->numTabs++; /* - * See if there is an explicit alignment in the next list - * element. Otherwise just use "left". + * See if there is an explicit alignment in the next list element. + * Otherwise just use "left". */ tabPtr->alignment = LEFT; if ((i+1) == objc) { continue; } - /* There may be a more efficient way of getting this */ + + /* + * There may be a more efficient way of getting this. + */ + Tcl_UtfToUniChar(Tcl_GetString(objv[i+1]), &ch); if (!Tcl_UniCharIsAlpha(ch)) { continue; } i += 1; - - if (Tcl_GetIndexFromObj(interp, objv[i], tabOptionStrings, - "tab alignment", 0, &index) != TCL_OK) { + + if (Tcl_GetIndexFromObj(interp, objv[i], tabOptionStrings, + "tab alignment", 0, &index) != TCL_OK) { goto error; } tabPtr->alignment = ((TkTextTabAlign)index); } - + /* - * For when we need to interpolate tab stops, store - * these two so we know the tab stop size to very - * high precision. With the above checks, we can - * guarantee that tabIncrement is strictly positive - * here. + * For when we need to interpolate tab stops, store these two so we know + * the tab stop size to very high precision. With the above checks, we can + * guarantee that tabIncrement is strictly positive here. */ + tabArrayPtr->lastTab = lastStop; tabArrayPtr->tabIncrement = lastStop - prevStop; - + return tabArrayPtr; - error: + error: ckfree((char *) tabArrayPtr); return NULL; } @@ -4330,8 +4360,8 @@ TkTextGetTabs(interp, textPtr, stringPtr) * TextDumpCmd -- * * Return information about the text, tags, marks, and embedded windows - * and images in a text widget. See the man page for the description - * of the text dump operation for all the details. + * and images in a text widget. See the man page for the description of + * the text dump operation for all the details. * * Results: * A standard Tcl result. @@ -4405,7 +4435,7 @@ TextDumpCmd(textPtr, interp, objc, objv) case DUMP_CMD: arg++; if (arg >= objc) { - Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]), + Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]), " dump ?-all -image -text -mark -tag -window? ", "?-command script? index ?index2?", NULL); return TCL_ERROR; @@ -4417,7 +4447,7 @@ TextDumpCmd(textPtr, interp, objc, objv) } } if (arg >= objc || arg+2 < objc) { - Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]), + Tcl_AppendResult(interp, "Usage: ", Tcl_GetString(objv[0]), " dump ?-all -image -text -mark -tag -window? ", "?-command script? index ?index2?", NULL); return TCL_ERROR; @@ -4436,6 +4466,7 @@ TextDumpCmd(textPtr, interp, objc, objv) } else { int length; char *str; + if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) { return TCL_ERROR; } @@ -4465,12 +4496,14 @@ TextDumpCmd(textPtr, interp, objc, objv) DumpLine(interp, textPtr, what, index2.linePtr, 0, index2.byteIndex, lineno, command); } + /* * Special case to get the leftovers hiding at the end mark. */ + if (atEnd) { DumpLine(interp, textPtr, what & ~TK_DUMP_TEXT, index2.linePtr, - 0, 1, lineno, command); + 0, 1, lineno, command); } return TCL_OK; } @@ -4479,16 +4512,16 @@ TextDumpCmd(textPtr, interp, objc, objv) *---------------------------------------------------------------------- * * DumpLine - * - * Return information about a given text line from character - * position "start" up to, but not including, "end". + * + * Return information about a given text line from character position + * "start" up to, but not including, "end". * * Results: * A standard Tcl result. * * Side effects: * None, but see DumpSegment. - * + * *---------------------------------------------------------------------- */ static void @@ -4521,6 +4554,7 @@ DumpLine(interp, textPtr, what, linePtr, startByte, endByte, lineno, command) char savedChar; /* Last char used in the seg */ int last = segPtr->size; /* Index of savedChar */ int first = 0; /* Index of first char in seg */ + if (offset + segPtr->size > endByte) { last = endByte - offset; } @@ -4529,62 +4563,65 @@ DumpLine(interp, textPtr, what, linePtr, startByte, endByte, lineno, command) } savedChar = segPtr->body.chars[last]; segPtr->body.chars[last] = '\0'; - - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, lineno, - offset + first, &index); + + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, lineno, + offset + first, &index); DumpSegment(textPtr, interp, "text", segPtr->body.chars + first, command, &index, what); segPtr->body.chars[last] = savedChar; } else if ((offset >= startByte)) { if ((what & TK_DUMP_MARK) && (segPtr->typePtr->name[0] == 'm')) { char *name; - TkTextMark *markPtr = (TkTextMark *)&segPtr->body; + TkTextMark *markPtr = (TkTextMark *) &segPtr->body; + if (segPtr == textPtr->insertMarkPtr) { name = "insert"; } else if (segPtr == textPtr->currentMarkPtr) { name = "current"; } else { - name = Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, - markPtr->hPtr); + name = Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, + markPtr->hPtr); } - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - lineno, offset, &index); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, + lineno, offset, &index); DumpSegment(textPtr, interp, "mark", name, command, &index, what); } else if ((what & TK_DUMP_TAG) && - (segPtr->typePtr == &tkTextToggleOnType)) { - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - lineno, offset, &index); + (segPtr->typePtr == &tkTextToggleOnType)) { + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, + lineno, offset, &index); DumpSegment(textPtr, interp, "tagon", - segPtr->body.toggle.tagPtr->name, - command, &index, what); - } else if ((what & TK_DUMP_TAG) && - (segPtr->typePtr == &tkTextToggleOffType)) { - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - lineno, offset, &index); + segPtr->body.toggle.tagPtr->name, command, &index, + what); + } else if ((what & TK_DUMP_TAG) && + (segPtr->typePtr == &tkTextToggleOffType)) { + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, + lineno, offset, &index); DumpSegment(textPtr, interp, "tagoff", - segPtr->body.toggle.tagPtr->name, - command, &index, what); - } else if ((what & TK_DUMP_IMG) && - (segPtr->typePtr->name[0] == 'i')) { + segPtr->body.toggle.tagPtr->name, command, &index, + what); + } else if ((what & TK_DUMP_IMG) && + (segPtr->typePtr->name[0] == 'i')) { TkTextEmbImage *eiPtr = (TkTextEmbImage *)&segPtr->body; - char *name = (eiPtr->name == NULL) ? "" : eiPtr->name; - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - lineno, offset, &index); - DumpSegment(textPtr, interp, "image", name, - command, &index, what); - } else if ((what & TK_DUMP_WIN) && - (segPtr->typePtr->name[0] == 'w')) { + char *name = (eiPtr->name == NULL) ? "" : eiPtr->name; + + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, + lineno, offset, &index); + DumpSegment(textPtr, interp, "image", name, command, &index, + what); + } else if ((what & TK_DUMP_WIN) && + (segPtr->typePtr->name[0] == 'w')) { TkTextEmbWindow *ewPtr = (TkTextEmbWindow *)&segPtr->body; char *pathname; + if (ewPtr->tkwin == (Tk_Window) NULL) { pathname = ""; } else { pathname = Tk_PathName(ewPtr->tkwin); } - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - lineno, offset, &index); - DumpSegment(textPtr, interp, "window", pathname, - command, &index, what); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, + lineno, offset, &index); + DumpSegment(textPtr, interp, "window", pathname, command, + &index, what); } } } @@ -4594,18 +4631,19 @@ DumpLine(interp, textPtr, what, linePtr, startByte, endByte, lineno, command) *---------------------------------------------------------------------- * * DumpSegment - * - * Either append information about the current segment to the result, - * or make a script callback with that information as arguments. + * + * Either append information about the current segment to the result, or + * make a script callback with that information as arguments. * * Results: * None * * Side effects: * Either evals the callback or appends elements to the result string. - * + * *---------------------------------------------------------------------- */ + static int DumpSegment(textPtr, interp, key, value, command, index, what) TkText *textPtr; @@ -4613,10 +4651,11 @@ DumpSegment(textPtr, interp, key, value, command, index, what) CONST char *key; /* Segment type key */ CONST char *value; /* Segment value */ CONST char *command; /* Script callback */ - CONST TkTextIndex *index; /* index with line/byte position info */ + CONST TkTextIndex *index; /* index with line/byte position info */ int what; /* Look for TK_DUMP_INDEX bit */ { char buffer[TK_POS_CHARS]; + TkTextPrintIndex(textPtr, index, buffer); if (command == NULL) { Tcl_AppendElement(interp, key); @@ -4627,6 +4666,7 @@ DumpSegment(textPtr, interp, key, value, command, index, what) CONST char *argv[4]; char *list; int result; + argv[0] = key; argv[1] = value; argv[2] = buffer; @@ -4642,41 +4682,40 @@ DumpSegment(textPtr, interp, key, value, command, index, what) *---------------------------------------------------------------------- * * TextEditUndo -- - * - * undo the last change. + * + * Undo the last change. * * Results: - * None + * None. * * Side effects: - * None. - * + * Apart from manipulating the undo and redo stacks, the state of the + * rest of the widget may also change (due to whatever is being undone). + * *---------------------------------------------------------------------- */ static int TextEditUndo(textPtr) - TkText *textPtr; /* Overall information about text widget. */ + TkText *textPtr; /* Overall information about text widget. */ { int status; if (!textPtr->sharedTextPtr->undo) { - return TCL_OK; + return TCL_OK; } - /* Turn off the undo feature */ - textPtr->sharedTextPtr->undo = 0; + /* + * Turn off the undo feature while we revert a compound action. Note that + * the dirty counter counts backwards while we are undoing... + */ - /* The dirty counter should count downwards as we are undoing things */ + textPtr->sharedTextPtr->undo = 0; textPtr->sharedTextPtr->isDirtyIncrement = -1; - /* revert one compound action */ status = TkUndoRevert(textPtr->sharedTextPtr->undoStack); - /* Restore the isdirty increment */ textPtr->sharedTextPtr->isDirtyIncrement = 1; - - /* Turn back on the undo feature */ textPtr->sharedTextPtr->undo = 1; return status; @@ -4686,37 +4725,39 @@ TextEditUndo(textPtr) *---------------------------------------------------------------------- * * TextEditRedo -- - * - * redo the last undone change. + * + * Redo the last undone change. * * Results: - * None + * None. * * Side effects: - * None. - * + * Apart from manipulating the undo and redo stacks, the state of the + * rest of the widget may also change (due to whatever is being redone). + * *---------------------------------------------------------------------- */ static int TextEditRedo(textPtr) - TkText *textPtr; /* Overall information about text widget. */ + TkText *textPtr; /* Overall information about text widget. */ { int status; if (!textPtr->sharedTextPtr->undo) { - return TCL_OK; + return TCL_OK; } - /* Turn off the undo feature temporarily */ + /* + * Turn off the undo feature temporarily while we revert a previously + * undone compound action. + */ + textPtr->sharedTextPtr->undo = 0; - /* reapply one compound action */ status = TkUndoApply(textPtr->sharedTextPtr->undoStack); - /* Turn back on the undo feature */ textPtr->sharedTextPtr->undo = 1; - return status; } @@ -4725,126 +4766,122 @@ TextEditRedo(textPtr) * * TextEditCmd -- * - * Handle the subcommands to "$text edit ...". - * See documentation for details. + * Handle the subcommands to "$text edit ...". See documentation for + * details. * * Results: - * None + * None * * Side effects: - * None. - * + * None. + * *---------------------------------------------------------------------- */ static int TextEditCmd(textPtr, interp, objc, objv) - TkText *textPtr; /* Information about text widget. */ - Tcl_Interp *interp; /* Current interpreter. */ + TkText *textPtr; /* Information about text widget. */ + Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ { int index; - + static CONST char *editOptionStrings[] = { - "modified", "redo", "reset", "separator", "undo", (char *) NULL + "modified", "redo", "reset", "separator", "undo", (char *) NULL }; enum editOptions { EDIT_MODIFIED, EDIT_REDO, EDIT_RESET, EDIT_SEPARATOR, EDIT_UNDO }; - + if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); return TCL_ERROR; } - - if (Tcl_GetIndexFromObj(interp, objv[2], editOptionStrings, - "edit option", 0, &index) != TCL_OK) { + + if (Tcl_GetIndexFromObj(interp, objv[2], editOptionStrings, + "edit option", 0, &index) != TCL_OK) { return TCL_ERROR; } - switch ((enum editOptions)index) { - case EDIT_MODIFIED: { - if (objc == 3) { - Tcl_SetObjResult(interp, - Tcl_NewBooleanObj(textPtr->sharedTextPtr->isDirty)); - } else if (objc != 4) { - Tcl_WrongNumArgs(interp, 3, objv, "?boolean?"); - return TCL_ERROR; - } else { - int setModified; - XEvent event; - if (Tcl_GetBooleanFromObj(interp, objv[3], &setModified) - != TCL_OK) { - return TCL_ERROR; - } - /* - * Set or reset the dirty info and trigger a Modified event. - */ + switch ((enum editOptions) index) { + case EDIT_MODIFIED: + if (objc == 3) { + Tcl_SetObjResult(interp, + Tcl_NewBooleanObj(textPtr->sharedTextPtr->isDirty)); + } else if (objc != 4) { + Tcl_WrongNumArgs(interp, 3, objv, "?boolean?"); + return TCL_ERROR; + } else { + int setModified; + XEvent event; - if (setModified) { - textPtr->sharedTextPtr->isDirty = 1; - textPtr->sharedTextPtr->modifiedSet = 1; - } else { - textPtr->sharedTextPtr->isDirty = 0; - textPtr->sharedTextPtr->modifiedSet = 0; - } + if (Tcl_GetBooleanFromObj(interp, objv[3], + &setModified) != TCL_OK) { + return TCL_ERROR; + } - /* - * Send an event that the text was modified. This is - * equivalent to "event generate $textWidget <<Modified>>" - */ + /* + * Set or reset the dirty info and trigger a Modified event. + */ - memset((VOID *) &event, 0, sizeof(event)); - event.xany.type = VirtualEvent; - event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); - event.xany.send_event = False; - event.xany.window = Tk_WindowId(textPtr->tkwin); - event.xany.display = Tk_Display(textPtr->tkwin); - ((XVirtualEvent *) &event)->name = Tk_GetUid("Modified"); - Tk_HandleEvent(&event); + if (setModified) { + textPtr->sharedTextPtr->isDirty = 1; + textPtr->sharedTextPtr->modifiedSet = 1; + } else { + textPtr->sharedTextPtr->isDirty = 0; + textPtr->sharedTextPtr->modifiedSet = 0; } - break; + + /* + * Send an event that the text was modified. This is equivalent to + * "event generate $textWidget <<Modified>>" + */ + + memset((VOID *) &event, 0, sizeof(event)); + event.xany.type = VirtualEvent; + event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); + event.xany.send_event = False; + event.xany.window = Tk_WindowId(textPtr->tkwin); + event.xany.display = Tk_Display(textPtr->tkwin); + ((XVirtualEvent *) &event)->name = Tk_GetUid("Modified"); + Tk_HandleEvent(&event); } - case EDIT_REDO: { - if (objc != 3) { - Tcl_WrongNumArgs(interp, 3, objv, NULL); - return TCL_ERROR; - } - if (TextEditRedo(textPtr)) { - Tcl_AppendResult(interp, "nothing to redo", (char *) NULL); - return TCL_ERROR; - } - break; + break; + case EDIT_REDO: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 3, objv, NULL); + return TCL_ERROR; } - case EDIT_RESET: { - if (objc != 3) { - Tcl_WrongNumArgs(interp, 3, objv, NULL); - return TCL_ERROR; - } - TkUndoClearStacks(textPtr->sharedTextPtr->undoStack); - break; + if (TextEditRedo(textPtr)) { + Tcl_AppendResult(interp, "nothing to redo", (char *) NULL); + return TCL_ERROR; } - case EDIT_SEPARATOR: { - if (objc != 3) { - Tcl_WrongNumArgs(interp, 3, objv, NULL); - return TCL_ERROR; - } - TkUndoInsertUndoSeparator(textPtr->sharedTextPtr->undoStack); - break; + break; + case EDIT_RESET: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 3, objv, NULL); + return TCL_ERROR; } - case EDIT_UNDO: { - if (objc != 3) { - Tcl_WrongNumArgs(interp, 3, objv, NULL); - return TCL_ERROR; - } - if (TextEditUndo(textPtr)) { - Tcl_AppendResult(interp, "nothing to undo", - (char *) NULL); - return TCL_ERROR; - } - break; - } + TkUndoClearStacks(textPtr->sharedTextPtr->undoStack); + break; + case EDIT_SEPARATOR: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 3, objv, NULL); + return TCL_ERROR; + } + TkUndoInsertUndoSeparator(textPtr->sharedTextPtr->undoStack); + break; + case EDIT_UNDO: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 3, objv, NULL); + return TCL_ERROR; + } + if (TextEditUndo(textPtr)) { + Tcl_AppendResult(interp, "nothing to undo", (char *) NULL); + return TCL_ERROR; + } + break; } return TCL_OK; } @@ -4853,49 +4890,51 @@ TextEditCmd(textPtr, interp, objc, objv) *---------------------------------------------------------------------- * * TextGetText -- - * - * Returns the text from indexPtr1 to indexPtr2, placing that text - * in a string object which is returned with a refCount of zero. - * - * Since the amount of text may potentially be several megabytes (e.g. - * in text editors built on the text widget), efficiency is very - * important. We may want to investigate the efficiency of the - * Tcl_AppendToObj more carefully (e.g. if we know we are going to be - * appending several thousand lines, we could attempt to pre-allocate - * a larger space). - * - * Also the result is built up as a utf-8 string, but, if we knew - * we wanted it as Unicode, we could potentially save a huge - * conversion by building it up as Unicode directly. This could - * be as simple as replacing Tcl_NewObj by Tcl_NewUnicodeObj. + * + * Returns the text from indexPtr1 to indexPtr2, placing that text in a + * string object which is returned with a refCount of zero. + * + * Since the amount of text may potentially be several megabytes (e.g. + * in text editors built on the text widget), efficiency is very + * important. We may want to investigate the efficiency of the + * Tcl_AppendToObj more carefully (e.g. if we know we are going to be + * appending several thousand lines, we could attempt to pre-allocate a + * larger space). + * + * Also the result is built up as a utf-8 string, but, if we knew we + * wanted it as Unicode, we could potentially save a huge conversion by + * building it up as Unicode directly. This could be as simple as + * replacing Tcl_NewObj by Tcl_NewUnicodeObj. * * Results: - * Tcl_Obj of string type containing the specified text. If the - * visibleOnly flag is set to 1, then only those characters which - * are not elided will be returned. Otherwise (flag is 0) all - * characters in the given range are returned. + * Tcl_Obj of string type containing the specified text. If the + * visibleOnly flag is set to 1, then only those characters which are not + * elided will be returned. Otherwise (flag is 0) all characters in the + * given range are returned. * * Side effects: - * Memory will be allocated for the new object. Remember to free it if - * it isn't going to be stored appropriately. - * + * Memory will be allocated for the new object. Remember to free it if it + * isn't going to be stored appropriately. + * *---------------------------------------------------------------------- */ -static Tcl_Obj* +static Tcl_Obj* TextGetText(textPtr, indexPtr1,indexPtr2, visibleOnly) - CONST TkText *textPtr; /* Information about text widget. */ - CONST TkTextIndex *indexPtr1; /* Get text from this index... */ - CONST TkTextIndex *indexPtr2; /* ...to this index */ - int visibleOnly; /* If non-zero, then only return - * non-elided characters. */ + CONST TkText *textPtr; /* Information about text widget. */ + CONST TkTextIndex *indexPtr1; + /* Get text from this index... */ + CONST TkTextIndex *indexPtr2; + /* ...to this index. */ + int visibleOnly; /* If non-zero, then only return non-elided + * characters. */ { TkTextIndex tmpIndex; Tcl_Obj *resultPtr = Tcl_NewObj(); - - TkTextMakeByteIndex(indexPtr1->tree, textPtr, - TkBTreeLinesTo(textPtr, indexPtr1->linePtr), - indexPtr1->byteIndex, &tmpIndex); + + TkTextMakeByteIndex(indexPtr1->tree, textPtr, + TkBTreeLinesTo(textPtr, indexPtr1->linePtr), + indexPtr1->byteIndex, &tmpIndex); if (TkTextIndexCmp(indexPtr1, indexPtr2) < 0) { while (1) { @@ -4905,25 +4944,27 @@ TextGetText(textPtr, indexPtr1,indexPtr2, visibleOnly) segPtr = TkTextIndexToSeg(&tmpIndex, &offset); last = segPtr->size; if (tmpIndex.linePtr == indexPtr2->linePtr) { - /* - * The last line that was requested must be handled - * carefully, because we may need to break out of this - * loop in the middle of the line + /* + * The last line that was requested must be handled carefully, + * because we may need to break out of this loop in the middle + * of the line. */ + if (indexPtr2->byteIndex == tmpIndex.byteIndex) { break; } else { - int last2; - last2 = indexPtr2->byteIndex - tmpIndex.byteIndex + offset; + int last2 = + indexPtr2->byteIndex - tmpIndex.byteIndex + offset; + if (last2 < last) { last = last2; } } } if (segPtr->typePtr == &tkTextCharType) { - if (!visibleOnly || !TkTextIsElided(textPtr, &tmpIndex, NULL)) { + if (!visibleOnly || !TkTextIsElided(textPtr,&tmpIndex,NULL)) { Tcl_AppendToObj(resultPtr, segPtr->body.chars + offset, - last - offset); + last - offset); } } TkTextIndexForwBytes(textPtr, &tmpIndex, last-offset, &tmpIndex); @@ -4936,39 +4977,40 @@ TextGetText(textPtr, indexPtr1,indexPtr2, visibleOnly) *---------------------------------------------------------------------- * * UpdateDirtyFlag -- - * - * Increases the dirtyness of the text widget + * + * Increases the dirtyness of the text widget * * Results: - * None + * None * * Side effects: - * None. - * + * None. + * *---------------------------------------------------------------------- */ -static void -UpdateDirtyFlag (sharedTextPtr) - TkSharedText *sharedTextPtr; /* Information about text widget. */ +static void +UpdateDirtyFlag(sharedTextPtr) + TkSharedText *sharedTextPtr;/* Information about text widget. */ { int oldDirtyFlag; if (sharedTextPtr->modifiedSet) { - return; + return; } oldDirtyFlag = sharedTextPtr->isDirty; sharedTextPtr->isDirty += sharedTextPtr->isDirtyIncrement; if (sharedTextPtr->isDirty == 0 || oldDirtyFlag == 0) { TkText *textPtr; - for (textPtr = sharedTextPtr->peers; textPtr != NULL; - textPtr = textPtr->next) { - XEvent event; + for (textPtr = sharedTextPtr->peers; textPtr != NULL; + textPtr = textPtr->next) { /* - * Send an event that the text was modified. This is equivalent to - * "event generate $textWidget <<Modified>>" + * Send an event that the text was modified. This is equivalent to + * event generate $textWidget <<Modified>> */ + XEvent event; + memset((VOID *) &event, 0, sizeof(event)); event.xany.type = VirtualEvent; event.xany.serial = NextRequest(Tk_Display(textPtr->tkwin)); @@ -4986,68 +5028,75 @@ UpdateDirtyFlag (sharedTextPtr) * * SearchPerform -- * - * Overall control of search process. Is given a pattern, a - * starting index and an ending index, and attempts to perform a - * search. This procedure is actually completely independent of Tk, - * and could in the future be split off. - * + * Overall control of search process. Is given a pattern, a starting + * index and an ending index, and attempts to perform a search. This + * function is actually completely independent of Tk, and could in the + * future be split off. + * * Results: - * Standard Tcl result code. In particular, if fromPtr or toPtr - * are not considered valid by the 'lineIndexProc', an error - * will be thrown and no search performed. + * Standard Tcl result code. In particular, if fromPtr or toPtr are not + * considered valid by the 'lineIndexProc', an error will be thrown and + * no search performed. * * Side effects: * See 'SearchCore'. - * + * *---------------------------------------------------------------------- */ static int SearchPerform(interp, searchSpecPtr, patObj, fromPtr, toPtr) - Tcl_Interp *interp; /* For error messages */ - SearchSpec *searchSpecPtr; /* Search parameters */ - Tcl_Obj *patObj; /* Contains an exact string or a - * regexp pattern. Must have a - * refCount > 0 */ - Tcl_Obj *fromPtr; /* Contains information describing - * the first index */ - Tcl_Obj *toPtr; /* NULL or information describing - * the last index */ + Tcl_Interp *interp; /* For error messages */ + SearchSpec *searchSpecPtr; /* Search parameters */ + Tcl_Obj *patObj; /* Contains an exact string or a regexp + * pattern. Must have a refCount > 0 */ + Tcl_Obj *fromPtr; /* Contains information describing the first + * index */ + Tcl_Obj *toPtr; /* NULL or information describing the last + * index */ { - /* - * Find the starting line and starting offset (measured in Unicode - * chars for regexp search, utf-8 bytes for exact search) + /* + * Find the starting line and starting offset (measured in Unicode chars + * for regexp search, utf-8 bytes for exact search). */ - if ((*searchSpecPtr->lineIndexProc)(interp, fromPtr, searchSpecPtr, + + if ((*searchSpecPtr->lineIndexProc)(interp, fromPtr, searchSpecPtr, &searchSpecPtr->startLine, &searchSpecPtr->startOffset) != TCL_OK) { return TCL_ERROR; } - /* + /* * Find the optional end location, similarly. */ + if (toPtr != NULL) { CONST TkTextIndex *indexToPtr, *indexFromPtr; TkText *textPtr = (TkText*)(searchSpecPtr->clientData); - + indexToPtr = TkTextGetIndexFromObj(interp, textPtr, toPtr); if (indexToPtr == NULL) { return TCL_ERROR; } indexFromPtr = TkTextGetIndexFromObj(interp, textPtr, fromPtr); - /* - * Check for any empty search range here. It might be better - * in the future to embed that in SearchCore (whose default - * behaviour is to wrap when given a negative search range). + + /* + * Check for any empty search range here. It might be better in the + * future to embed that in SearchCore (whose default behaviour is to + * wrap when given a negative search range). */ + if (searchSpecPtr->backwards) { - if (TkTextIndexCmp(indexFromPtr, indexToPtr) == -1) return TCL_OK; + if (TkTextIndexCmp(indexFromPtr, indexToPtr) == -1) { + return TCL_OK; + } } else { - if (TkTextIndexCmp(indexFromPtr, indexToPtr) == 1) return TCL_OK; + if (TkTextIndexCmp(indexFromPtr, indexToPtr) == 1) { + return TCL_OK; + } } - - if ((*searchSpecPtr->lineIndexProc)(interp, toPtr, searchSpecPtr, + + if ((*searchSpecPtr->lineIndexProc)(interp, toPtr, searchSpecPtr, &searchSpecPtr->stopLine, &searchSpecPtr->stopOffset) != TCL_OK) { return TCL_ERROR; @@ -5057,10 +5106,9 @@ SearchPerform(interp, searchSpecPtr, patObj, fromPtr, toPtr) } /* - * Scan through all of the lines of the text circularly, starting - * at the given index. 'patObj' is the pattern which may be an - * exact string or a regexp pattern depending on the flags in - * searchSpecPtr. + * Scan through all of the lines of the text circularly, starting at the + * given index. 'patObj' is the pattern which may be an exact string or a + * regexp pattern depending on the flags in searchSpecPtr. */ return SearchCore(interp, searchSpecPtr, patObj); @@ -5071,14 +5119,12 @@ SearchPerform(interp, searchSpecPtr, patObj, fromPtr, toPtr) * * SearchCore -- * - * The core of the search procedure. This procedure is actually - * completely independent of Tk, and could in the future be split - * off. + * The core of the search function. This function is actually completely + * independent of Tk, and could in the future be split off. * - * The function assumes regexp-based searches operate on Unicode - * strings, and exact searches on utf-8 strings. Therefore the - * 'foundMatchProc' and 'addLineProc' need to be aware of this - * distinction. + * The function assumes regexp-based searches operate on Unicode strings, + * and exact searches on utf-8 strings. Therefore the 'foundMatchProc' + * and 'addLineProc' need to be aware of this distinction. * * Results: * Standard Tcl result code. @@ -5087,46 +5133,50 @@ SearchPerform(interp, searchSpecPtr, patObj, fromPtr, toPtr) * Only those of the 'searchSpecPtr->foundMatchProc' which is called * whenever a match is found. * - * Note that the way matching across multiple lines is implemented, - * we start afresh with each line we have available, even though we - * may already have examined the contents of that line (and further - * ones) if we were attempting a multi-line match using the previous - * line. This means there may be ways to speed this up a lot by not - * throwing away all the multi-line information one has accumulated. - * Profiling should be done to see where the bottlenecks lie before - * attempting this, however. We would also need to be very careful - * such optimisation keep within the specified search bounds. + * Note that the way matching across multiple lines is implemented, we + * start afresh with each line we have available, even though we may + * already have examined the contents of that line (and further ones) if + * we were attempting a multi-line match using the previous line. This + * means there may be ways to speed this up a lot by not throwing away + * all the multi-line information one has accumulated. Profiling should + * be done to see where the bottlenecks lie before attempting this, + * however. We would also need to be very careful such optimisation keep + * within the specified search bounds. * *---------------------------------------------------------------------- */ static int SearchCore(interp, searchSpecPtr, patObj) - Tcl_Interp *interp; /* For error messages */ - SearchSpec *searchSpecPtr; /* Search parameters */ - Tcl_Obj *patObj; /* Contains an exact string or a - * regexp pattern. Must have a - * refCount > 0 */ + Tcl_Interp *interp; /* For error messages */ + SearchSpec *searchSpecPtr; /* Search parameters */ + Tcl_Obj *patObj; /* Contains an exact string or a regexp + * pattern. Must have a refCount > 0 */ { - int passes; /* - * For exact searches these are utf-8 char* offsets, for regexp - * searches they are Unicode char offsets + * For exact searches these are utf-8 char* offsets, for regexp searches + * they are Unicode char offsets. */ + int firstOffset, lastOffset, matchOffset, matchLength; + int passes; int lineNum = searchSpecPtr->startLine; int code = TCL_OK; Tcl_Obj *theLine; int alreadySearchOffset = -1; - - Tcl_RegExp regexp = NULL; /* For regexp searches only */ - /* - * These items are for backward regexp searches only. They are for - * two purposes: to allow us to report backwards matches in the - * correct order, even though the implementation uses repeated - * forward searches; and to provide for overlap checking between - * backwards matches on different text lines. + + CONST char *pattern = NULL; /* For exact searches only. */ + int firstNewLine = -1; /* For exact searches only. */ + Tcl_RegExp regexp = NULL; /* For regexp searches only. */ + + /* + * These items are for backward regexp searches only. They are for two + * purposes: to allow us to report backwards matches in the correct order, + * even though the implementation uses repeated forward searches; and to + * provide for overlap checking between backwards matches on different + * text lines. */ + #define LOTS_OF_MATCHES 20 int matchNum = LOTS_OF_MATCHES; int smArray[2 * LOTS_OF_MATCHES]; @@ -5134,76 +5184,81 @@ SearchCore(interp, searchSpecPtr, patObj) int *storeLength = smArray + LOTS_OF_MATCHES; int lastBackwardsLineMatch = -1; int lastBackwardsMatchOffset = -1; - - /* These two items are for exact searches only */ - CONST char *pattern = NULL; - int firstNewLine = -1; if (searchSpecPtr->exact) { /* - * Convert the pattern to lower-case if we're supposed to ignore - * case. + * Convert the pattern to lower-case if we're supposed to ignore case. */ + if (searchSpecPtr->noCase) { patObj = Tcl_DuplicateObj(patObj); + /* - * This can change the length of the string behind the - * object's back, so ensure it is correctly synchronised. + * This can change the length of the string behind the object's + * back, so ensure it is correctly synchronised. */ + Tcl_SetObjLength(patObj, Tcl_UtfToLower(Tcl_GetString(patObj))); } } else { /* - * Compile the regular expression. We want '^$' to match after and + * Compile the regular expression. We want '^$' to match after and * before \n respectively, so use the TCL_REG_NLANCH flag. */ + regexp = Tcl_GetRegExpFromObj(interp, patObj, (searchSpecPtr->noCase ? TCL_REG_NOCASE : 0) | (searchSpecPtr->noLineStop ? 0 : TCL_REG_NLSTOP) - | TCL_REG_ADVANCED | TCL_REG_CANMATCH | TCL_REG_NLANCH); + | TCL_REG_ADVANCED | TCL_REG_CANMATCH | TCL_REG_NLANCH); if (regexp == NULL) { return TCL_ERROR; } } /* - * For exact strings, we want to know where the first newline is, - * and we will also use this as a flag to test whether it is even - * possible to match the pattern on a single line. If not we - * will have to search across multiple lines. + * For exact strings, we want to know where the first newline is, and we + * will also use this as a flag to test whether it is even possible to + * match the pattern on a single line. If not we will have to search + * across multiple lines. */ + if (searchSpecPtr->exact) { CONST char *nl; /* - * We only need to set the matchLength once for exact searches, - * and we do it here. It is also used below as the actual - * pattern length, so it has dual purpose. + * We only need to set the matchLength once for exact searches, and we + * do it here. It is also used below as the actual pattern length, so + * it has dual purpose. */ + pattern = Tcl_GetStringFromObj(patObj, &matchLength); nl = strchr(pattern, '\n'); + /* - * If there is no newline, or it is the very end of the string, - * then we don't need any special treatment, since single-line - * matching will work fine. + * If there is no newline, or it is the very end of the string, then + * we don't need any special treatment, since single-line matching + * will work fine. */ + if (nl != NULL && nl[1] != '\0') { firstNewLine = (nl - pattern); } } else { - matchLength = 0; /* Only needed to prevent compiler warnings. */ + matchLength = 0; /* Only needed to prevent compiler warnings. */ } /* - * Keep a reference here, so that we can be sure the object - * doesn't disappear behind our backs and invalidate its - * contents which we are using. + * Keep a reference here, so that we can be sure the object doesn't + * disappear behind our backs and invalidate its contents which we are + * using. */ + Tcl_IncrRefCount(patObj); /* - * For building up the current line being checked + * For building up the current line being checked. */ + theLine = Tcl_NewObj(); Tcl_IncrRefCount(theLine); @@ -5211,40 +5266,41 @@ SearchCore(interp, searchSpecPtr, patObj) ClientData lineInfo; int linesSearched = 1; int extraLinesSearched = 0; - + if (lineNum >= searchSpecPtr->numLines) { /* * Don't search the dummy last line of the text. */ + goto nextLine; } /* - * Extract the text from the line, storing its length in - * 'lastOffset' (in bytes if exact, chars if regexp), since - * obviously the length is the maximum offset at which - * it is possible to find something on this line, which is - * what 'lastOffset' represents. + * Extract the text from the line, storing its length in 'lastOffset' + * (in bytes if exact, chars if regexp), since obviously the length is + * the maximum offset at which it is possible to find something on + * this line, which is what 'lastOffset' represents. */ - lineInfo = (*searchSpecPtr->addLineProc)(lineNum, - searchSpecPtr, theLine, &lastOffset, &linesSearched); + lineInfo = (*searchSpecPtr->addLineProc)(lineNum, searchSpecPtr, + theLine, &lastOffset, &linesSearched); if (lineInfo == NULL) { - /* - * This should not happen, since 'lineNum' should be valid - * in the call above. However, let's try to be flexible and - * not cause a crash below. + /* + * This should not happen, since 'lineNum' should be valid in the + * call above. However, let's try to be flexible and not cause a + * crash below. */ + goto nextLine; } - + if (lineNum == searchSpecPtr->stopLine && searchSpecPtr->backwards) { firstOffset = searchSpecPtr->stopOffset; } else { firstOffset = 0; } - + if (alreadySearchOffset != -1) { if (searchSpecPtr->backwards) { if (alreadySearchOffset < lastOffset) { @@ -5257,18 +5313,19 @@ SearchCore(interp, searchSpecPtr, patObj) } alreadySearchOffset = -1; } - + if (lineNum == searchSpecPtr->startLine) { /* - * The starting line is tricky: the first time we see it - * we check one part of the line, and the second pass through - * we check the other part of the line. + * The starting line is tricky: the first time we see it we check + * one part of the line, and the second pass through we check the + * other part of the line. */ + passes++; if ((passes == 1) ^ searchSpecPtr->backwards) { /* - * Forward search and first pass, or backward - * search and second pass. + * Forward search and first pass, or backward search and + * second pass. * * Only use the last part of the line. */ @@ -5292,11 +5349,11 @@ SearchCore(interp, searchSpecPtr, patObj) } /* - * Check for matches within the current line 'lineNum'. If so, - * and if we're searching backwards or for all matches, repeat - * the search until we find the last match in the line. The - * 'lastOffset' is one beyond the last position in the line at - * which a match is allowed to begin. + * Check for matches within the current line 'lineNum'. If so, and if + * we're searching backwards or for all matches, repeat the search + * until we find the last match in the line. The 'lastOffset' is one + * beyond the last position in the line at which a match is allowed to + * begin. */ matchOffset = -1; @@ -5311,22 +5368,29 @@ SearchCore(interp, searchSpecPtr, patObj) int lastFullLine = lastOffset; if (firstNewLine == -1) { - if (searchSpecPtr->strictLimits - && (firstOffset + matchLength > lastOffset)) { - /* Not enough characters to match. */ - break; + if (searchSpecPtr->strictLimits + && (firstOffset + matchLength > lastOffset)) { + /* + * Not enough characters to match. + */ + + break; } - /* - * Single line matching. We want to scan forwards - * or backwards as appropriate. + + /* + * Single line matching. We want to scan forwards or + * backwards as appropriate. */ + if (searchSpecPtr->backwards) { - /* - * Search back either from the previous match or - * from 'startOfLine + lastOffset - 1' until we - * find a match. + /* + * Search back either from the previous match or from + * 'startOfLine + lastOffset - 1' until we find a + * match. */ + CONST char c = pattern[0]; + if (alreadySearchOffset != -1) { p = startOfLine + alreadySearchOffset; alreadySearchOffset = -1; @@ -5345,41 +5409,49 @@ SearchCore(interp, searchSpecPtr, patObj) p = strstr(startOfLine + firstOffset, pattern); } if (p == NULL) { - /* - * Single line match failed. + /* + * Single line match failed. */ - break; + + break; } } else if (firstNewLine >= (lastOffset - firstOffset)) { - /* - * Multi-line match, but not enough characters to - * match. + /* + * Multi-line match, but not enough characters to match. */ + break; } else { - /* - * Multi-line match has only one possible match - * position, because we know where the '\n' is. + /* + * Multi-line match has only one possible match position, + * because we know where the '\n' is. */ + p = startOfLine + lastOffset - firstNewLine - 1; if (strncmp(p, pattern, (unsigned)(firstNewLine + 1))) { - /* No match */ + /* + * No match. + */ break; } else { int extraLines = 1; - /* + + /* * If we find a match that overlaps more than one - * line, we will use this value to determine the - * first allowed starting offset for the following - * search (to avoid overlapping results). + * line, we will use this value to determine the first + * allowed starting offset for the following search + * (to avoid overlapping results). */ + int lastTotal = lastOffset; int skipFirst = lastOffset - firstNewLine -1; + /* - * We may be able to match if given more text. - * The following 'while' block handles multi-line - * exact searches. + * We may be able to match if given more text. The + * following 'while' block handles multi-line exact + * searches. */ + while (1) { lastFullLine = lastTotal; @@ -5389,9 +5461,10 @@ SearchCore(interp, searchSpecPtr, patObj) } /* - * Only add the line if we haven't already - * done so already. + * Only add the line if we haven't already done so + * already. */ + if (extraLines > maxExtraLines) { if ((*searchSpecPtr->addLineProc)(lineNum + extraLines, searchSpecPtr, theLine, @@ -5407,64 +5480,80 @@ SearchCore(interp, searchSpecPtr, patObj) startOfLine = Tcl_GetString(theLine); p = startOfLine + skipFirst; + /* - * Use the fact that 'matchLength = patLength' - * for exact searches + * Use the fact that 'matchLength = patLength' for + * exact searches. */ + if ((lastTotal - skipFirst) >= matchLength) { - /* - * We now have enough text to match, so - * we make a final test and break - * whatever the result - */ - if (strncmp(p, pattern, (unsigned)matchLength)) { + /* + * We now have enough text to match, so we + * make a final test and break whatever the + * result. + */ + + if (strncmp(p,pattern,(unsigned)matchLength)) { p = NULL; } break; } else { /* - * Not enough text yet, but check the prefix + * Not enough text yet, but check the prefix. */ + if (strncmp(p, pattern, (unsigned)(lastTotal - skipFirst))) { p = NULL; break; } + /* - * The prefix matches, so keep looking + * The prefix matches, so keep looking. */ } extraLines++; } /* * If we reach here, with p != NULL, we've found a - * multi-line match, else we started a multi-match - * but didn't finish it off, so we go to the next line. + * multi-line match, else we started a multi-match but + * didn't finish it off, so we go to the next line. */ + if (p == NULL) { break; } - /* We've found a multi-line match */ + + /* + * We've found a multi-line match. + */ + extraLinesSearched = extraLines - 1; } } - backwardsMatch: + + backwardsMatch: if ((p - startOfLine) >= lastOffset) { break; } + /* - * Remember the match + * Remember the match. */ + matchOffset = p - startOfLine; if (searchSpecPtr->all && - !(*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr, - lineInfo, theLine, matchOffset, matchLength)) { + !(*searchSpecPtr->foundMatchProc)(lineNum, + searchSpecPtr, lineInfo, theLine, matchOffset, + matchLength)) { /* * We reached the end of the search */ + goto searchDone; } + if (!searchSpecPtr->overlap) { if (searchSpecPtr->backwards) { alreadySearchOffset = p - startOfLine; @@ -5476,18 +5565,20 @@ SearchCore(interp, searchSpecPtr, patObj) } else { firstOffset = p - startOfLine + matchLength; if (firstOffset >= lastOffset) { - /* + /* * Now, we have to be careful not to find * overlapping matches either on the same or - * following lines. Assume that if we did find - * something, it goes until the last extra line - * we added. - * - * We can break out of the loop, since we know - * no more will be found. + * following lines. Assume that if we did find + * something, it goes until the last extra line we + * added. + * + * We can break out of the loop, since we know no + * more will be found. */ + if (!searchSpecPtr->backwards) { - alreadySearchOffset = firstOffset - lastFullLine; + alreadySearchOffset = + firstOffset - lastFullLine; break; } } @@ -5499,8 +5590,8 @@ SearchCore(interp, searchSpecPtr, patObj) break; } } else { - firstOffset = p - startOfLine - + Tcl_UtfToUniChar(startOfLine + matchOffset, &ch); + firstOffset = p - startOfLine + + Tcl_UtfToUniChar(startOfLine+matchOffset, &ch); } } } while (searchSpecPtr->all); @@ -5510,12 +5601,12 @@ SearchCore(interp, searchSpecPtr, patObj) int maxExtraLines = 0; int matches = 0; int lastNonOverlap = -1; - + do { Tcl_RegExpInfo info; int match; int lastFullLine = lastOffset; - + match = Tcl_RegExpExecObj(interp, regexp, theLine, firstOffset, 1, ((firstOffset > 0) ? TCL_REG_NOTBOL : 0)); if (match < 0) { @@ -5524,54 +5615,66 @@ SearchCore(interp, searchSpecPtr, patObj) } Tcl_RegExpGetInfo(regexp, &info); - /* - * If we don't have a match, or if we do, but it - * extends to the end of the line, we must try to - * add more lines to get a full greedy match. + /* + * If we don't have a match, or if we do, but it extends to + * the end of the line, we must try to add more lines to get a + * full greedy match. */ - if (!match - || ((info.extendStart == info.matches[0].start) - && (info.matches[0].end == (lastOffset - firstOffset)))) { + + if (!match || + ((info.extendStart == info.matches[0].start) + && (info.matches[0].end == lastOffset-firstOffset))) { int extraLines = 0; int prevFullLine; - /* - * If we find a match that overlaps more than one - * line, we will use this value to determine the - * first allowed starting offset for the following - * search (to avoid overlapping results). + + /* + * If we find a match that overlaps more than one line, we + * will use this value to determine the first allowed + * starting offset for the following search (to avoid + * overlapping results). */ + int lastTotal = lastOffset; - + if ((lastBackwardsLineMatch != -1) - && (lastBackwardsLineMatch == (lineNum + 1))) { + && (lastBackwardsLineMatch == (lineNum + 1))) { lastNonOverlap = lastTotal; } if (info.extendStart < 0) { - /* No multi-line match is possible */ + /* + * No multi-line match is possible. + */ + break; } /* - * We may be able to match if given more text. - * The following 'while' block handles multi-line - * regexp searches. + * We may be able to match if given more text. The + * following 'while' block handles multi-line regexp + * searches. */ + while (1) { prevFullLine = lastTotal; + /* * Move firstOffset to first possible start */ - if (!match) firstOffset += info.extendStart; + + if (!match) { + firstOffset += info.extendStart; + } if (firstOffset >= lastOffset) { /* - * We're being told that the only possible - * new match is starting after the end of - * the line. But, that is the next line which - * we will handle when we look at that line. + * We're being told that the only possible new + * match is starting after the end of the line. + * But, that is the next line which we will handle + * when we look at that line. */ + if (!match && !searchSpecPtr->backwards - && (firstOffset == 0)) { + && (firstOffset == 0)) { extraLinesSearched = extraLines; } break; @@ -5580,128 +5683,145 @@ SearchCore(interp, searchSpecPtr, patObj) if (lineNum + extraLines >= searchSpecPtr->numLines) { break; } + /* - * Add next line, provided we haven't already done so + * Add next line, provided we haven't already done so. */ + if (extraLines > maxExtraLines) { if ((*searchSpecPtr->addLineProc)(lineNum + extraLines, searchSpecPtr, theLine, &lastTotal, &extraLines) == NULL) { /* - * There are no more acceptable lines, so - * we can say we have searched all of these + * There are no more acceptable lines, so we + * can say we have searched all of these. */ + if (!match && !searchSpecPtr->backwards) { extraLinesSearched = extraLines; } break; } + maxExtraLines = extraLines; if ((lastBackwardsLineMatch != -1) - && (lastBackwardsLineMatch + && (lastBackwardsLineMatch == (lineNum + extraLines + 1))) { lastNonOverlap = lastTotal; } } match = Tcl_RegExpExecObj(interp, regexp, theLine, - firstOffset, 1, - ((firstOffset > 0) ? TCL_REG_NOTBOL : 0)); + firstOffset, 1, + ((firstOffset > 0) ? TCL_REG_NOTBOL : 0)); if (match < 0) { code = TCL_ERROR; goto searchDone; } Tcl_RegExpGetInfo(regexp, &info); - /* + /* * Unfortunately there are bugs in Tcl's regexp - * library, which tells us that info.extendStart - * is zero when it should not be (should be -1), - * which makes our task a bit more complicated - * here. We check if there was a match, and the - * end of the match leaves an entire extra line - * unmatched, then we stop searching. Clearly it - * still might sometimes be possible to add more - * text and match again, but Tcl's regexp library - * doesn't tell us that. - * - * This means we often add and search one more - * line than might be necessary if Tcl were able - * to give us a correct value of info.extendStart - * under all circumstances. - */ - if ((match && ((firstOffset + info.matches[0].end) - != lastTotal) - && ((firstOffset + info.matches[0].end) - < prevFullLine)) - || info.extendStart < 0) { + * library, which tells us that info.extendStart is + * zero when it should not be (should be -1), which + * makes our task a bit more complicated here. We + * check if there was a match, and the end of the + * match leaves an entire extra line unmatched, then + * we stop searching. Clearly it still might sometimes + * be possible to add more text and match again, but + * Tcl's regexp library doesn't tell us that. + * + * This means we often add and search one more line + * than might be necessary if Tcl were able to give us + * a correct value of info.extendStart under all + * circumstances. + */ + + if ((match && + firstOffset+info.matches[0].end != lastTotal && + firstOffset+info.matches[0].end < prevFullLine) + || info.extendStart < 0) { break; } + /* - * If there is a match, but that match starts - * after the end of the first line, then we'll - * handle that next time around, when we're - * actually looking at that line. + * If there is a match, but that match starts after + * the end of the first line, then we'll handle that + * next time around, when we're actually looking at + * that line. */ + if (match && (info.matches[0].start >= lastOffset)) { break; } - if (match && ((firstOffset + info.matches[0].end) - >= prevFullLine)) { + if (match && ((firstOffset + info.matches[0].end) + >= prevFullLine)) { extraLinesSearched = extraLines - 1; lastFullLine = prevFullLine; } + /* - * The prefix matches, so keep looking + * The prefix matches, so keep looking. */ + extraLines++; } + /* * If we reach here with 'match == 1', we've found a * multi-line match, which we will record in the code - * which follows directly else we started a - * multi-line match but didn't finish it off, so we - * go to the next line. + * which follows directly else we started a multi-line + * match but didn't finish it off, so we go to the next + * line. */ + if (!match) { - /* + /* * Here is where we could perform an optimisation, - * since we have already retrieved the contents of - * the next line (perhaps many more), so we shouldn't - * really throw it all away and start again. This + * since we have already retrieved the contents of the + * next line (perhaps many more), so we shouldn't + * really throw it all away and start again. This * could be particularly important for complex regexp * searches. - * + * * This 'break' will take us to just before the * 'nextLine:' below. */ + break; } if (lastBackwardsLineMatch != -1) { - if ((lineNum + linesSearched + extraLinesSearched) - == lastBackwardsLineMatch) { - /* Possible overlap or inclusion */ - int thisOffset = firstOffset + info.matches[0].end - - info.matches[0].start; - + if ((lineNum + linesSearched + extraLinesSearched) + == lastBackwardsLineMatch) { + /* + * Possible overlap or inclusion. + */ + + int thisOffset = firstOffset + info.matches[0].end + - info.matches[0].start; + if (lastNonOverlap != -1) { - /* Possible overlap or enclosure */ - if ((thisOffset - lastNonOverlap) - >= (lastBackwardsMatchOffset - + matchLength)) { - /* + /* + * Possible overlap or enclosure. + */ + + if (thisOffset-lastNonOverlap >= + lastBackwardsMatchOffset+matchLength) { + /* * Totally encloses previous match, so - * forget the previous match + * forget the previous match. */ + lastBackwardsLineMatch = -1; - } else if ((thisOffset - lastNonOverlap) - > lastBackwardsMatchOffset) { - /* - * Overlap. Previous match is ok, and - * the current match is only ok if - * we are searching with -overlap. + } else if ((thisOffset - lastNonOverlap) + > lastBackwardsMatchOffset) { + /* + * Overlap. Previous match is ok, and the + * current match is only ok if we are + * searching with -overlap. */ + if (searchSpecPtr->overlap) { goto recordBackwardsMatch; } else { @@ -5709,83 +5829,95 @@ SearchCore(interp, searchSpecPtr, patObj) break; } } else { - /* - * No overlap, although the same - * line was reached. + /* + * No overlap, although the same line was + * reached. */ + goto recordBackwardsMatch; } } else { - /* No overlap */ + /* + * No overlap. + */ + goto recordBackwardsMatch; } - } else if (lineNum + linesSearched + extraLinesSearched - < lastBackwardsLineMatch) { - /* No overlap */ + } else if (lineNum+linesSearched+extraLinesSearched + < lastBackwardsLineMatch) { + /* + * No overlap. + */ + goto recordBackwardsMatch; } else { - /* Totally enclosed */ + /* + * Totally enclosed. + */ + lastBackwardsLineMatch = -1; } } } else { - /* Matched in a single line */ + /* + * Matched in a single line. + */ + if (lastBackwardsLineMatch != -1) { - recordBackwardsMatch: - (*searchSpecPtr->foundMatchProc)(lastBackwardsLineMatch, - searchSpecPtr, NULL, NULL, - lastBackwardsMatchOffset, matchLength); + recordBackwardsMatch: + (*searchSpecPtr->foundMatchProc)( + lastBackwardsLineMatch, searchSpecPtr, NULL, + NULL, lastBackwardsMatchOffset, matchLength); lastBackwardsLineMatch = -1; if (!searchSpecPtr->all) { goto searchDone; } } } - + firstOffset += info.matches[0].start; if (firstOffset >= lastOffset) { break; } /* - * Update our local variables with the match, if we - * haven't yet found anything, or if we're doing '-all' - * or '-backwards' _and_ this match isn't fully enclosed - * in the previous match. + * Update our local variables with the match, if we haven't + * yet found anything, or if we're doing '-all' or + * '-backwards' _and_ this match isn't fully enclosed in the + * previous match. */ - - if (matchOffset == -1 || - ((searchSpecPtr->all || searchSpecPtr->backwards) - && ((firstOffset < matchOffset) - || ((firstOffset + info.matches[0].end - - info.matches[0].start) - > (matchOffset + matchLength)) - ) - ) - ) { + + if (matchOffset == -1 || + ((searchSpecPtr->all || searchSpecPtr->backwards) + && ((firstOffset < matchOffset) + || ((firstOffset + info.matches[0].end + - info.matches[0].start) + > (matchOffset + matchLength))))) { matchOffset = firstOffset; matchLength = info.matches[0].end - info.matches[0].start; if (searchSpecPtr->backwards) { - /* - * To get backwards searches in the correct - * order, we must store them away here. + /* + * To get backwards searches in the correct order, we + * must store them away here. */ + if (matches == matchNum) { - /* - * We've run out of space in our normal - * store, so we must allocate space for - * these backwards matches on the heap. + /* + * We've run out of space in our normal store, so + * we must allocate space for these backwards + * matches on the heap. */ - int *newArray; - newArray = (int*) ckalloc(4*matchNum *sizeof(int)); + + int *newArray = (int *) + ckalloc(4 * matchNum * sizeof(int)); memcpy(newArray, storeMatch, matchNum*sizeof(int)); - memcpy(newArray + 2*matchNum, - storeLength, matchNum*sizeof(int)); + memcpy(newArray + 2*matchNum, storeLength, + matchNum * sizeof(int)); if (storeMatch != smArray) { - ckfree((char*)storeMatch); + ckfree((char *) storeMatch); } matchNum *= 2; storeMatch = newArray; @@ -5795,93 +5927,105 @@ SearchCore(interp, searchSpecPtr, patObj) storeLength[matches] = matchLength; matches++; } else { - /* - * Now actually record the match, but only if we - * are doing an '-all' search. + /* + * Now actually record the match, but only if we are + * doing an '-all' search. */ + if (searchSpecPtr->all && - !(*searchSpecPtr->foundMatchProc)(lineNum, - searchSpecPtr, lineInfo, theLine, matchOffset, - matchLength)) { + !(*searchSpecPtr->foundMatchProc)(lineNum, + searchSpecPtr, lineInfo, theLine, matchOffset, + matchLength)) { /* * We reached the end of the search */ + goto searchDone; } } + /* - * For forward matches, unless we allow overlaps, we - * move this on by the length of the current match so - * that we explicitly disallow overlapping matches. + * For forward matches, unless we allow overlaps, we move + * this on by the length of the current match so that we + * explicitly disallow overlapping matches. */ - if (matchLength > 0 && !searchSpecPtr->overlap - && !searchSpecPtr->backwards) { + + if (matchLength > 0 && !searchSpecPtr->overlap + && !searchSpecPtr->backwards) { firstOffset += matchLength; if (firstOffset >= lastOffset) { - /* + /* * Now, we have to be careful not to find * overlapping matches either on the same or - * following lines. Assume that if we did find - * something, it goes until the last extra line - * we added. - * - * We can break out of the loop, since we know - * no more will be found. + * following lines. Assume that if we did find + * something, it goes until the last extra line we + * added. + * + * We can break out of the loop, since we know no + * more will be found. */ + alreadySearchOffset = firstOffset - lastFullLine; break; } - /* We'll add this on again just below */ + + /* + * We'll add this on again just below. + */ + firstOffset --; } } /* - * Move the starting point on, in case we are doing - * repeated or backwards searches (for the latter, we - * actually do repeated forward searches). + * Move the starting point on, in case we are doing repeated + * or backwards searches (for the latter, we actually do + * repeated forward searches). */ + firstOffset++; } while (searchSpecPtr->backwards || searchSpecPtr->all); if (matches > 0) { - /* + /* * Now we have all the matches in our array, but not stored * with 'foundMatchProc' yet. */ + matches--; matchOffset = storeMatch[matches]; matchLength = storeLength[matches]; while (--matches >= 0) { if (lineNum == searchSpecPtr->stopLine) { - /* - * It appears as if a condition like - * 'if (storeMatch[matches] - * < searchSpecPtr->stopOffset) break;' - * - * might be needed here, but no test case - * has been found which would exercise such - * a problem. + /* + * It appears as if a condition like: + * + * if (storeMatch[matches]<searchSpecPtr->stopOffset) + * break; + * + * might be needed here, but no test case has been + * found which would exercise such a problem. */ } - if (storeMatch[matches] + storeLength[matches] - >= matchOffset + matchLength) { - /* - * The new match totally encloses the previous - * one, so we overwrite the previous one. + if (storeMatch[matches] + storeLength[matches] + >= matchOffset + matchLength) { + /* + * The new match totally encloses the previous one, so + * we overwrite the previous one. */ + matchOffset = storeMatch[matches]; matchLength = storeLength[matches]; continue; } if (!searchSpecPtr->overlap) { - if (storeMatch[matches] + storeLength[matches] - > matchOffset) { + if (storeMatch[matches] + storeLength[matches] + > matchOffset) { continue; } } (*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr, - lineInfo, theLine, matchOffset, matchLength); + lineInfo, theLine, matchOffset, matchLength); if (!searchSpecPtr->all) { goto searchDone; } @@ -5889,13 +6033,14 @@ SearchCore(interp, searchSpecPtr, patObj) matchLength = storeLength[matches]; } if (searchSpecPtr->all && matches > 0) { - /* - * We only need to do this for the '-all' case, - * because just below we will call the - * foundMatchProc for the non-all case + /* + * We only need to do this for the '-all' case, because + * just below we will call the foundMatchProc for the + * non-all case. */ + (*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr, - lineInfo, theLine, matchOffset, matchLength); + lineInfo, theLine, matchOffset, matchLength); } else { lastBackwardsLineMatch = lineNum; lastBackwardsMatchOffset = matchOffset; @@ -5904,18 +6049,17 @@ SearchCore(interp, searchSpecPtr, patObj) } /* - * If the 'all' flag is set, we will already have stored all - * matches, so we just proceed to the next line. + * If the 'all' flag is set, we will already have stored all matches, + * so we just proceed to the next line. * - * If not, and there is a match we need to store that information - * and we are done. + * If not, and there is a match we need to store that information and + * we are done. */ - if ((lastBackwardsLineMatch == -1) - && (matchOffset >= 0) - && !searchSpecPtr->all) { - (*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr, - lineInfo, theLine, matchOffset, matchLength); + if ((lastBackwardsLineMatch == -1) && (matchOffset >= 0) + && !searchSpecPtr->all) { + (*searchSpecPtr->foundMatchProc)(lineNum, searchSpecPtr, lineInfo, + theLine, matchOffset, matchLength); goto searchDone; } @@ -5923,13 +6067,14 @@ SearchCore(interp, searchSpecPtr, patObj) * Go to the next (or previous) line; */ - nextLine: - linesSearched += extraLinesSearched; - + nextLine: + linesSearched += extraLinesSearched; + while (linesSearched-- > 0) { /* * If we have just completed the 'stopLine', we are done */ + if (lineNum == searchSpecPtr->stopLine) { goto searchDone; } @@ -5937,12 +6082,12 @@ SearchCore(interp, searchSpecPtr, patObj) if (searchSpecPtr->backwards) { lineNum--; - if (lastBackwardsLineMatch != -1 - && ((lineNum < 0) || (lineNum + 2 < lastBackwardsLineMatch))) { - (*searchSpecPtr->foundMatchProc)(lastBackwardsLineMatch, - searchSpecPtr, NULL, NULL, - lastBackwardsMatchOffset, - matchLength); + if (lastBackwardsLineMatch != -1 + && ((lineNum < 0) + || (lineNum + 2 < lastBackwardsLineMatch))) { + (*searchSpecPtr->foundMatchProc)(lastBackwardsLineMatch, + searchSpecPtr, NULL, NULL, + lastBackwardsMatchOffset, matchLength); lastBackwardsLineMatch = -1; if (!searchSpecPtr->all) { goto searchDone; @@ -5953,15 +6098,15 @@ SearchCore(interp, searchSpecPtr, patObj) lineNum = searchSpecPtr->numLines-1; } if (!searchSpecPtr->exact) { - /* - * The 'exact' search loops above are designed to - * give us an accurate picture of the number of lines - * which we can skip here. For 'regexp' searches, on - * the other hand, which can match potentially variable - * lengths, we cannot skip multiple lines when searching - * backwards. Therefore we only allow one line to be - * skipped here. + /* + * The 'exact' search loops above are designed to give us + * an accurate picture of the number of lines which we can + * skip here. For 'regexp' searches, on the other hand, + * which can match potentially variable lengths, we cannot + * skip multiple lines when searching backwards. Therefore + * we only allow one line to be skipped here. */ + break; } } else { @@ -5971,11 +6116,12 @@ SearchCore(interp, searchSpecPtr, patObj) } } if (lineNum == searchSpecPtr->startLine && linesSearched > 0) { - /* - * We've just searched all the way round and have - * gone right through the start line without finding - * anything in the last attempt. + /* + * We've just searched all the way round and have gone right + * through the start line without finding anything in the last + * attempt. */ + break; } } @@ -5986,18 +6132,20 @@ SearchCore(interp, searchSpecPtr, patObj) if (lastBackwardsLineMatch != -1) { (*searchSpecPtr->foundMatchProc)(lastBackwardsLineMatch, searchSpecPtr, - NULL, NULL, lastBackwardsMatchOffset, matchLength); + NULL, NULL, lastBackwardsMatchOffset, matchLength); } - + /* * Free up the cached line and pattern */ + Tcl_DecrRefCount(theLine); Tcl_DecrRefCount(patObj); /* * Free up any extra space we allocated */ + if (storeMatch != smArray) { ckfree((char*)storeMatch); } @@ -6010,9 +6158,8 @@ SearchCore(interp, searchSpecPtr, patObj) * * GetLineStartEnd - * - * Converts an internal TkTextLine ptr into a Tcl string obj - * containing the line number. (Handler for the 'line' - * configuration option type) + * Converts an internal TkTextLine ptr into a Tcl string obj containing + * the line number. (Handler for the 'line' configuration option type.) * * Results: * Tcl_Obj containing the string representation of the line value. @@ -6045,16 +6192,15 @@ GetLineStartEnd(clientData, tkwin, recordPtr, internalOffset) * * SetLineStartEnd -- * - * Converts a Tcl_Obj representing a widget's (start or end) line - * into a TkTextLine* value. (Handler for the 'line' configuration - * option type) + * Converts a Tcl_Obj representing a widget's (start or end) line into a + * TkTextLine* value. (Handler for the 'line' configuration option type.) * * Results: * Standard Tcl result. * * Side effects: * May store the TkTextLine* value into the internal representation - * pointer. May change the pointer to the Tcl_Obj to NULL to indicate + * pointer. May change the pointer to the Tcl_Obj to NULL to indicate * that the specified string was empty and that is acceptable. * *---------------------------------------------------------------------- @@ -6067,28 +6213,29 @@ SetLineStartEnd(clientData, interp, tkwin, value, recordPtr, internalOffset, Tcl_Interp *interp; /* Current interp; may be used for errors. */ Tk_Window tkwin; /* Window for which option is being set. */ Tcl_Obj **value; /* Pointer to the pointer to the value object. - * We use a pointer to the pointer because - * we may need to return a value (NULL). */ + * We use a pointer to the pointer because we + * may need to return a value (NULL). */ char *recordPtr; /* Pointer to storage for the widget record. */ int internalOffset; /* Offset within *recordPtr at which the - internal value is to be stored. */ + * internal value is to be stored. */ char *oldInternalPtr; /* Pointer to storage for the old value. */ int flags; /* Flags for the option, set Tk_SetOptions. */ { TkTextLine *linePtr = NULL; char *internalPtr; TkText *textPtr = (TkText*)recordPtr; - + if (internalOffset >= 0) { internalPtr = recordPtr + internalOffset; } else { internalPtr = NULL; } - + if (flags & TK_OPTION_NULL_OK && ObjectIsEmpty(*value)) { *value = NULL; } else { int line; + if (Tcl_GetIntFromObj(interp, *value, &line) != TCL_OK) { return TCL_ERROR; } @@ -6100,15 +6247,15 @@ SetLineStartEnd(clientData, interp, tkwin, value, recordPtr, internalOffset, *((TkTextLine **) internalPtr) = linePtr; } return TCL_OK; -} +} /* *---------------------------------------------------------------------- * * RestoreLineStartEnd -- * - * Restore a line option value from a saved value. (Handler for - * the 'line' configuration option type) + * Restore a line option value from a saved value. (Handler for the + * 'line' configuration option type.) * * Results: * None. @@ -6134,12 +6281,11 @@ RestoreLineStartEnd(clientData, tkwin, internalPtr, oldInternalPtr) * * ObjectIsEmpty -- * - * This procedure tests whether the string value of an object is - * empty. + * This function tests whether the string value of an object is empty. * * Results: - * The return value is 1 if the string value of objPtr has length - * zero, and 0 otherwise. + * The return value is 1 if the string value of objPtr has length zero, + * and 0 otherwise. * * Side effects: * May cause object shimmering, since this function can force a @@ -6150,7 +6296,7 @@ RestoreLineStartEnd(clientData, tkwin, internalPtr, oldInternalPtr) static int ObjectIsEmpty(objPtr) - Tcl_Obj *objPtr; /* Object to test. May be NULL. */ + Tcl_Obj *objPtr; /* Object to test. May be NULL. */ { int length; @@ -6163,3 +6309,11 @@ ObjectIsEmpty(objPtr) Tcl_GetStringFromObj(objPtr, &length); return (length == 0); } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkTextImage.c b/generic/tkTextImage.c index fbbec00..fa95e3c 100644 --- a/generic/tkTextImage.c +++ b/generic/tkTextImage.c @@ -1,16 +1,15 @@ -/* +/* * tkImage.c -- * - * This file contains code that allows images to be - * nested inside text widgets. It also implements the "image" - * widget command for texts. + * This file contains code that allows images to be nested inside text + * widgets. It also implements the "image" widget command for texts. * * Copyright (c) 1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextImage.c,v 1.14 2004/09/10 12:13:41 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextImage.c,v 1.15 2005/08/10 22:02:22 dkf Exp $ */ #include "tk.h" @@ -21,52 +20,52 @@ * Macro that determines the size of an embedded image segment: */ -#define EI_SEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \ - + sizeof(TkTextEmbImage))) +#define EI_SEG_SIZE \ + ((unsigned) (Tk_Offset(TkTextSegment, body) + sizeof(TkTextEmbImage))) /* - * Prototypes for procedures defined in this file: + * Prototypes for functions defined in this file: */ -static TkTextSegment * EmbImageCleanupProc _ANSI_ARGS_((TkTextSegment *segPtr, - TkTextLine *linePtr)); -static void EmbImageCheckProc _ANSI_ARGS_((TkTextSegment *segPtr, - TkTextLine *linePtr)); -static void EmbImageBboxProc _ANSI_ARGS_((TkText *textPtr, - TkTextDispChunk *chunkPtr, - int index, int y, int lineHeight, int baseline, - int *xPtr, int *yPtr, int *widthPtr, - int *heightPtr)); -static int EmbImageConfigure _ANSI_ARGS_((TkText *textPtr, - TkTextSegment *eiPtr, int objc, Tcl_Obj *CONST objv[])); -static int EmbImageDeleteProc _ANSI_ARGS_((TkTextSegment *segPtr, - TkTextLine *linePtr, int treeGone)); -static void EmbImageDisplayProc _ANSI_ARGS_((TkText *textPtr, +static TkTextSegment * EmbImageCleanupProc(TkTextSegment *segPtr, + TkTextLine *linePtr); +static void EmbImageCheckProc(TkTextSegment *segPtr, + TkTextLine *linePtr); +static void EmbImageBboxProc(TkText *textPtr, + TkTextDispChunk *chunkPtr, int index, int y, + int lineHeight, int baseline, int *xPtr, int *yPtr, + int *widthPtr, int *heightPtr); +static int EmbImageConfigure(TkText *textPtr, + TkTextSegment *eiPtr, int objc, + Tcl_Obj *CONST objv[]); +static int EmbImageDeleteProc(TkTextSegment *segPtr, + TkTextLine *linePtr, int treeGone); +static void EmbImageDisplayProc(TkText *textPtr, TkTextDispChunk *chunkPtr, int x, int y, int lineHeight, int baseline, Display *display, - Drawable dst, int screenY)); -static int EmbImageLayoutProc _ANSI_ARGS_((TkText *textPtr, + Drawable dst, int screenY); +static int EmbImageLayoutProc(TkText *textPtr, TkTextIndex *indexPtr, TkTextSegment *segPtr, int offset, int maxX, int maxChars, int noCharsYet, TkWrapMode wrapMode, - TkTextDispChunk *chunkPtr)); -static void EmbImageProc _ANSI_ARGS_((ClientData clientData, - int x, int y, int width, int height, - int imageWidth, int imageHeight)); + TkTextDispChunk *chunkPtr); +static void EmbImageProc(ClientData clientData, int x, int y, + int width, int height, int imageWidth, + int imageHeight); /* * The following structure declares the "embedded image" segment type. */ static Tk_SegType tkTextEmbImageType = { - "image", /* name */ - 0, /* leftGravity */ - (Tk_SegSplitProc *) NULL, /* splitProc */ - EmbImageDeleteProc, /* deleteProc */ - EmbImageCleanupProc, /* cleanupProc */ - (Tk_SegLineChangeProc *) NULL, /* lineChangeProc */ - EmbImageLayoutProc, /* layoutProc */ - EmbImageCheckProc /* checkProc */ + "image", /* name */ + 0, /* leftGravity */ + NULL, /* splitProc */ + EmbImageDeleteProc, /* deleteProc */ + EmbImageCleanupProc, /* cleanupProc */ + NULL, /* lineChangeProc */ + EmbImageLayoutProc, /* layoutProc */ + EmbImageCheckProc /* checkProc */ }; /* @@ -77,7 +76,7 @@ static char *alignStrings[] = { "baseline", "bottom", "center", "top", (char *) NULL }; -typedef enum { +typedef enum { ALIGN_BASELINE, ALIGN_BOTTOM, ALIGN_CENTER, ALIGN_TOP } alignMode; @@ -87,13 +86,13 @@ typedef enum { static Tk_OptionSpec optionSpecs[] = { {TK_OPTION_STRING_TABLE, "-align", (char *) NULL, (char *) NULL, - "center", -1, Tk_Offset(TkTextEmbImage, align), + "center", -1, Tk_Offset(TkTextEmbImage, align), 0, (ClientData) alignStrings, 0}, {TK_OPTION_PIXELS, "-padx", (char *) NULL, (char *) NULL, - "0", -1, Tk_Offset(TkTextEmbImage, padX), + "0", -1, Tk_Offset(TkTextEmbImage, padX), 0, 0, 0}, {TK_OPTION_PIXELS, "-pady", (char *) NULL, (char *) NULL, - "0", -1, Tk_Offset(TkTextEmbImage, padY), + "0", -1, Tk_Offset(TkTextEmbImage, padY), 0, 0, 0}, {TK_OPTION_STRING, "-image", (char *) NULL, (char *) NULL, (char *) NULL, -1, Tk_Offset(TkTextEmbImage, imageString), @@ -110,9 +109,8 @@ static Tk_OptionSpec optionSpecs[] = { * * TkTextImageCmd -- * - * This procedure implements the "image" widget command - * for text widgets. See the user documentation for details - * on what it does. + * This function implements the "image" widget command for text widgets. + * See the user documentation for details on what it does. * * Results: * A standard Tcl result or error. @@ -141,7 +139,7 @@ TkTextImageCmd(textPtr, interp, objc, objv) enum opts { CMD_CGET, CMD_CONF, CMD_CREATE, CMD_NAMES }; - + if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); return TCL_ERROR; @@ -152,7 +150,8 @@ TkTextImageCmd(textPtr, interp, objc, objv) } switch ((enum opts) idx) { case CMD_CGET: { - Tcl_Obj *objPtr; + Tcl_Obj *objPtr; + if (objc != 5) { Tcl_WrongNumArgs(interp, 3, objv, "index option"); return TCL_ERROR; @@ -163,11 +162,11 @@ TkTextImageCmd(textPtr, interp, objc, objv) eiPtr = TkTextIndexToSeg(&index, (int *) NULL); if (eiPtr->typePtr != &tkTextEmbImageType) { Tcl_AppendResult(interp, "no embedded image at index \"", - Tcl_GetString(objv[3]), "\"", (char *) NULL); + Tcl_GetString(objv[3]), "\"", (char *) NULL); return TCL_ERROR; } objPtr = Tk_GetOptionValue(interp, (char *) &eiPtr->body.ei, - eiPtr->body.ei.optionTable, objv[4], textPtr->tkwin); + eiPtr->body.ei.optionTable, objv[4], textPtr->tkwin); if (objPtr == NULL) { return TCL_ERROR; } else { @@ -175,7 +174,7 @@ TkTextImageCmd(textPtr, interp, objc, objv) return TCL_OK; } } - case CMD_CONF: { + case CMD_CONF: if (objc < 4) { Tcl_WrongNumArgs(interp, 3, objv, "index ?option value ...?"); return TCL_ERROR; @@ -186,14 +185,13 @@ TkTextImageCmd(textPtr, interp, objc, objv) eiPtr = TkTextIndexToSeg(&index, (int *) NULL); if (eiPtr->typePtr != &tkTextEmbImageType) { Tcl_AppendResult(interp, "no embedded image at index \"", - Tcl_GetString(objv[3]), "\"", (char *) NULL); + Tcl_GetString(objv[3]), "\"", (char *) NULL); return TCL_ERROR; } if (objc <= 5) { - Tcl_Obj* objPtr = Tk_GetOptionInfo(interp, (char *) &eiPtr->body.ei, - eiPtr->body.ei.optionTable, - (objc == 5) ? objv[4] : (Tcl_Obj *) NULL, - textPtr->tkwin); + Tcl_Obj* objPtr = Tk_GetOptionInfo(interp, + (char *) &eiPtr->body.ei, eiPtr->body.ei.optionTable, + (objc == 5) ? objv[4] : (Tcl_Obj *) NULL, textPtr->tkwin); if (objPtr == NULL) { return TCL_ERROR; } else { @@ -202,23 +200,23 @@ TkTextImageCmd(textPtr, interp, objc, objv) } } else { TkTextChanged(textPtr->sharedTextPtr, NULL, &index, &index); - /* - * It's probably not true that all window configuration - * can change the line height, so we could be more - * efficient here and only call this when necessary. + + /* + * It's probably not true that all window configuration can change + * the line height, so we could be more efficient here and only + * call this when necessary. */ - TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL, - index.linePtr, 0, - TK_TEXT_INVALIDATE_ONLY); + + TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL, + index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY); return EmbImageConfigure(textPtr, eiPtr, objc-4, objv+4); } - } case CMD_CREATE: { int lineIndex; /* - * Add a new image. Find where to put the new image, and - * mark that position for redisplay. + * Add a new image. Find where to put the new image, and mark that + * position for redisplay. */ if (objc < 4) { @@ -232,12 +230,13 @@ TkTextImageCmd(textPtr, interp, objc, objv) /* * Don't allow insertions on the last (dummy) line of the text. */ - + lineIndex = TkBTreeLinesTo(textPtr, index.linePtr); - if (lineIndex == TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr)) { + if (lineIndex == TkBTreeNumLines(textPtr->sharedTextPtr->tree, + textPtr)) { lineIndex--; - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - lineIndex, 1000000, &index); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, + lineIndex, 1000000, &index); } /* @@ -259,8 +258,8 @@ TkTextImageCmd(textPtr, interp, objc, objv) eiPtr->body.ei.optionTable = Tk_CreateOptionTable(interp, optionSpecs); /* - * Link the segment into the text widget, then configure it (delete - * it again if the configuration fails). + * Link the segment into the text widget, then configure it (delete it + * again if the configuration fails). */ TkTextChanged(textPtr->sharedTextPtr, NULL, &index, &index); @@ -272,9 +271,8 @@ TkTextImageCmd(textPtr, interp, objc, objv) TkBTreeDeleteChars(textPtr->sharedTextPtr->tree, &index, &index2); return TCL_ERROR; } - TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL, - index.linePtr, 0, - TK_TEXT_INVALIDATE_ONLY); + TkTextInvalidateLineMetrics(textPtr->sharedTextPtr, NULL, + index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY); return TCL_OK; } case CMD_NAMES: { @@ -285,8 +283,8 @@ TkTextImageCmd(textPtr, interp, objc, objv) Tcl_WrongNumArgs(interp, 3, objv, NULL); return TCL_ERROR; } - for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->imageTable, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->imageTable, + &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { Tcl_AppendElement(interp, Tcl_GetHashKey(&textPtr->sharedTextPtr->markTable, hPtr)); } @@ -303,24 +301,24 @@ TkTextImageCmd(textPtr, interp, objc, objv) * * EmbImageConfigure -- * - * This procedure is called to handle configuration options - * for an embedded image, using an objc/objv list. + * This function is called to handle configuration options for an + * embedded image, using an objc/objv list. * * Results: - * The return value is a standard Tcl result. If TCL_ERROR is - * returned, then the interp's result contains an error message.. + * The return value is a standard Tcl result. If TCL_ERROR is returned, + * then the interp's result contains an error message.. * * Side effects: - * Configuration information for the embedded image changes, - * such as alignment, or name of the image. + * Configuration information for the embedded image changes, such as + * alignment, or name of the image. * *-------------------------------------------------------------- */ static int EmbImageConfigure(textPtr, eiPtr, objc, objv) - TkText *textPtr; /* Information about text widget that - * contains embedded image. */ + TkText *textPtr; /* Information about text widget that contains + * embedded image. */ TkTextSegment *eiPtr; /* Embedded image to be configured. */ int objc; /* Number of strings in objv. */ Tcl_Obj *CONST objv[]; /* Array of strings describing configuration @@ -335,24 +333,23 @@ EmbImageConfigure(textPtr, eiPtr, objc, objv) int count = 0; /* The counter for picking a unique name */ int conflict = 0; /* True if we have a name conflict */ unsigned int len; /* length of image name */ - - if (Tk_SetOptions(textPtr->interp, (char*)&eiPtr->body.ei, + + if (Tk_SetOptions(textPtr->interp, (char*)&eiPtr->body.ei, eiPtr->body.ei.optionTable, objc, objv, textPtr->tkwin, NULL, NULL) != TCL_OK) { return TCL_ERROR; } /* - * Create the image. Save the old image around and don't free it - * until after the new one is allocated. This keeps the reference - * count from going to zero so the image doesn't have to be recreated - * if it hasn't changed. + * Create the image. Save the old image around and don't free it until + * after the new one is allocated. This keeps the reference count from + * going to zero so the image doesn't have to be recreated if it hasn't + * changed. */ if (eiPtr->body.ei.imageString != NULL) { - image = Tk_GetImage(textPtr->interp, textPtr->tkwin, - eiPtr->body.ei.imageString, EmbImageProc, - (ClientData) eiPtr); + image = Tk_GetImage(textPtr->interp, textPtr->tkwin, + eiPtr->body.ei.imageString, EmbImageProc, (ClientData) eiPtr); if (image == NULL) { return TCL_ERROR; } @@ -368,10 +365,10 @@ EmbImageConfigure(textPtr, eiPtr, objc, objv) return TCL_OK; } - /* - * Find a unique name for this image. Use imageName (or imageString) - * if available, otherwise tack on a #nn and use it. If a name is - * already associated with this image, delete the name. + /* + * Find a unique name for this image. Use imageName (or imageString) if + * available, otherwise tack on a #nn and use it. If a name is already + * associated with this image, delete the name. */ name = eiPtr->body.ei.imageName; @@ -379,16 +376,17 @@ EmbImageConfigure(textPtr, eiPtr, objc, objv) name = eiPtr->body.ei.imageString; } if (name == NULL) { - Tcl_AppendResult(textPtr->interp,"Either a \"-name\" ", + Tcl_AppendResult(textPtr->interp,"Either a \"-name\" ", "or a \"-image\" argument must be provided ", - "to the \"image create\" subcommand.", - (char *) NULL); + "to the \"image create\" subcommand.", (char *) NULL); return TCL_ERROR; } len = strlen(name); - for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->imageTable, &search); - hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { - char *haveName = Tcl_GetHashKey(&textPtr->sharedTextPtr->imageTable, hPtr); + for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->imageTable, + &search); hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) { + char *haveName = + Tcl_GetHashKey(&textPtr->sharedTextPtr->imageTable, hPtr); + if (strncmp(name, haveName, len) == 0) { new = 0; sscanf(haveName+len, "#%d", &new); @@ -406,11 +404,12 @@ EmbImageConfigure(textPtr, eiPtr, objc, objv) if (conflict) { char buf[4 + TCL_INTEGER_SPACE]; + sprintf(buf, "#%d", count+1); Tcl_DStringAppend(&newName, buf, -1); } name = Tcl_DStringValue(&newName); - hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->imageTable, name, &new); + hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->imageTable, name,&new); Tcl_SetHashValue(hPtr, eiPtr); Tcl_AppendResult(textPtr->interp, name , (char *) NULL); eiPtr->body.ei.name = ckalloc((unsigned) Tcl_DStringLength(&newName)+1); @@ -425,8 +424,8 @@ EmbImageConfigure(textPtr, eiPtr, objc, objv) * * EmbImageDeleteProc -- * - * This procedure is invoked by the text B-tree code whenever - * an embedded image lies in a range of characters being deleted. + * This function is invoked by the text B-tree code whenever an embedded + * image lies in a range of characters being deleted. * * Results: * Returns 0 to indicate that the deletion has been accepted. @@ -441,11 +440,11 @@ EmbImageConfigure(textPtr, eiPtr, objc, objv) /* ARGSUSED */ static int EmbImageDeleteProc(eiPtr, linePtr, treeGone) - TkTextSegment *eiPtr; /* Segment being deleted. */ - TkTextLine *linePtr; /* Line containing segment. */ - int treeGone; /* Non-zero means the entire tree is - * being deleted, so everything must - * get cleaned up. */ + TkTextSegment *eiPtr; /* Segment being deleted. */ + TkTextLine *linePtr; /* Line containing segment. */ + int treeGone; /* Non-zero means the entire tree is being + * deleted, so everything must get cleaned + * up. */ { Tcl_HashEntry *hPtr; @@ -463,12 +462,14 @@ EmbImageDeleteProc(eiPtr, linePtr, treeGone) } Tk_FreeImage(eiPtr->body.ei.image); } - /* - * No need to supply a tkwin argument, since we have no - * window-specific options. + + /* + * No need to supply a tkwin argument, since we have no window-specific + * options. */ + Tk_FreeConfigOptions((char *) &eiPtr->body.ei, eiPtr->body.ei.optionTable, - NULL); + NULL); ckfree((char *) eiPtr); return 0; } @@ -478,9 +479,8 @@ EmbImageDeleteProc(eiPtr, linePtr, treeGone) * * EmbImageCleanupProc -- * - * This procedure is invoked by the B-tree code whenever a - * segment containing an embedded image is moved from one - * line to another. + * This function is invoked by the B-tree code whenever a segment + * containing an embedded image is moved from one line to another. * * Results: * None. @@ -493,8 +493,8 @@ EmbImageDeleteProc(eiPtr, linePtr, treeGone) static TkTextSegment * EmbImageCleanupProc(eiPtr, linePtr) - TkTextSegment *eiPtr; /* Mark segment that's being moved. */ - TkTextLine *linePtr; /* Line that now contains segment. */ + TkTextSegment *eiPtr; /* Mark segment that's being moved. */ + TkTextLine *linePtr; /* Line that now contains segment. */ { eiPtr->body.ei.linePtr = linePtr; return eiPtr; @@ -505,12 +505,11 @@ EmbImageCleanupProc(eiPtr, linePtr) * * EmbImageLayoutProc -- * - * This procedure is the "layoutProc" for embedded image - * segments. + * This function is the "layoutProc" for embedded image segments. * * Results: - * 1 is returned to indicate that the segment should be - * displayed. The chunkPtr structure is filled in. + * 1 is returned to indicate that the segment should be displayed. The + * chunkPtr structure is filled in. * * Side effects: * None, except for filling in chunkPtr. @@ -529,16 +528,17 @@ EmbImageLayoutProc(textPtr, indexPtr, eiPtr, offset, maxX, maxChars, * indexPtr (always 0). */ int maxX; /* Chunk must not occupy pixels at this * position or higher. */ - int maxChars; /* Chunk must not include more than this - * many characters. */ + int maxChars; /* Chunk must not include more than this many + * characters. */ int noCharsYet; /* Non-zero means no characters have been * assigned to this line yet. */ - TkWrapMode wrapMode; /* Wrap mode to use for line: TEXT_WRAPMODE_CHAR, - * TEXT_WRAPMODE_NONE, or TEXT_WRAPMODE_WORD. */ + TkWrapMode wrapMode; /* Wrap mode to use for line: + * TEXT_WRAPMODE_CHAR, TEXT_WRAPMODE_NONE, or + * TEXT_WRAPMODE_WORD. */ register TkTextDispChunk *chunkPtr; - /* Structure to fill in with information - * about this chunk. The x field has already - * been set by the caller. */ + /* Structure to fill in with information about + * this chunk. The x field has already been + * set by the caller. */ { int width, height; @@ -594,29 +594,30 @@ EmbImageLayoutProc(textPtr, indexPtr, eiPtr, offset, maxX, maxChars, * * EmbImageCheckProc -- * - * This procedure is invoked by the B-tree code to perform - * consistency checks on embedded images. + * This function is invoked by the B-tree code to perform consistency + * checks on embedded images. * * Results: * None. * * Side effects: - * The procedure panics if it detects anything wrong with - * the embedded image. + * The function panics if it detects anything wrong with the embedded + * image. * *-------------------------------------------------------------- */ static void EmbImageCheckProc(eiPtr, linePtr) - TkTextSegment *eiPtr; /* Segment to check. */ - TkTextLine *linePtr; /* Line containing segment. */ + TkTextSegment *eiPtr; /* Segment to check. */ + TkTextLine *linePtr; /* Line containing segment. */ { if (eiPtr->nextPtr == NULL) { Tcl_Panic("EmbImageCheckProc: embedded image is last segment in line"); } if (eiPtr->size != 1) { - Tcl_Panic("EmbImageCheckProc: embedded image has size %d", eiPtr->size); + Tcl_Panic("EmbImageCheckProc: embedded image has size %d", + eiPtr->size); } } @@ -625,39 +626,36 @@ EmbImageCheckProc(eiPtr, linePtr) * * EmbImageDisplayProc -- * - * This procedure is invoked by the text displaying code - * when it is time to actually draw an embedded image - * chunk on the screen. + * This function is invoked by the text displaying code when it is time + * to actually draw an embedded image chunk on the screen. * * Results: * None. * * Side effects: - * The embedded image gets moved to the correct location - * and drawn onto the display. + * The embedded image gets moved to the correct location and drawn onto + * the display. * *-------------------------------------------------------------- */ static void -EmbImageDisplayProc(textPtr, chunkPtr, x, y, lineHeight, baseline, display, - dst, screenY) +EmbImageDisplayProc(textPtr, chunkPtr, x, y, lineHeight, baseline, display, + dst, screenY) TkText *textPtr; - TkTextDispChunk *chunkPtr; /* Chunk that is to be drawn. */ - int x; /* X-position in dst at which to - * draw this chunk (differs from - * the x-position in the chunk because - * of scrolling). */ - int y; /* Top of rectangular bounding box - * for line: tells where to draw this - * chunk in dst (x-position is in - * the chunk itself). */ - int lineHeight; /* Total height of line. */ - int baseline; /* Offset of baseline from y. */ - Display *display; /* Display to use for drawing. */ - Drawable dst; /* Pixmap or window in which to draw */ - int screenY; /* Y-coordinate in text window that - * corresponds to y. */ + TkTextDispChunk *chunkPtr; /* Chunk that is to be drawn. */ + int x; /* X-position in dst at which to draw this + * chunk (differs from the x-position in the + * chunk because of scrolling). */ + int y; /* Top of rectangular bounding box for line: + * tells where to draw this chunk in dst + * (x-position is in the chunk itself). */ + int lineHeight; /* Total height of line. */ + int baseline; /* Offset of baseline from y. */ + Display *display; /* Display to use for drawing. */ + Drawable dst; /* Pixmap or window in which to draw */ + int screenY; /* Y-coordinate in text window that + * corresponds to y. */ { TkTextSegment *eiPtr = (TkTextSegment *) chunkPtr->clientData; int lineX, imageX, imageY, width, height; @@ -672,16 +670,15 @@ EmbImageDisplayProc(textPtr, chunkPtr, x, y, lineHeight, baseline, display, } /* - * Compute the image's location and size in the text widget, taking - * into account the align value for the image. + * Compute the image's location and size in the text widget, taking into + * account the align value for the image. */ EmbImageBboxProc(textPtr, chunkPtr, 0, y, lineHeight, baseline, &lineX, &imageY, &width, &height); imageX = lineX - chunkPtr->x + x; - Tk_RedrawImage(image, 0, 0, width, height, dst, - imageX, imageY); + Tk_RedrawImage(image, 0, 0, width, height, dst, imageX, imageY); } /* @@ -689,17 +686,16 @@ EmbImageDisplayProc(textPtr, chunkPtr, x, y, lineHeight, baseline, display, * * EmbImageBboxProc -- * - * This procedure is called to compute the bounding box of - * the area occupied by an embedded image. + * This function is called to compute the bounding box of the area + * occupied by an embedded image. * * Results: - * There is no return value. *xPtr and *yPtr are filled in - * with the coordinates of the upper left corner of the - * image, and *widthPtr and *heightPtr are filled in with - * the dimensions of the image in pixels. Note: not all - * of the returned bbox is necessarily visible on the screen - * (the rightmost part might be off-screen to the right, - * and the bottommost part might be off-screen to the bottom). + * There is no return value. *xPtr and *yPtr are filled in with the + * coordinates of the upper left corner of the image, and *widthPtr and + * *heightPtr are filled in with the dimensions of the image in pixels. + * Note: not all of the returned bbox is necessarily visible on the + * screen (the rightmost part might be off-screen to the right, and the + * bottommost part might be off-screen to the bottom). * * Side effects: * None. @@ -711,20 +707,20 @@ static void EmbImageBboxProc(textPtr, chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr, widthPtr, heightPtr) TkText *textPtr; - TkTextDispChunk *chunkPtr; /* Chunk containing desired char. */ - int index; /* Index of desired character within - * the chunk. */ - int y; /* Topmost pixel in area allocated - * for this line. */ - int lineHeight; /* Total height of line. */ - int baseline; /* Location of line's baseline, in - * pixels measured down from y. */ - int *xPtr, *yPtr; /* Gets filled in with coords of - * character's upper-left pixel. */ - int *widthPtr; /* Gets filled in with width of - * image, in pixels. */ - int *heightPtr; /* Gets filled in with height of - * image, in pixels. */ + TkTextDispChunk *chunkPtr; /* Chunk containing desired char. */ + int index; /* Index of desired character within the + * chunk. */ + int y; /* Topmost pixel in area allocated for this + * line. */ + int lineHeight; /* Total height of line. */ + int baseline; /* Location of line's baseline, in pixels + * measured down from y. */ + int *xPtr, *yPtr; /* Gets filled in with coords of character's + * upper-left pixel. */ + int *widthPtr; /* Gets filled in with width of image, in + * pixels. */ + int *heightPtr; /* Gets filled in with height of image, in + * pixels. */ { TkTextSegment *eiPtr = (TkTextSegment *) chunkPtr->clientData; Tk_Image image; @@ -736,20 +732,22 @@ EmbImageBboxProc(textPtr, chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr, *widthPtr = 0; *heightPtr = 0; } + *xPtr = chunkPtr->x + eiPtr->body.ei.padX; + switch (eiPtr->body.ei.align) { - case ALIGN_BOTTOM: - *yPtr = y + (lineHeight - *heightPtr - eiPtr->body.ei.padY); - break; - case ALIGN_CENTER: - *yPtr = y + (lineHeight - *heightPtr)/2; - break; - case ALIGN_TOP: - *yPtr = y + eiPtr->body.ei.padY; - break; - case ALIGN_BASELINE: - *yPtr = y + (baseline - *heightPtr); - break; + case ALIGN_BOTTOM: + *yPtr = y + (lineHeight - *heightPtr - eiPtr->body.ei.padY); + break; + case ALIGN_CENTER: + *yPtr = y + (lineHeight - *heightPtr)/2; + break; + case ALIGN_TOP: + *yPtr = y + eiPtr->body.ei.padY; + break; + case ALIGN_BASELINE: + *yPtr = y + (baseline - *heightPtr); + break; } } @@ -758,14 +756,13 @@ EmbImageBboxProc(textPtr, chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr, * * TkTextImageIndex -- * - * Given the name of an embedded image within a text widget, - * returns an index corresponding to the image's position - * in the text. + * Given the name of an embedded image within a text widget, returns an + * index corresponding to the image's position in the text. * * Results: - * The return value is 1 if there is an embedded image by - * the given name in the text widget, 0 otherwise. If the - * image exists, *indexPtr is filled in with its index. + * The return value is 1 if there is an embedded image by the given name + * in the text widget, 0 otherwise. If the image exists, *indexPtr is + * filled in with its index. * * Side effects: * None. @@ -776,7 +773,7 @@ EmbImageBboxProc(textPtr, chunkPtr, index, y, lineHeight, baseline, xPtr, yPtr, int TkTextImageIndex(textPtr, name, indexPtr) TkText *textPtr; /* Text widget containing image. */ - CONST char *name; /* Name of image. */ + CONST char *name; /* Name of image. */ TkTextIndex *indexPtr; /* Index information gets stored here. */ { Tcl_HashEntry *hPtr; @@ -798,8 +795,8 @@ TkTextImageIndex(textPtr, name, indexPtr) * * EmbImageProc -- * - * This procedure is called by the image code whenever an - * image or its contents changes. + * This function is called by the image code whenever an image or its + * contents changes. * * Results: * None. @@ -812,12 +809,12 @@ TkTextImageIndex(textPtr, name, indexPtr) static void EmbImageProc(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. */ + 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. */ { TkTextSegment *eiPtr = (TkTextSegment *) clientData; @@ -827,11 +824,21 @@ EmbImageProc(clientData, x, y, width, height, imgWidth, imgHeight) index.linePtr = eiPtr->body.ei.linePtr; index.byteIndex = TkTextSegToOffset(eiPtr, eiPtr->body.ei.linePtr); TkTextChanged(eiPtr->body.ei.sharedTextPtr, NULL, &index, &index); - /* - * It's probably not true that all image changes - * can change the line height, so we could be more - * efficient here and only call this when necessary. + + /* + * It's probably not true that all image changes can change the line + * height, so we could be more efficient here and only call this when + * necessary. */ - TkTextInvalidateLineMetrics(eiPtr->body.ei.sharedTextPtr, NULL, - index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY); + + TkTextInvalidateLineMetrics(eiPtr->body.ei.sharedTextPtr, NULL, + index.linePtr, 0, TK_TEXT_INVALIDATE_ONLY); } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkTextIndex.c b/generic/tkTextIndex.c index e9469ee..127b397 100644 --- a/generic/tkTextIndex.c +++ b/generic/tkTextIndex.c @@ -1,16 +1,16 @@ -/* +/* * tkTextIndex.c -- * - * This module provides procedures that manipulate indices for - * text widgets. + * This module provides functions that manipulate indices for text + * widgets. * * Copyright (c) 1992-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextIndex.c,v 1.21 2005/02/14 23:00:46 vincentdarley Exp $ + * RCS: @(#) $Id: tkTextIndex.c,v 1.22 2005/08/10 22:02:22 dkf Exp $ */ #include "default.h" @@ -27,62 +27,72 @@ /* * Modifiers for index parsing: 'display', 'any' or nothing. */ -#define TKINDEX_NONE 0 -#define TKINDEX_DISPLAY 1 -#define TKINDEX_ANY 2 + +#define TKINDEX_NONE 0 +#define TKINDEX_DISPLAY 1 +#define TKINDEX_ANY 2 /* - * Forward declarations for procedures defined later in this file: + * Forward declarations for functions defined later in this file: */ -static CONST char * ForwBack _ANSI_ARGS_((TkText *textPtr, - CONST char *string, TkTextIndex *indexPtr)); -static CONST char * StartEnd _ANSI_ARGS_((TkText *textPtr, - CONST char *string, TkTextIndex *indexPtr)); -static int GetIndex _ANSI_ARGS_((Tcl_Interp *interp, - TkSharedText *sharedPtr, TkText *textPtr, - CONST char *string, - TkTextIndex *indexPtr, int *canCachePtr)); +static CONST char * ForwBack(TkText *textPtr, CONST char *string, + TkTextIndex *indexPtr); +static CONST char * StartEnd(TkText *textPtr, CONST char *string, + TkTextIndex *indexPtr); +static int GetIndex(Tcl_Interp *interp, TkSharedText *sharedPtr, + TkText *textPtr, CONST char *string, + TkTextIndex *indexPtr, int *canCachePtr); /* * The "textindex" Tcl_Obj definition: */ -static void DupTextIndexInternalRep _ANSI_ARGS_((Tcl_Obj *srcPtr, - Tcl_Obj *copyPtr)); -static void FreeTextIndexInternalRep _ANSI_ARGS_((Tcl_Obj *listPtr)); -static int SetTextIndexFromAny _ANSI_ARGS_((Tcl_Interp *interp, - Tcl_Obj *objPtr)); -static void UpdateStringOfTextIndex _ANSI_ARGS_((Tcl_Obj *objPtr)); +static void DupTextIndexInternalRep(Tcl_Obj *srcPtr, + Tcl_Obj *copyPtr); +static void FreeTextIndexInternalRep(Tcl_Obj *listPtr); +static int SetTextIndexFromAny(Tcl_Interp *interp, + Tcl_Obj *objPtr); +static void UpdateStringOfTextIndex(Tcl_Obj *objPtr); + +/* + * Accessor macros for the "textindex" type. + */ #define GET_TEXTINDEX(objPtr) \ - ((TkTextIndex *) (objPtr)->internalRep.twoPtrValue.ptr1) + ((TkTextIndex *) (objPtr)->internalRep.twoPtrValue.ptr1) #define GET_INDEXEPOCH(objPtr) \ - ((int) (objPtr)->internalRep.twoPtrValue.ptr2) + ((int) (objPtr)->internalRep.twoPtrValue.ptr2) #define SET_TEXTINDEX(objPtr, indexPtr) \ - (objPtr)->internalRep.twoPtrValue.ptr1 = (VOID*) (indexPtr) + ((objPtr)->internalRep.twoPtrValue.ptr1 = (VOID *) (indexPtr)) #define SET_INDEXEPOCH(objPtr, epoch) \ - (objPtr)->internalRep.twoPtrValue.ptr2 = (VOID*) (epoch) + ((objPtr)->internalRep.twoPtrValue.ptr2 = (VOID *) (epoch)) + /* - * Define the 'textindex' object type, which Tk uses to represent - * indices in text widgets internally. + * Define the 'textindex' object type, which Tk uses to represent indices in + * text widgets internally. */ + Tcl_ObjType tkTextIndexType = { - "textindex", /* name */ - FreeTextIndexInternalRep, /* freeIntRepProc */ - DupTextIndexInternalRep, /* dupIntRepProc */ - NULL, /* updateStringProc */ - SetTextIndexFromAny /* setFromAnyProc */ + "textindex", /* name */ + FreeTextIndexInternalRep, /* freeIntRepProc */ + DupTextIndexInternalRep, /* dupIntRepProc */ + NULL, /* updateStringProc */ + SetTextIndexFromAny /* setFromAnyProc */ }; - + static void FreeTextIndexInternalRep(indexObjPtr) - Tcl_Obj *indexObjPtr; /* TextIndex object with internal rep to free. */ + Tcl_Obj *indexObjPtr; /* TextIndex object with internal rep to + * free. */ { TkTextIndex *indexPtr = GET_TEXTINDEX(indexObjPtr); if (indexPtr->textPtr != NULL) { - if (--indexPtr->textPtr->refCount == 0) { - /* The text widget has been deleted and we need to free it now */ + if (--indexPtr->textPtr->refCount == 0) { + /* + * The text widget has been deleted and we need to free it now. + */ + ckfree((char *) (indexPtr->textPtr)); } } @@ -99,19 +109,21 @@ DupTextIndexInternalRep(srcPtr, copyPtr) dupIndexPtr = (TkTextIndex*) ckalloc(sizeof(TkTextIndex)); indexPtr = GET_TEXTINDEX(srcPtr); epoch = GET_INDEXEPOCH(srcPtr); - + dupIndexPtr->tree = indexPtr->tree; dupIndexPtr->linePtr = indexPtr->linePtr; dupIndexPtr->byteIndex = indexPtr->byteIndex; - + SET_TEXTINDEX(copyPtr, dupIndexPtr); SET_INDEXEPOCH(copyPtr, epoch); } -/* - * This will not be called except by TkTextNewIndexObj below. - * This is because if a TkTextIndex is no longer valid, it is - * not possible to regenerate the string representation. + +/* + * This will not be called except by TkTextNewIndexObj below. This is because + * if a TkTextIndex is no longer valid, it is not possible to regenerate the + * string representation. */ + static void UpdateStringOfTextIndex(objPtr) Tcl_Obj *objPtr; @@ -127,14 +139,15 @@ UpdateStringOfTextIndex(objPtr) strcpy(objPtr->bytes, buffer); objPtr->length = len; } + static int SetTextIndexFromAny(interp, objPtr) Tcl_Interp *interp; /* Used for error reporting if not NULL. */ Tcl_Obj *objPtr; /* The object to convert. */ { Tcl_AppendToObj(Tcl_GetObjResult(interp), - "can't convert value to textindex except via TkTextGetIndexFromObj API", - -1); + "can't convert value to textindex except via TkTextGetIndexFromObj API", + -1); return TCL_ERROR; } @@ -142,19 +155,19 @@ SetTextIndexFromAny(interp, objPtr) *--------------------------------------------------------------------------- * * MakeObjIndex -- - * - * This procedure generates a Tcl_Obj description of an index, - * suitable for reading in again later. If the 'textPtr' is NULL - * then we still generate an index object, but it's internal - * description is deemed non-cacheable, and therefore effectively - * useless (apart from as a temporary memory storage). This is used - * for indices whose meaning is very temporary (like @0,0 or the - * name of a mark or tag). The mapping from such strings/objects to - * actual TkTextIndex pointers is not stable to minor text widget - * changes which we do not track (we track insertions/deletions). + * + * This function generates a Tcl_Obj description of an index, suitable + * for reading in again later. If the 'textPtr' is NULL then we still + * generate an index object, but it's internal description is deemed + * non-cacheable, and therefore effectively useless (apart from as a + * temporary memory storage). This is used for indices whose meaning is + * very temporary (like @0,0 or the name of a mark or tag). The mapping + * from such strings/objects to actual TkTextIndex pointers is not stable + * to minor text widget changes which we do not track (we track + * insertions/deletions). * * Results: - * A pointer to an allocated TkTextIndex which will be freed + * A pointer to an allocated TkTextIndex which will be freed * automatically when the Tcl_Obj is used for other purposes. * * Side effects: @@ -162,13 +175,15 @@ SetTextIndexFromAny(interp, objPtr) * *--------------------------------------------------------------------------- */ -static TkTextIndex* -MakeObjIndex(textPtr, objPtr, origPtr) + +static TkTextIndex * +MakeObjIndex(textPtr, objPtr, origPtr) TkText *textPtr; /* Information about text widget. */ - Tcl_Obj *objPtr; /* Object containing description of position. */ - CONST TkTextIndex *origPtr; /* Pointer to index. */ + Tcl_Obj *objPtr; /* Object containing description of + * position. */ + CONST TkTextIndex *origPtr; /* Pointer to index. */ { - TkTextIndex *indexPtr = (TkTextIndex*) ckalloc(sizeof(TkTextIndex)); + TkTextIndex *indexPtr = (TkTextIndex *) ckalloc(sizeof(TkTextIndex)); indexPtr->tree = origPtr->tree; indexPtr->linePtr = origPtr->linePtr; @@ -190,18 +205,19 @@ CONST TkTextIndex* TkTextGetIndexFromObj(interp, textPtr, objPtr) Tcl_Interp *interp; /* Use this for error reporting. */ TkText *textPtr; /* Information about text widget. */ - Tcl_Obj *objPtr; /* Object containing description of position. */ + Tcl_Obj *objPtr; /* Object containing description of + * position. */ { TkTextIndex index; TkTextIndex *indexPtr = NULL; int cache; - + if (objPtr->typePtr == &tkTextIndexType) { int epoch; - + indexPtr = GET_TEXTINDEX(objPtr); epoch = GET_INDEXEPOCH(objPtr); - + if (epoch == textPtr->sharedTextPtr->stateEpoch) { if (indexPtr->textPtr == textPtr) { return indexPtr; @@ -209,17 +225,17 @@ TkTextGetIndexFromObj(interp, textPtr, objPtr) } } - /* - * The object is either not an index type or referred to a different - * text widget, or referred to the correct widget, but it is out of - * date (text has been added/deleted since). + /* + * The object is either not an index type or referred to a different text + * widget, or referred to the correct widget, but it is out of date (text + * has been added/deleted since). */ - - if (GetIndex(interp, NULL, textPtr, Tcl_GetString(objPtr), - &index, &cache) != TCL_OK) { + + if (GetIndex(interp, NULL, textPtr, Tcl_GetString(objPtr), &index, + &cache) != TCL_OK) { return NULL; } - + if (objPtr->typePtr != NULL) { if (objPtr->bytes == NULL) { objPtr->typePtr->updateStringProc(objPtr); @@ -228,7 +244,7 @@ TkTextGetIndexFromObj(interp, textPtr, objPtr) (*objPtr->typePtr->freeIntRepProc)(objPtr); } } - + if (cache) { return MakeObjIndex(textPtr, objPtr, &index); } else { @@ -240,11 +256,10 @@ TkTextGetIndexFromObj(interp, textPtr, objPtr) *--------------------------------------------------------------------------- * * TkTextNewIndexObj -- - * - * This procedure generates a Tcl_Obj description of an index, - * suitable for reading in again later. The index generated is - * effectively stable to all except insertion/deletion operations on - * the widget. + * + * This function generates a Tcl_Obj description of an index, suitable + * for reading in again later. The index generated is effectively stable + * to all except insertion/deletion operations on the widget. * * Results: * A new Tcl_Obj with refCount zero. @@ -257,25 +272,27 @@ TkTextGetIndexFromObj(interp, textPtr, objPtr) Tcl_Obj* TkTextNewIndexObj(textPtr, indexPtr) - TkText *textPtr; /* text widget for this index */ - CONST TkTextIndex *indexPtr; /* Pointer to index. */ + TkText *textPtr; /* Text widget for this index */ + CONST TkTextIndex *indexPtr;/* Pointer to index. */ { Tcl_Obj *retVal; retVal = Tcl_NewObj(); retVal->bytes = NULL; - /* - * Assumption that the above call returns an object with + /* + * Assumption that the above call returns an object with: * retVal->typePtr == NULL */ + MakeObjIndex(textPtr, retVal, indexPtr); - - /* - * Unfortunately, it isn't possible for us to regenerate the - * string representation so we have to create it here, while we - * can be sure the contents of the index are still valid. + + /* + * Unfortunately, it isn't possible for us to regenerate the string + * representation so we have to create it here, while we can be sure the + * contents of the index are still valid. */ + UpdateStringOfTextIndex(retVal); return retVal; } @@ -285,23 +302,22 @@ TkTextNewIndexObj(textPtr, indexPtr) * * TkTextMakePixelIndex -- * - * Given a pixel index and a byte index, look things up in the B-tree - * and fill in a TkTextIndex structure. - * - * The valid input range for pixelIndex is from 0 to the number - * of pixels in the widget-1. Anything outside that range will - * be rounded to the closest acceptable value. + * Given a pixel index and a byte index, look things up in the B-tree and + * fill in a TkTextIndex structure. + * + * The valid input range for pixelIndex is from 0 to the number of pixels + * in the widget-1. Anything outside that range will be rounded to the + * closest acceptable value. * * Results: - * - * The structure at *indexPtr is filled in with information about - * the character at pixelIndex (or the closest existing character, - * if the specified one doesn't exist), and the number of excess - * pixels is returned as a result. This means if the given pixel - * index is exactly correct for the top-edge of the indexPtr, then - * zero will be returned, and otherwise we will return the - * calculation 'desired pixelIndex' - 'actual pixel index of - * indexPtr'. + * + * The structure at *indexPtr is filled in with information about the + * character at pixelIndex (or the closest existing character, if the + * specified one doesn't exist), and the number of excess pixels is + * returned as a result. This means if the given pixel index is exactly + * correct for the top-edge of the indexPtr, then zero will be returned, + * and otherwise we will return the calculation 'desired pixelIndex' - + * 'actual pixel index of indexPtr'. * * Side effects: * None. @@ -312,7 +328,7 @@ TkTextNewIndexObj(textPtr, indexPtr) int TkTextMakePixelIndex(textPtr, pixelIndex, indexPtr) TkText* textPtr; /* The Text Widget */ - int pixelIndex; /* pixel-index of desired line (0 means first + int pixelIndex; /* Pixel-index of desired line (0 means first * pixel of first line of text). */ TkTextIndex *indexPtr; /* Structure to fill in. */ { @@ -320,24 +336,24 @@ TkTextMakePixelIndex(textPtr, pixelIndex, indexPtr) indexPtr->tree = textPtr->sharedTextPtr->tree; indexPtr->textPtr = textPtr; - + if (pixelIndex < 0) { pixelIndex = 0; } - indexPtr->linePtr = TkBTreeFindPixelLine(textPtr->sharedTextPtr->tree, - textPtr, - pixelIndex, - &pixelOffset); - /* - * 'pixedlIndex' was too large, so we try again, just to find - * the last pixel in the window + indexPtr->linePtr = TkBTreeFindPixelLine(textPtr->sharedTextPtr->tree, + textPtr, pixelIndex, &pixelOffset); + + /* + * 'pixelIndex' was too large, so we try again, just to find the last + * pixel in the window */ + if (indexPtr->linePtr == NULL) { int lastMinusOne = TkBTreeNumPixels(textPtr->sharedTextPtr->tree, - textPtr)-1; - indexPtr->linePtr = TkBTreeFindPixelLine(textPtr->sharedTextPtr->tree, - textPtr, - lastMinusOne, &pixelOffset); + textPtr)-1; + + indexPtr->linePtr = TkBTreeFindPixelLine(textPtr->sharedTextPtr->tree, + textPtr, lastMinusOne, &pixelOffset); indexPtr->byteIndex = 0; return pixelOffset; } @@ -354,8 +370,8 @@ TkTextMakePixelIndex(textPtr, pixelIndex, indexPtr) * * TkTextMakeByteIndex -- * - * Given a line index and a byte index, look things up in the B-tree - * and fill in a TkTextIndex structure. + * Given a line index and a byte index, look things up in the B-tree and + * fill in a TkTextIndex structure. * * Results: * The structure at *indexPtr is filled in with information about the @@ -374,8 +390,8 @@ TkTextMakeByteIndex(tree, textPtr, lineIndex, byteIndex, indexPtr) TkTextBTree tree; /* Tree that lineIndex and byteIndex refer * to. */ CONST TkText *textPtr; - int lineIndex; /* Index of desired line (0 means first - * line of text). */ + int lineIndex; /* Index of desired line (0 means first line + * of text). */ int byteIndex; /* Byte index of desired character. */ TkTextIndex *indexPtr; /* Structure to fill in. */ { @@ -394,8 +410,8 @@ TkTextMakeByteIndex(tree, textPtr, lineIndex, byteIndex, indexPtr) } indexPtr->linePtr = TkBTreeFindLine(tree, textPtr, lineIndex); if (indexPtr->linePtr == NULL) { - indexPtr->linePtr = TkBTreeFindLine(tree, textPtr, - TkBTreeNumLines(tree, textPtr)); + indexPtr->linePtr = TkBTreeFindLine(tree, textPtr, + TkBTreeNumLines(tree, textPtr)); byteIndex = 0; } if (byteIndex == 0) { @@ -404,19 +420,19 @@ TkTextMakeByteIndex(tree, textPtr, lineIndex, byteIndex, indexPtr) } /* - * Verify that the index is within the range of the line and points - * to a valid character boundary. + * Verify that the index is within the range of the line and points to a + * valid character boundary. */ index = 0; for (segPtr = indexPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr) { if (segPtr == NULL) { /* - * Use the index of the last character in the line. Since - * the last character on the line is guaranteed to be a '\n', - * we can back up a constant sizeof(char) bytes. + * Use the index of the last character in the line. Since the last + * character on the line is guaranteed to be a '\n', we can back + * up a constant sizeof(char) bytes. */ - + indexPtr->byteIndex = index - sizeof(char); break; } @@ -425,7 +441,7 @@ TkTextMakeByteIndex(tree, textPtr, lineIndex, byteIndex, indexPtr) if ((byteIndex > index) && (segPtr->typePtr == &tkTextCharType)) { /* * Prevent UTF-8 character from being split up by ensuring - * that byteIndex falls on a character boundary. If index + * that byteIndex falls on a character boundary. If index * falls in the middle of a UTF-8 character, it will be * adjusted to the end of that UTF-8 character. */ @@ -447,8 +463,8 @@ TkTextMakeByteIndex(tree, textPtr, lineIndex, byteIndex, indexPtr) * * TkTextMakeCharIndex -- * - * Given a line index and a character index, look things up in the - * B-tree and fill in a TkTextIndex structure. + * Given a line index and a character index, look things up in the B-tree + * and fill in a TkTextIndex structure. * * Results: * The structure at *indexPtr is filled in with information about the @@ -467,8 +483,8 @@ TkTextMakeCharIndex(tree, textPtr, lineIndex, charIndex, indexPtr) TkTextBTree tree; /* Tree that lineIndex and charIndex refer * to. */ TkText *textPtr; - int lineIndex; /* Index of desired line (0 means first - * line of text). */ + int lineIndex; /* Index of desired line (0 means first line + * of text). */ int charIndex; /* Index of desired character. */ TkTextIndex *indexPtr; /* Structure to fill in. */ { @@ -487,25 +503,25 @@ TkTextMakeCharIndex(tree, textPtr, lineIndex, charIndex, indexPtr) } indexPtr->linePtr = TkBTreeFindLine(tree, textPtr, lineIndex); if (indexPtr->linePtr == NULL) { - indexPtr->linePtr = TkBTreeFindLine(tree, textPtr, - TkBTreeNumLines(tree, textPtr)); + indexPtr->linePtr = TkBTreeFindLine(tree, textPtr, + TkBTreeNumLines(tree, textPtr)); charIndex = 0; } /* - * Verify that the index is within the range of the line. - * If not, just use the index of the last character in the line. + * Verify that the index is within the range of the line. If not, just use + * the index of the last character in the line. */ index = 0; for (segPtr = indexPtr->linePtr->segPtr; ; segPtr = segPtr->nextPtr) { if (segPtr == NULL) { /* - * Use the index of the last character in the line. Since - * the last character on the line is guaranteed to be a '\n', - * we can back up a constant sizeof(char) bytes. + * Use the index of the last character in the line. Since the last + * character on the line is guaranteed to be a '\n', we can back + * up a constant sizeof(char) bytes. */ - + indexPtr->byteIndex = index - sizeof(char); break; } @@ -542,14 +558,14 @@ TkTextMakeCharIndex(tree, textPtr, lineIndex, charIndex, indexPtr) * * TkTextIndexToSeg -- * - * Given an index, this procedure returns the segment and offset - * within segment for the index. + * Given an index, this function returns the segment and offset within + * segment for the index. * * Results: - * The return value is a pointer to the segment referred to by - * indexPtr; this will always be a segment with non-zero size. The - * variable at *offsetPtr is set to hold the integer offset within - * the segment of the character given by indexPtr. + * The return value is a pointer to the segment referred to by indexPtr; + * this will always be a segment with non-zero size. The variable at + * *offsetPtr is set to hold the integer offset within the segment of the + * character given by indexPtr. * * Side effects: * None. @@ -582,7 +598,7 @@ TkTextIndexToSeg(indexPtr, offsetPtr) * * TkTextSegToOffset -- * - * Given a segment pointer and the line containing it, this procedure + * Given a segment pointer and the line containing it, this function * returns the offset of the segment within its line. * * Results: @@ -615,16 +631,16 @@ TkTextSegToOffset(segPtr, linePtr) *--------------------------------------------------------------------------- * * TkTextGetObjIndex -- - * - * Simpler wrapper around the string based function, but could be - * enhanced with a new object type in the future. + * + * Simpler wrapper around the string based function, but could be + * enhanced with a new object type in the future. * * Results: - * see TkTextGetIndex + * see TkTextGetIndex * * Side effects: - * None. - * + * None. + * *--------------------------------------------------------------------------- */ @@ -632,27 +648,28 @@ int TkTextGetObjIndex(interp, textPtr, idxObj, indexPtr) Tcl_Interp *interp; /* Use this for error reporting. */ TkText *textPtr; /* Information about text widget. */ - Tcl_Obj *idxObj; /* Object containing textual description - * of position. */ + Tcl_Obj *idxObj; /* Object containing textual description of + * position. */ TkTextIndex *indexPtr; /* Index structure to fill in. */ { - return GetIndex(interp, NULL, textPtr, Tcl_GetString(idxObj), indexPtr, NULL); + return GetIndex(interp, NULL, textPtr, Tcl_GetString(idxObj), indexPtr, + NULL); } /* *--------------------------------------------------------------------------- * * TkTextSharedGetObjIndex -- - * - * Simpler wrapper around the string based function, but could be - * enhanced with a new object type in the future. + * + * Simpler wrapper around the string based function, but could be + * enhanced with a new object type in the future. * * Results: - * see TkTextGetIndex + * see TkTextGetIndex * * Side effects: - * None. - * + * None. + * *--------------------------------------------------------------------------- */ @@ -660,12 +677,12 @@ int TkTextSharedGetObjIndex(interp, sharedTextPtr, idxObj, indexPtr) Tcl_Interp *interp; /* Use this for error reporting. */ TkSharedText *sharedTextPtr;/* Information about text widget. */ - Tcl_Obj *idxObj; /* Object containing textual description - * of position. */ + Tcl_Obj *idxObj; /* Object containing textual description of + * position. */ TkTextIndex *indexPtr; /* Index structure to fill in. */ { - return GetIndex(interp, sharedTextPtr, NULL, - Tcl_GetString(idxObj), indexPtr, NULL); + return GetIndex(interp, sharedTextPtr, NULL, Tcl_GetString(idxObj), + indexPtr, NULL); } /* @@ -676,10 +693,10 @@ TkTextSharedGetObjIndex(interp, sharedTextPtr, idxObj, indexPtr) * Given a string, return the index that is described. * * Results: - * The return value is a standard Tcl return result. If TCL_OK is + * The return value is a standard Tcl return result. If TCL_OK is * returned, then everything went well and the index at *indexPtr is - * filled in; otherwise TCL_ERROR is returned and an error message - * is left in the interp's result. + * filled in; otherwise TCL_ERROR is returned and an error message is + * left in the interp's result. * * Side effects: * None. @@ -705,14 +722,14 @@ TkTextGetIndex(interp, textPtr, string, indexPtr) * Given a string, return the index that is described. * * Results: - * The return value is a standard Tcl return result. If TCL_OK is + * The return value is a standard Tcl return result. If TCL_OK is * returned, then everything went well and the index at *indexPtr is - * filled in; otherwise TCL_ERROR is returned and an error message - * is left in the interp's result. - * - * If *canCachePtr is non-NULL, and everything went well, the - * integer it points to is set to 1 if the indexPtr is something - * which can be cached, and zero otherwise. + * filled in; otherwise TCL_ERROR is returned and an error message is + * left in the interp's result. + * + * If *canCachePtr is non-NULL, and everything went well, the integer it + * points to is set to 1 if the indexPtr is something which can be + * cached, and zero otherwise. * * Side effects: * None. @@ -727,8 +744,8 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) TkText *textPtr; /* Information about text widget. */ CONST char *string; /* Textual description of position. */ TkTextIndex *indexPtr; /* Index structure to fill in. */ - int *canCachePtr; /* Pointer to integer to store whether - * we can cache the index (or NULL) */ + int *canCachePtr; /* Pointer to integer to store whether we can + * cache the index (or NULL). */ { char *p, *end, *endOfBase; TkTextIndex first, last; @@ -737,17 +754,16 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) CONST char *cp; Tcl_DString copy; int canCache = 0; - + if (sharedPtr == NULL) { sharedPtr = textPtr->sharedTextPtr; } - + /* *--------------------------------------------------------------------- - * Stage 1: check to see if the index consists of nothing but a mark - * name. We do this check now even though it's also done later, in - * order to allow mark names that include funny characters such as - * spaces or "+1c". + * Stage 1: check to see if the index consists of nothing but a mark name. + * We do this check now even though it's also done later, in order to + * allow mark names that include funny characters such as spaces or "+1c". *--------------------------------------------------------------------- */ @@ -764,11 +780,11 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) indexPtr->tree = sharedPtr->tree; /* - * First look for the form "tag.first" or "tag.last" where "tag" - * is the name of a valid tag. Try to use up as much as possible - * of the string in this check (strrchr instead of strchr below). - * Doing the check now, and in this way, allows tag names to include - * funny characters like "@" or "+1c". + * First look for the form "tag.first" or "tag.last" where "tag" is the + * name of a valid tag. Try to use up as much as possible of the string in + * this check (strrchr instead of strchr below). Doing the check now, and + * in this way, allows tag names to include funny characters like "@" or + * "+1c". */ Tcl_DStringInit(©); @@ -778,7 +794,7 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) TkTextTag *tagPtr; Tcl_HashEntry *hPtr = NULL; CONST char *tagName; - + if ((p[1] == 'f') && (strncmp(p+1, "first", 5) == 0)) { wantLast = 0; endOfBase = p+6; @@ -788,13 +804,14 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) } else { goto tryxy; } + tagPtr = NULL; tagName = Tcl_DStringValue(©); if (((p - tagName) == 3) && !strncmp(tagName, "sel", 3)) { - /* - * Special case for sel tag which is not stored in - * the hash table. + /* + * Special case for sel tag which is not stored in the hash table. */ + tagPtr = textPtr->selTagPtr; } else { *p = 0; @@ -804,17 +821,18 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); } } + if (tagPtr == NULL) { goto tryxy; } + TkTextMakeByteIndex(sharedPtr->tree, textPtr, 0, 0, &first); - TkTextMakeByteIndex(sharedPtr->tree, textPtr, - TkBTreeNumLines(sharedPtr->tree, textPtr), - 0, &last); + TkTextMakeByteIndex(sharedPtr->tree, textPtr, + TkBTreeNumLines(sharedPtr->tree, textPtr), 0, &last); TkBTreeStartSearch(&first, &last, tagPtr, &search); if (!TkBTreeCharTagged(&first, tagPtr) && !TkBTreeNextTag(&search)) { if (tagPtr == textPtr->selTagPtr) { - tagName = "sel"; + tagName = "sel"; } else { tagName = Tcl_GetHashKey(&sharedPtr->tagTable, hPtr); } @@ -834,7 +852,7 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) goto gotBase; } - tryxy: + tryxy: if (string[0] == '@') { /* * Find character at a given x,y location in the window. @@ -854,7 +872,7 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) } TkTextPixelIndex(textPtr, x, y, indexPtr, NULL); endOfBase = end; - goto gotBase; + goto gotBase; } if (isdigit(UCHAR(string[0])) || (string[0] == '-')) { @@ -879,8 +897,8 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) } endOfBase = end; } - TkTextMakeCharIndex(sharedPtr->tree, textPtr, lineIndex, - charIndex, indexPtr); + TkTextMakeCharIndex(sharedPtr->tree, textPtr, lineIndex, charIndex, + indexPtr); canCache = 1; goto gotBase; } @@ -912,8 +930,7 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) */ TkTextMakeByteIndex(sharedPtr->tree, textPtr, - TkBTreeNumLines(sharedPtr->tree, textPtr), - 0, indexPtr); + TkBTreeNumLines(sharedPtr->tree, textPtr), 0, indexPtr); canCache = 1; goto gotBase; } else { @@ -946,14 +963,14 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) /* *------------------------------------------------------------------- - * Stage 3: process zero or more modifiers. Each modifier is either - * a keyword like "wordend" or "linestart", or it has the form - * "op count units" where op is + or -, count is a number, and units - * is "chars" or "lines". + * Stage 3: process zero or more modifiers. Each modifier is either a + * keyword like "wordend" or "linestart", or it has the form "op count + * units" where op is + or -, count is a number, and units is "chars" or + * "lines". *------------------------------------------------------------------- */ - gotBase: + gotBase: cp = endOfBase; while (1) { while (isspace(UCHAR(*cp))) { @@ -962,7 +979,7 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) if (*cp == 0) { break; } - + if ((*cp == '+') || (*cp == '-')) { cp = ForwBack(textPtr, cp, indexPtr); } else { @@ -973,7 +990,8 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) } } Tcl_DStringFree(©); - done: + + done: if (canCachePtr != NULL) { *canCachePtr = canCache; } @@ -982,11 +1000,10 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) } return TCL_OK; - error: + error: Tcl_DStringFree(©); Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "bad text index \"", string, "\"", - (char *) NULL); + Tcl_AppendResult(interp, "bad text index \"", string, "\"", (char *)NULL); return TCL_ERROR; } @@ -994,13 +1011,13 @@ GetIndex(interp, sharedPtr, textPtr, string, indexPtr, canCachePtr) *--------------------------------------------------------------------------- * * TkTextPrintIndex -- - * - * This procedure generates a string description of an index, suitable - * for reading in again later. + * + * This function generates a string description of an index, suitable for + * reading in again later. * * Results: - * The characters pointed to by string are modified. Returns the - * number of characters in the string. + * The characters pointed to by string are modified. Returns the number + * of characters in the string. * * Side effects: * None. @@ -1012,8 +1029,8 @@ int TkTextPrintIndex(textPtr, indexPtr, string) CONST TkText *textPtr; CONST TkTextIndex *indexPtr;/* Pointer to index. */ - char *string; /* Place to store the position. Must have - * at least TK_POS_CHARS characters. */ + char *string; /* Place to store the position. Must have at + * least TK_POS_CHARS characters. */ { TkTextSegment *segPtr; TkTextLine *linePtr; @@ -1022,12 +1039,14 @@ TkTextPrintIndex(textPtr, indexPtr, string) numBytes = indexPtr->byteIndex; charIndex = 0; linePtr = indexPtr->linePtr; + for (segPtr = linePtr->segPtr; ; segPtr = segPtr->nextPtr) { if (segPtr == NULL) { - /* - * Two logical lines merged into one display line - * through eliding of a newline + /* + * Two logical lines merged into one display line through eliding + * of a newline. */ + linePtr = TkBTreeNextLine(NULL, linePtr); segPtr = linePtr->segPtr; } @@ -1041,14 +1060,15 @@ TkTextPrintIndex(textPtr, indexPtr, string) } numBytes -= segPtr->size; } + if (segPtr->typePtr == &tkTextCharType) { charIndex += Tcl_NumUtfChars(segPtr->body.chars, numBytes); } else { charIndex += numBytes; } - return sprintf(string, "%d.%d", - TkBTreeLinesTo(textPtr, indexPtr->linePtr) + 1, - charIndex); + + return sprintf(string, "%d.%d", + TkBTreeLinesTo(textPtr, indexPtr->linePtr) + 1, charIndex); } /* @@ -1085,13 +1105,14 @@ TkTextIndexCmp(index1Ptr, index2Ptr) return 0; } } - /* - * Assumption here that it is ok for comparisons to reflect - * the full B-tree and not just the portion that is available - * to any client. This should be true because the only - * indexPtr's we should be given are ones which are valid - * for the current client. + + /* + * Assumption here that it is ok for comparisons to reflect the full + * B-tree and not just the portion that is available to any client. This + * should be true because the only indexPtr's we should be given are ones + * which are valid for the current client. */ + line1 = TkBTreeLinesTo(NULL, index1Ptr->linePtr); line2 = TkBTreeLinesTo(NULL, index2Ptr->linePtr); if (line1 < line2) { @@ -1108,14 +1129,14 @@ TkTextIndexCmp(index1Ptr, index2Ptr) * * ForwBack -- * - * This procedure handles +/- modifiers for indices to adjust the - * index forwards or backwards. + * This function handles +/- modifiers for indices to adjust the index + * forwards or backwards. * * Results: - * If the modifier in string is successfully parsed then the return - * value is the address of the first character after the modifier, - * and *indexPtr is updated to reflect the modifier. If there is a - * syntax error in the modifier then NULL is returned. + * If the modifier in string is successfully parsed then the return value + * is the address of the first character after the modifier, and + * *indexPtr is updated to reflect the modifier. If there is a syntax + * error in the modifier then NULL is returned. * * Side effects: * None. @@ -1126,10 +1147,9 @@ TkTextIndexCmp(index1Ptr, index2Ptr) static CONST char * ForwBack(textPtr, string, indexPtr) TkText *textPtr; /* Information about text widget. */ - CONST char *string; /* String to parse for additional info - * about modifier (count and units). - * Points to "+" or "-" that starts - * modifier. */ + CONST char *string; /* String to parse for additional info about + * modifier (count and units). Points to "+" + * or "-" that starts modifier. */ TkTextIndex *indexPtr; /* Index to update as specified in string. */ { register CONST char *p, *units; @@ -1155,28 +1175,27 @@ ForwBack(textPtr, string, indexPtr) } /* - * Find the end of this modifier (next space or + or - character), - * then check if there is a textual 'display' or 'any' modifier. - * These modifiers can be their own word (in which case they can - * be abbreviated) or they can follow on to the actual unit in - * a single word (in which case no abbreviation is allowed). So, - * 'display lines', 'd lines', 'displaylin' are all ok, but 'dline' - * is not. + * Find the end of this modifier (next space or + or - character), then + * check if there is a textual 'display' or 'any' modifier. These + * modifiers can be their own word (in which case they can be abbreviated) + * or they can follow on to the actual unit in a single word (in which + * case no abbreviation is allowed). So, 'display lines', 'd lines', + * 'displaylin' are all ok, but 'dline' is not. */ - units = p; + units = p; while ((*p != '\0') && !isspace(UCHAR(*p)) && (*p != '+') && (*p != '-')) { p++; } length = p - units; - if ((*units == 'd') && (strncmp(units, "display", + if ((*units == 'd') && (strncmp(units, "display", (length > 7 ? 7 : length)) == 0)) { modifier = TKINDEX_DISPLAY; if (length > 7) { p -= (length - 7); } - } else if ((*units == 'a') && (strncmp(units, "any", - (length > 3 ? 3 : length)) == 0)) { + } else if ((*units == 'a') && + (strncmp(units, "any", (length > 3 ? 3 : length)) == 0)) { modifier = TKINDEX_ANY; if (length > 3) { p -= (length - 3); @@ -1185,16 +1204,17 @@ ForwBack(textPtr, string, indexPtr) modifier = TKINDEX_NONE; } - /* - * If we had a modifier, which we interpreted ok, so now forward - * to the actual units. + /* + * If we had a modifier, which we interpreted ok, so now forward to the + * actual units. */ + if (modifier != TKINDEX_NONE) { while (isspace(UCHAR(*p))) { p++; } - units = p; - while ((*p != '\0') && !isspace(UCHAR(*p)) && (*p != '+') && (*p != '-')) { + units = p; + while (*p!='\0' && !isspace(UCHAR(*p)) && *p!='+' && *p!='-') { p++; } length = p - units; @@ -1203,8 +1223,10 @@ ForwBack(textPtr, string, indexPtr) /* * Finally parse the units. */ + if ((*units == 'c') && (strncmp(units, "chars", length) == 0)) { TkTextCountType type; + if (modifier == TKINDEX_NONE) { type = COUNT_INDICES; } else if (modifier == TKINDEX_ANY) { @@ -1212,6 +1234,7 @@ ForwBack(textPtr, string, indexPtr) } else { type = COUNT_DISPLAY_CHARS; } + if (*string == '+') { TkTextIndexForwChars(textPtr, indexPtr, count, indexPtr, type); } else { @@ -1219,11 +1242,13 @@ ForwBack(textPtr, string, indexPtr) } } else if ((*units == 'i') && (strncmp(units, "indices", length) == 0)) { TkTextCountType type; + if (modifier == TKINDEX_DISPLAY) { type = COUNT_DISPLAY_INDICES; } else { type = COUNT_INDICES; } + if (*string == '+') { TkTextIndexForwChars(textPtr, indexPtr, count, indexPtr, type); } else { @@ -1231,68 +1256,79 @@ ForwBack(textPtr, string, indexPtr) } } else if ((*units == 'l') && (strncmp(units, "lines", length) == 0)) { if (modifier == TKINDEX_DISPLAY) { - /* + /* * Find the appropriate pixel offset of the current position - * within its display line. This also has the side-effect of - * moving indexPtr, but that doesn't matter since we will do - * it again below. - * - * Then find the right display line, and finally calculated - * the index we want in that display line, based on the - * original pixel offset. + * within its display line. This also has the side-effect of + * moving indexPtr, but that doesn't matter since we will do it + * again below. + * + * Then find the right display line, and finally calculated the + * index we want in that display line, based on the original pixel + * offset. */ + int xOffset, forward; + if (TkTextIsElided(textPtr, indexPtr, NULL)) { - /* Go forward to the first non-elided index */ - TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr, - COUNT_DISPLAY_INDICES); + /* + * Go forward to the first non-elided index. + */ + + TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr, + COUNT_DISPLAY_INDICES); } - /* - * Unlike the Forw/BackChars code, the display line code - * is sensitive to whether we are genuinely going - * forwards or backwards. So, we need to determine that. - * This is important in the case where we have "+ -3 - * displaylines", for example. + + /* + * Unlike the Forw/BackChars code, the display line code is + * sensitive to whether we are genuinely going forwards or + * backwards. So, we need to determine that. This is important in + * the case where we have "+ -3 displaylines", for example. */ + if ((count < 0) ^ (*string == '-')) { forward = 0; } else { forward = 1; } + count = abs(count); if (count == 0) { return p; } + if (forward) { TkTextFindDisplayLineEnd(textPtr, indexPtr, 1, &xOffset); while (count-- > 0) { - /* - * Go to the end of the line, then forward one - * char/byte to get to the beginning of the next - * line. + /* + * Go to the end of the line, then forward one char/byte + * to get to the beginning of the next line. */ + TkTextFindDisplayLineEnd(textPtr, indexPtr, 1, NULL); - TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr, - COUNT_DISPLAY_INDICES); + TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr, + COUNT_DISPLAY_INDICES); } } else { TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, &xOffset); while (count-- > 0) { - /* + /* * Go to the beginning of the line, then backward one * char/byte to get to the end of the previous line */ + TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, NULL); - TkTextIndexBackChars(textPtr, indexPtr, 1, indexPtr, - COUNT_DISPLAY_INDICES); + TkTextIndexBackChars(textPtr, indexPtr, 1, indexPtr, + COUNT_DISPLAY_INDICES); } TkTextFindDisplayLineEnd(textPtr, indexPtr, 0, NULL); } - /* + + /* * This call assumes indexPtr is the beginning of a display line * and moves it to the 'xOffset' position of that line, which is * just what we want. */ + TkTextIndexOfX(textPtr, xOffset, indexPtr); } else { lineIndex = TkBTreeLinesTo(textPtr, indexPtr->linePtr); @@ -1302,31 +1338,29 @@ ForwBack(textPtr, string, indexPtr) lineIndex -= count; /* - * The check below retains the character position, even - * if the line runs off the start of the file. Without - * it, the character position will get reset to 0 by - * TkTextMakeIndex. + * The check below retains the character position, even if the + * line runs off the start of the file. Without it, the + * character position will get reset to 0 by TkTextMakeIndex. */ if (lineIndex < 0) { lineIndex = 0; } } + /* * This doesn't work quite right if using a proportional font or - * UTF-8 characters with varying numbers of bytes, or if there - * are embedded windows, images, etc. The cursor will bop - * around, keeping a constant number of bytes (not characters) - * from the left edge (but making sure not to split any UTF-8 - * characters), regardless of the x-position the index - * corresponds to. The proper way to do this is to get the - * x-position of the index and then pick the character at the - * same x-position in the new line. + * UTF-8 characters with varying numbers of bytes, or if there are + * embedded windows, images, etc. The cursor will bop around, + * keeping a constant number of bytes (not characters) from the + * left edge (but making sure not to split any UTF-8 characters), + * regardless of the x-position the index corresponds to. The + * proper way to do this is to get the x-position of the index and + * then pick the character at the same x-position in the new line. */ - TkTextMakeByteIndex(indexPtr->tree, textPtr, - lineIndex, indexPtr->byteIndex, - indexPtr); + TkTextMakeByteIndex(indexPtr->tree, textPtr, lineIndex, + indexPtr->byteIndex, indexPtr); } } else { return NULL; @@ -1339,16 +1373,16 @@ ForwBack(textPtr, string, indexPtr) * * TkTextIndexForwBytes -- * - * Given an index for a text widget, this procedure creates a new - * index that points "count" bytes ahead of the source index. + * Given an index for a text widget, this function creates a new index + * that points "count" bytes ahead of the source index. * * Results: * *dstPtr is modified to refer to the character "count" bytes after - * srcPtr, or to the last character in the TkText if there aren't - * "count" bytes left. - * - * In this latter case, the function returns '1' to indicate - * that not all of 'byteCount' could be used. + * srcPtr, or to the last character in the TkText if there aren't "count" + * bytes left. + * + * In this latter case, the function returns '1' to indicate that not all + * of 'byteCount' could be used. * * Side effects: * None. @@ -1360,7 +1394,7 @@ int TkTextIndexForwBytes(textPtr, srcPtr, byteCount, dstPtr) CONST TkText *textPtr; CONST TkTextIndex *srcPtr; /* Source index. */ - int byteCount; /* How many bytes forward to move. May be + int byteCount; /* How many bytes forward to move. May be * negative. */ TkTextIndex *dstPtr; /* Destination index: gets modified. */ { @@ -1387,8 +1421,8 @@ TkTextIndexForwBytes(textPtr, srcPtr, byteCount, dstPtr) } /* - * If the new index is in the same line then we're done. - * Otherwise go on to the next line. + * If the new index is in the same line then we're done. Otherwise go + * on to the next line. */ if (dstPtr->byteIndex < lineLength) { @@ -1409,19 +1443,18 @@ TkTextIndexForwBytes(textPtr, srcPtr, byteCount, dstPtr) * * TkTextIndexForwChars -- * - * Given an index for a text widget, this procedure creates a new - * index that points "count" items of type given by "type" ahead of - * the source index. "count" can be zero, which is useful in - * the case where one wishes to move forward by display - * (non-elided) chars or indices or one wishes to move forward - * by chars, skipping any intervening indices. In this case - * dstPtr will point to the first acceptable index which is + * Given an index for a text widget, this function creates a new index + * that points "count" items of type given by "type" ahead of the source + * index. "count" can be zero, which is useful in the case where one + * wishes to move forward by display (non-elided) chars or indices or one + * wishes to move forward by chars, skipping any intervening indices. In + * this case dstPtr will point to the first acceptable index which is * encountered. * * Results: - * *dstPtr is modified to refer to the character "count" items - * after srcPtr, or to the last character in the TkText if there - * aren't sufficient items left in the widget. + * *dstPtr is modified to refer to the character "count" items after + * srcPtr, or to the last character in the TkText if there aren't + * sufficient items left in the widget. * * Side effects: * None. @@ -1431,12 +1464,12 @@ TkTextIndexForwBytes(textPtr, srcPtr, byteCount, dstPtr) void TkTextIndexForwChars(textPtr, srcPtr, charCount, dstPtr, type) - CONST TkText *textPtr; /* Overall information about text widget. */ + CONST TkText *textPtr; /* Overall information about text widget. */ CONST TkTextIndex *srcPtr; /* Source index. */ - int charCount; /* How many characters forward to move. - * May be negative. */ + int charCount; /* How many characters forward to move. May + * be negative. */ TkTextIndex *dstPtr; /* Destination index: gets modified. */ - TkTextCountType type; /* The type of item to count */ + TkTextCountType type; /* The type of item to count */ { TkTextLine *linePtr; TkTextSegment *segPtr; @@ -1446,7 +1479,7 @@ TkTextIndexForwChars(textPtr, srcPtr, charCount, dstPtr, type) Tcl_UniChar ch; int elide = 0; int checkElided = (type & COUNT_DISPLAY); - + if (charCount < 0) { TkTextIndexBackChars(textPtr, srcPtr, -charCount, dstPtr, type); return; @@ -1459,21 +1492,22 @@ TkTextIndexForwChars(textPtr, srcPtr, charCount, dstPtr, type) *dstPtr = *srcPtr; /* - * Find seg that contains src byteIndex. - * Move forward specified number of chars. + * Find seg that contains src byteIndex. Move forward specified number of + * chars. */ if (checkElided) { - /* - * In this case we have already calculated the information - * we need, so no need to use TkTextIndexToSeg() + /* + * In this case we have already calculated the information we need, so + * no need to use TkTextIndexToSeg() */ + segPtr = infoPtr->segPtr; byteOffset = dstPtr->byteIndex - infoPtr->segOffset; } else { segPtr = TkTextIndexToSeg(dstPtr, &byteOffset); } - + while (1) { /* * Go through each segment in line looking for specified character @@ -1483,61 +1517,62 @@ TkTextIndexForwChars(textPtr, srcPtr, charCount, dstPtr, type) for ( ; segPtr != NULL; segPtr = segPtr->nextPtr) { /* * If we do need to pay attention to the visibility of - * characters/indices, check that first. If the current - * segment isn't visible, then we simply continue the - * loop + * characters/indices, check that first. If the current segment + * isn't visible, then we simply continue the loop */ - if (checkElided) { - if ((segPtr->typePtr == &tkTextToggleOffType) - || (segPtr->typePtr == &tkTextToggleOnType)) { - TkTextTag *tagPtr = segPtr->body.toggle.tagPtr; - /* - * The elide state only changes if this tag is - * either the current highest priority tag - * (and is therefore being toggled off), or it's - * a new tag with higher priority. - */ - if (tagPtr->elideString != NULL) { - infoPtr->tagCnts[tagPtr->priority]++; - if (infoPtr->tagCnts[tagPtr->priority] & 1) { - infoPtr->tagPtrs[tagPtr->priority] = tagPtr; - } - if (tagPtr->priority >= infoPtr->elidePriority) { - if (segPtr->typePtr == &tkTextToggleOffType) { - /* - * If it is being toggled off, and it has - * an elide string, it must actually be the - * current highest priority tag, so this - * check is redundant: - */ - if (tagPtr->priority != infoPtr->elidePriority) { - Tcl_Panic("Bad tag priority being toggled off"); - } - - /* - * Find previous elide tag, if any (if not - * then elide will be zero, of course). - */ - elide = 0; - while (--infoPtr->elidePriority > 0) { - if (infoPtr->tagCnts[infoPtr->elidePriority] + + if (checkElided && ((segPtr->typePtr == &tkTextToggleOffType) + || (segPtr->typePtr == &tkTextToggleOnType))) { + TkTextTag *tagPtr = segPtr->body.toggle.tagPtr; + + /* + * The elide state only changes if this tag is either the + * current highest priority tag (and is therefore being + * toggled off), or it's a new tag with higher priority. + */ + + if (tagPtr->elideString != NULL) { + infoPtr->tagCnts[tagPtr->priority]++; + if (infoPtr->tagCnts[tagPtr->priority] & 1) { + infoPtr->tagPtrs[tagPtr->priority] = tagPtr; + } + + if (tagPtr->priority >= infoPtr->elidePriority) { + if (segPtr->typePtr == &tkTextToggleOffType) { + /* + * If it is being toggled off, and it has an elide + * string, it must actually be the current highest + * priority tag, so this check is redundant: + */ + + if (tagPtr->priority != infoPtr->elidePriority) { + Tcl_Panic("Bad tag priority being toggled off"); + } + + /* + * Find previous elide tag, if any (if not then + * elide will be zero, of course). + */ + + elide = 0; + while (--infoPtr->elidePriority > 0) { + if (infoPtr->tagCnts[infoPtr->elidePriority] & 1) { - elide = infoPtr->tagPtrs + elide = infoPtr->tagPtrs [infoPtr->elidePriority]->elide; - break; - } + break; } - } else { - elide = tagPtr->elide; - infoPtr->elidePriority = tagPtr->priority; } + } else { + elide = tagPtr->elide; + infoPtr->elidePriority = tagPtr->priority; } } } } if (!elide) { - if (segPtr->typePtr == &tkTextCharType) { + if (segPtr->typePtr == &tkTextCharType) { start = segPtr->body.chars + byteOffset; end = segPtr->body.chars + segPtr->size; for (p = start; p < end; p += Tcl_UtfToUniChar(p, &ch)) { @@ -1547,27 +1582,24 @@ TkTextIndexForwChars(textPtr, srcPtr, charCount, dstPtr, type) } charCount--; } - } else { - if (type & COUNT_INDICES) { - if (charCount < segPtr->size - byteOffset) { - dstPtr->byteIndex += charCount; - goto forwardCharDone; - } - charCount -= segPtr->size - byteOffset; + } else if (type & COUNT_INDICES) { + if (charCount < segPtr->size - byteOffset) { + dstPtr->byteIndex += charCount; + goto forwardCharDone; } + charCount -= segPtr->size - byteOffset; } } - + dstPtr->byteIndex += segPtr->size - byteOffset; byteOffset = 0; } /* - * Go to the next line. If we are at the end of the text item, - * back up one byte (for the terminal '\n' character) and return - * that index. + * Go to the next line. If we are at the end of the text item, back up + * one byte (for the terminal '\n' character) and return that index. */ - + linePtr = TkBTreeNextLine(textPtr, dstPtr->linePtr); if (linePtr == NULL) { dstPtr->byteIndex -= sizeof(char); @@ -1577,6 +1609,7 @@ TkTextIndexForwChars(textPtr, srcPtr, charCount, dstPtr, type) dstPtr->byteIndex = 0; segPtr = dstPtr->linePtr->segPtr; } + forwardCharDone: if (infoPtr != NULL) { TkTextFreeElideInfo(infoPtr); @@ -1589,19 +1622,18 @@ TkTextIndexForwChars(textPtr, srcPtr, charCount, dstPtr, type) * * TkTextIndexCount -- * - * Given an ordered pair of indices in a text widget, this - * procedure counts how many characters (not bytes) are between - * the two indices. - * - * It is illegal to call this procedure with unordered indices. - * - * Note that 'textPtr' is only used if we need to check for - * elided attributes, i.e. if type is COUNT_DISPLAY_INDICES or + * Given an ordered pair of indices in a text widget, this function + * counts how many characters (not bytes) are between the two indices. + * + * It is illegal to call this function with unordered indices. + * + * Note that 'textPtr' is only used if we need to check for elided + * attributes, i.e. if type is COUNT_DISPLAY_INDICES or * COUNT_DISPLAY_CHARS. * * Results: - * The number of characters in the given range, which meet - * the appropriate 'type' attributes. + * The number of characters in the given range, which meet the + * appropriate 'type' attributes. * * Side effects: * None. @@ -1611,13 +1643,14 @@ TkTextIndexForwChars(textPtr, srcPtr, charCount, dstPtr, type) int TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type) - CONST TkText *textPtr; /* Overall information about text widget. */ - CONST TkTextIndex *indexPtr1;/* Index describing location of - * character from which to count. */ - CONST TkTextIndex *indexPtr2;/* Index describing location of last - * character at which to stop the - * count. */ - TkTextCountType type; /* The kind of indices to count */ + CONST TkText *textPtr; /* Overall information about text widget. */ + CONST TkTextIndex *indexPtr1; + /* Index describing location of character from + * which to count. */ + CONST TkTextIndex *indexPtr2; + /* Index describing location of last character + * at which to stop the count. */ + TkTextCountType type; /* The kind of indices to count. */ { TkTextLine *linePtr1; TkTextSegment *segPtr, *seg2Ptr = NULL; @@ -1628,43 +1661,43 @@ TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type) int checkElided = (type & COUNT_DISPLAY); /* - * Find seg that contains src index, and remember - * how many bytes not to count in the given segment. + * Find seg that contains src index, and remember how many bytes not to + * count in the given segment. */ segPtr = TkTextIndexToSeg(indexPtr1, &byteOffset); linePtr1 = indexPtr1->linePtr; - + seg2Ptr = TkTextIndexToSeg(indexPtr2, &maxBytes); if (checkElided) { infoPtr = (TkTextElideInfo*)ckalloc((unsigned)sizeof(TkTextElideInfo)); elide = TkTextIsElided(textPtr, indexPtr1, infoPtr); } - + while (1) { /* - * Go through each segment in line adding up the number - * of characters. + * Go through each segment in line adding up the number of characters. */ - + for ( ; segPtr != NULL; segPtr = segPtr->nextPtr) { /* * If we do need to pay attention to the visibility of - * characters/indices, check that first. If the current - * segment isn't visible, then we simply continue the - * loop + * characters/indices, check that first. If the current segment + * isn't visible, then we simply continue the loop. */ + if (checkElided) { if ((segPtr->typePtr == &tkTextToggleOffType) - || (segPtr->typePtr == &tkTextToggleOnType)) { + || (segPtr->typePtr == &tkTextToggleOnType)) { TkTextTag *tagPtr = segPtr->body.toggle.tagPtr; + /* - * The elide state only changes if this tag is - * either the current highest priority tag - * (and is therefore being toggled off), or it's - * a new tag with higher priority. + * The elide state only changes if this tag is either the + * current highest priority tag (and is therefore being + * toggled off), or it's a new tag with higher priority. */ + if (tagPtr->elideString != NULL) { infoPtr->tagCnts[tagPtr->priority]++; if (infoPtr->tagCnts[tagPtr->priority] & 1) { @@ -1672,26 +1705,28 @@ TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type) } if (tagPtr->priority >= infoPtr->elidePriority) { if (segPtr->typePtr == &tkTextToggleOffType) { - /* - * If it is being toggled off, and it has - * an elide string, it must actually be the - * current highest priority tag, so this - * check is redundant: + /* + * If it is being toggled off, and it has an + * elide string, it must actually be the + * current highest priority tag, so this check + * is redundant: */ - if (tagPtr->priority != infoPtr->elidePriority) { + + if (tagPtr->priority!=infoPtr->elidePriority) { Tcl_Panic("Bad tag priority being toggled off"); } - - /* + + /* * Find previous elide tag, if any (if not * then elide will be zero, of course). */ + elide = 0; while (--infoPtr->elidePriority > 0) { - if (infoPtr->tagCnts[infoPtr->elidePriority] - & 1) { - elide = infoPtr->tagPtrs - [infoPtr->elidePriority]->elide; + if (infoPtr->tagCnts[ + infoPtr->elidePriority] & 1) { + elide = infoPtr->tagPtrs[ + infoPtr->elidePriority]->elide; break; } } @@ -1710,29 +1745,34 @@ TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type) continue; } } - + if (segPtr->typePtr == &tkTextCharType) { int byteLen = segPtr->size - byteOffset; - register unsigned char *str = - (unsigned char *) segPtr->body.chars + byteOffset; + register unsigned char *str = (unsigned char *) + segPtr->body.chars + byteOffset; register int i; if (segPtr == seg2Ptr) { if (byteLen > (maxBytes - byteOffset)) { - byteLen = maxBytes - byteOffset; + byteLen = maxBytes - byteOffset; } } i = byteLen; - + /* - * This is a speed sensitive function, so run specially over the - * string to count continuous ascii characters before resorting - * to the Tcl_NumUtfChars call. This is a long form of: - * stringPtr->numChars = - * Tcl_NumUtfChars(objPtr->bytes, objPtr->length); + * This is a speed sensitive function, so run specially over + * the string to count continuous ascii characters before + * resorting to the Tcl_NumUtfChars call. This is a long form + * of: + * + * stringPtr->numChars = + * Tcl_NumUtfChars(objPtr->bytes, objPtr->length); */ - while (i && (*str < 0xC0)) { i--; str++; } + while (i && (*str < 0xC0)) { + i--; + str++; + } count += byteLen - i; if (i) { count += Tcl_NumUtfChars(segPtr->body.chars + byteOffset @@ -1741,6 +1781,7 @@ TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type) } else { if (type & COUNT_INDICES) { int byteLen = segPtr->size - byteOffset; + if (segPtr == seg2Ptr) { if (byteLen > (maxBytes - byteOffset)) { byteLen = maxBytes - byteOffset; @@ -1756,17 +1797,17 @@ TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type) } /* - * Go to the next line. If we are at the end of the text item, - * back up one byte (for the terminal '\n' character) and return - * that index. + * Go to the next line. If we are at the end of the text item, back up + * one byte (for the terminal '\n' character) and return that index. */ - + linePtr1 = TkBTreeNextLine(textPtr, linePtr1); if (linePtr1 == NULL) { Tcl_Panic("Reached end of text widget when counting characters"); } segPtr = linePtr1->segPtr; } + countDone: if (infoPtr != NULL) { TkTextFreeElideInfo(infoPtr); @@ -1774,22 +1815,22 @@ TkTextIndexCount(textPtr, indexPtr1, indexPtr2, type) } return count; } - + /* *--------------------------------------------------------------------------- * * TkTextIndexBackBytes -- * - * Given an index for a text widget, this procedure creates a new - * index that points "count" bytes earlier than the source index. + * Given an index for a text widget, this function creates a new index + * that points "count" bytes earlier than the source index. * * Results: * *dstPtr is modified to refer to the character "count" bytes before * srcPtr, or to the first character in the TkText if there aren't * "count" bytes earlier than srcPtr. - * - * Returns 1 if we couldn't use all of 'byteCount' because we - * have run into the beginning or end of the text, and zero otherwise. + * + * Returns 1 if we couldn't use all of 'byteCount' because we have run + * into the beginning or end of the text, and zero otherwise. * * Side effects: * None. @@ -1801,7 +1842,7 @@ int TkTextIndexBackBytes(textPtr, srcPtr, byteCount, dstPtr) CONST TkText *textPtr; CONST TkTextIndex *srcPtr; /* Source index. */ - int byteCount; /* How many bytes backward to move. May be + int byteCount; /* How many bytes backward to move. May be * negative. */ TkTextIndex *dstPtr; /* Destination index: gets modified. */ { @@ -1817,8 +1858,8 @@ TkTextIndexBackBytes(textPtr, srcPtr, byteCount, dstPtr) lineIndex = -1; while (dstPtr->byteIndex < 0) { /* - * Move back one line in the text. If we run off the beginning - * of the file then just return the first character in the text. + * Move back one line in the text. If we run off the beginning of the + * file then just return the first character in the text. */ if (lineIndex < 0) { @@ -1848,19 +1889,18 @@ TkTextIndexBackBytes(textPtr, srcPtr, byteCount, dstPtr) * * TkTextIndexBackChars -- * - * Given an index for a text widget, this procedure creates a new - * index that points "count" items of type given by "type" earlier - * than the source index. "count" can be zero, which is useful in - * the case where one wishes to move backward by display - * (non-elided) chars or indices or one wishes to move backward by - * chars, skipping any intervening indices. In this case the - * returned index *dstPtr will point just _after_ the first - * acceptable index which is encountered. + * Given an index for a text widget, this function creates a new index + * that points "count" items of type given by "type" earlier than the + * source index. "count" can be zero, which is useful in the case where + * one wishes to move backward by display (non-elided) chars or indices + * or one wishes to move backward by chars, skipping any intervening + * indices. In this case the returned index *dstPtr will point just + * _after_ the first acceptable index which is encountered. * * Results: - * *dstPtr is modified to refer to the character "count" items - * before srcPtr, or to the first index in the window if there - * aren't sufficient items earlier than srcPtr. + * *dstPtr is modified to refer to the character "count" items before + * srcPtr, or to the first index in the window if there aren't sufficient + * items earlier than srcPtr. * * Side effects: * None. @@ -1870,12 +1910,12 @@ TkTextIndexBackBytes(textPtr, srcPtr, byteCount, dstPtr) void TkTextIndexBackChars(textPtr, srcPtr, charCount, dstPtr, type) - CONST TkText *textPtr; /* Overall information about text widget. */ + CONST TkText *textPtr; /* Overall information about text widget. */ CONST TkTextIndex *srcPtr; /* Source index. */ - int charCount; /* How many characters backward to move. - * May be negative. */ + int charCount; /* How many characters backward to move. May + * be negative. */ TkTextIndex *dstPtr; /* Destination index: gets modified. */ - TkTextCountType type; /* The type of item to count */ + TkTextCountType type; /* The type of item to count */ { TkTextSegment *segPtr, *oldPtr; TkTextElideInfo *infoPtr = NULL; @@ -1889,21 +1929,21 @@ TkTextIndexBackChars(textPtr, srcPtr, charCount, dstPtr, type) return; } if (checkElided) { - infoPtr = (TkTextElideInfo*)ckalloc((unsigned)sizeof(TkTextElideInfo)); + infoPtr = (TkTextElideInfo *) ckalloc(sizeof(TkTextElideInfo)); elide = TkTextIsElided(textPtr, srcPtr, infoPtr); } - + *dstPtr = *srcPtr; /* - * Find offset within seg that contains byteIndex. - * Move backward specified number of chars. + * Find offset within seg that contains byteIndex. Move backward specified + * number of chars. */ lineIndex = -1; - + segSize = dstPtr->byteIndex; - + if (checkElided) { segPtr = infoPtr->segPtr; segSize -= infoPtr->segOffset; @@ -1911,10 +1951,11 @@ TkTextIndexBackChars(textPtr, srcPtr, charCount, dstPtr, type) TkTextLine *linePtr = dstPtr->linePtr; for (segPtr = linePtr->segPtr; ; segPtr = segPtr->nextPtr) { if (segPtr == NULL) { - /* - * Two logical lines merged into one display line - * through eliding of a newline + /* + * Two logical lines merged into one display line through + * eliding of a newline. */ + linePtr = TkBTreeNextLine(NULL, linePtr); segPtr = linePtr->segPtr; } @@ -1924,59 +1965,61 @@ TkTextIndexBackChars(textPtr, srcPtr, charCount, dstPtr, type) segSize -= segPtr->size; } } - /* + + /* * Now segPtr points to the segment containing the starting index */ + while (1) { /* * If we do need to pay attention to the visibility of - * characters/indices, check that first. If the current - * segment isn't visible, then we simply continue the - * loop + * characters/indices, check that first. If the current segment isn't + * visible, then we simply continue the loop. */ - if (checkElided) { - if ((segPtr->typePtr == &tkTextToggleOffType) - || (segPtr->typePtr == &tkTextToggleOnType)) { - TkTextTag *tagPtr = segPtr->body.toggle.tagPtr; - /* - * The elide state only changes if this tag is - * either the current highest priority tag - * (and is therefore being toggled off), or it's - * a new tag with higher priority. - */ - if (tagPtr->elideString != NULL) { - infoPtr->tagCnts[tagPtr->priority]++; - if (infoPtr->tagCnts[tagPtr->priority] & 1) { - infoPtr->tagPtrs[tagPtr->priority] = tagPtr; - } - if (tagPtr->priority >= infoPtr->elidePriority) { - if (segPtr->typePtr == &tkTextToggleOnType) { - /* - * If it is being toggled on, and it has - * an elide string, it must actually be the - * current highest priority tag, so this - * check is redundant: - */ - if (tagPtr->priority != infoPtr->elidePriority) { - Tcl_Panic("Bad tag priority being toggled on"); - } - - /* - * Find previous elide tag, if any (if not - * then elide will be zero, of course). - */ - elide = 0; - while (--infoPtr->elidePriority > 0) { - if (infoPtr->tagCnts[infoPtr->elidePriority] & 1) { - elide = infoPtr->tagPtrs - [infoPtr->elidePriority]->elide; - break; - } + + if (checkElided && ((segPtr->typePtr == &tkTextToggleOffType) + || (segPtr->typePtr == &tkTextToggleOnType))) { + TkTextTag *tagPtr = segPtr->body.toggle.tagPtr; + + /* + * The elide state only changes if this tag is either the current + * highest priority tag (and is therefore being toggled off), or + * it's a new tag with higher priority. + */ + + if (tagPtr->elideString != NULL) { + infoPtr->tagCnts[tagPtr->priority]++; + if (infoPtr->tagCnts[tagPtr->priority] & 1) { + infoPtr->tagPtrs[tagPtr->priority] = tagPtr; + } + if (tagPtr->priority >= infoPtr->elidePriority) { + if (segPtr->typePtr == &tkTextToggleOnType) { + /* + * If it is being toggled on, and it has an elide + * string, it must actually be the current highest + * priority tag, so this check is redundant: + */ + + if (tagPtr->priority != infoPtr->elidePriority) { + Tcl_Panic("Bad tag priority being toggled on"); + } + + /* + * Find previous elide tag, if any (if not then elide + * will be zero, of course). + */ + + elide = 0; + while (--infoPtr->elidePriority > 0) { + if (infoPtr->tagCnts[infoPtr->elidePriority] & 1) { + elide = infoPtr->tagPtrs[ + infoPtr->elidePriority]->elide; + break; } - } else { - elide = tagPtr->elide; - infoPtr->elidePriority = tagPtr->priority; } + } else { + elide = tagPtr->elide; + infoPtr->elidePriority = tagPtr->priority; } } } @@ -2048,6 +2091,7 @@ TkTextIndexBackChars(textPtr, srcPtr, charCount, dstPtr, type) segPtr = oldPtr; segSize = segPtr->size; } + backwardCharDone: if (infoPtr != NULL) { TkTextFreeElideInfo(infoPtr); @@ -2060,14 +2104,14 @@ TkTextIndexBackChars(textPtr, srcPtr, charCount, dstPtr, type) * * StartEnd -- * - * This procedure handles modifiers like "wordstart" and "lineend" - * to adjust indices forwards or backwards. + * This function handles modifiers like "wordstart" and "lineend" to + * adjust indices forwards or backwards. * * Results: - * If the modifier is successfully parsed then the return value - * is the address of the first character after the modifier, and - * *indexPtr is updated to reflect the modifier. If there is a - * syntax error in the modifier then NULL is returned. + * If the modifier is successfully parsed then the return value is the + * address of the first character after the modifier, and *indexPtr is + * updated to reflect the modifier. If there is a syntax error in the + * modifier then NULL is returned. * * Side effects: * None. @@ -2078,17 +2122,16 @@ TkTextIndexBackChars(textPtr, srcPtr, charCount, dstPtr, type) static CONST char * StartEnd(textPtr, string, indexPtr) TkText *textPtr; /* Information about text widget. */ - CONST char *string; /* String to parse for additional info - * about modifier (count and units). - * Points to first character of modifer - * word. */ + CONST char *string; /* String to parse for additional info about + * modifier (count and units). Points to first + * character of modifer word. */ TkTextIndex *indexPtr; /* Index to modify based on string. */ { CONST char *p; size_t length; register TkTextSegment *segPtr; int modifier; - + /* * Find the end of the modifier word. */ @@ -2096,15 +2139,16 @@ StartEnd(textPtr, string, indexPtr) for (p = string; isalnum(UCHAR(*p)); p++) { /* Empty loop body. */ } + length = p-string; - if ((*string == 'd') && (strncmp(string, "display", - (length > 7 ? 7 : length)) == 0)) { + if ((*string == 'd') && + (strncmp(string, "display", (length > 7 ? 7 : length)) == 0)) { modifier = TKINDEX_DISPLAY; if (length > 7) { p -= (length - 7); } - } else if ((*string == 'a') && (strncmp(string, "any", - (length > 3 ? 3 : length)) == 0)) { + } else if ((*string == 'a') && + (strncmp(string, "any", (length > 3 ? 3 : length)) == 0)) { modifier = TKINDEX_ANY; if (length > 3) { p -= (length - 3); @@ -2112,17 +2156,18 @@ StartEnd(textPtr, string, indexPtr) } else { modifier = TKINDEX_NONE; } - - /* - * If we had a modifier, which we interpreted ok, so now forward - * to the actual units. + + /* + * If we had a modifier, which we interpreted ok, so now forward to the + * actual units. */ + if (modifier != TKINDEX_NONE) { while (isspace(UCHAR(*p))) { p++; } - string = p; - while ((*p != '\0') && !isspace(UCHAR(*p)) && (*p != '+') && (*p != '-')) { + string = p; + while ((*p!='\0') && !isspace(UCHAR(*p)) && (*p!='+') && (*p!='-')) { p++; } length = p - string; @@ -2138,7 +2183,11 @@ StartEnd(textPtr, string, indexPtr) segPtr = segPtr->nextPtr) { indexPtr->byteIndex += segPtr->size; } - /* We know '\n' is encoded with a single byte index */ + + /* + * We know '\n' is encoded with a single byte index. + */ + indexPtr->byteIndex -= sizeof(char); } } else if ((*string == 'l') && (strncmp(string, "linestart", length) == 0) @@ -2155,19 +2204,21 @@ StartEnd(textPtr, string, indexPtr) /* * If the current character isn't part of a word then just move - * forward one character. Otherwise move forward until finding - * a character that isn't part of a word and stop there. + * forward one character. Otherwise move forward until finding a + * character that isn't part of a word and stop there. */ if (modifier == TKINDEX_DISPLAY) { - TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr, - COUNT_DISPLAY_INDICES); + TkTextIndexForwChars(textPtr, indexPtr, 0, indexPtr, + COUNT_DISPLAY_INDICES); } segPtr = TkTextIndexToSeg(indexPtr, &offset); while (1) { int chSize = 1; + if (segPtr->typePtr == &tkTextCharType) { Tcl_UniChar ch; + chSize = Tcl_UtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; @@ -2182,11 +2233,11 @@ StartEnd(textPtr, string, indexPtr) } if (firstChar) { if (modifier == TKINDEX_DISPLAY) { - TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr, - COUNT_DISPLAY_INDICES); + TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr, + COUNT_DISPLAY_INDICES); } else { - TkTextIndexForwChars(NULL, indexPtr, 1, indexPtr, - COUNT_INDICES); + TkTextIndexForwChars(NULL, indexPtr, 1, indexPtr, + COUNT_INDICES); } } } else if ((*string == 'w') && (strncmp(string, "wordstart", length) == 0) @@ -2195,29 +2246,32 @@ StartEnd(textPtr, string, indexPtr) int offset; if (modifier == TKINDEX_DISPLAY) { - TkTextIndexForwChars(NULL, indexPtr, 0, indexPtr, - COUNT_DISPLAY_INDICES); + TkTextIndexForwChars(NULL, indexPtr, 0, indexPtr, + COUNT_DISPLAY_INDICES); } + /* - * Starting with the current character, look for one that's not - * part of a word and keep moving backward until you find one. - * Then if the character found wasn't the first one, move forward - * again one position. + * Starting with the current character, look for one that's not part + * of a word and keep moving backward until you find one. Then if the + * character found wasn't the first one, move forward again one + * position. */ segPtr = TkTextIndexToSeg(indexPtr, &offset); while (1) { int chSize = 1; + if (segPtr->typePtr == &tkTextCharType) { Tcl_UniChar ch; + Tcl_UtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } if (offset > 0) { - chSize = (segPtr->body.chars + offset - - Tcl_UtfPrev(segPtr->body.chars + offset, - segPtr->body.chars)); + chSize = (segPtr->body.chars + offset + - Tcl_UtfPrev(segPtr->body.chars + offset, + segPtr->body.chars)); } firstChar = 0; } else { @@ -2232,18 +2286,28 @@ StartEnd(textPtr, string, indexPtr) segPtr = TkTextIndexToSeg(indexPtr, &offset); } } + if (!firstChar) { if (modifier == TKINDEX_DISPLAY) { - TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr, - COUNT_DISPLAY_INDICES); + TkTextIndexForwChars(textPtr, indexPtr, 1, indexPtr, + COUNT_DISPLAY_INDICES); } else { - TkTextIndexForwChars(NULL, indexPtr, 1, indexPtr, - COUNT_INDICES); + TkTextIndexForwChars(NULL, indexPtr, 1, indexPtr, + COUNT_INDICES); } } } else { return NULL; } - done: + + done: return p; } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/generic/tkTextTag.c b/generic/tkTextTag.c index eb09566..00d350a 100644 --- a/generic/tkTextTag.c +++ b/generic/tkTextTag.c @@ -1,17 +1,17 @@ -/* +/* * tkTextTag.c -- * - * This module implements the "tag" subcommand of the widget command - * for text widgets, plus most of the other high-level functions - * related to tags. + * This module implements the "tag" subcommand of the widget command for + * text widgets, plus most of the other high-level functions related to + * tags. * * Copyright (c) 1992-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkTextTag.c,v 1.19 2004/10/05 01:26:10 hobbs Exp $ + * RCS: @(#) $Id: tkTextTag.c,v 1.20 2005/08/10 22:02:22 dkf Exp $ */ #include "default.h" @@ -20,10 +20,10 @@ #include "tkText.h" /* - * The 'TkWrapMode' enum in tkText.h is used to define a type for the - * -wrap option of tags in a Text widget. These values are used as - * indices into the string table below. Tags are allowed an empty wrap - * value, but the widget as a whole is not. + * The 'TkWrapMode' enum in tkText.h is used to define a type for the -wrap + * option of tags in a Text widget. These values are used as indices into the + * string table below. Tags are allowed an empty wrap value, but the widget as + * a whole is not. */ static char *wrapStrings[] = { @@ -32,9 +32,9 @@ static char *wrapStrings[] = { static Tk_OptionSpec tagOptionSpecs[] = { {TK_OPTION_BORDER, "-background", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, border), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, border), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_BITMAP, "-bgstipple", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, bgStipple), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, bgStipple), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_PIXELS, "-borderwidth", (char *) NULL, (char *) NULL, "0", Tk_Offset(TkTextTag, borderWidthPtr), Tk_Offset(TkTextTag, borderWidth), TK_OPTION_DONT_SET_DEFAULT|TK_OPTION_NULL_OK, 0, 0}, @@ -42,34 +42,34 @@ static Tk_OptionSpec tagOptionSpecs[] = { "0", -1, Tk_Offset(TkTextTag, elideString), TK_OPTION_DONT_SET_DEFAULT|TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_BITMAP, "-fgstipple", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, fgStipple), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, fgStipple), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_FONT, "-font", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, tkfont), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, tkfont), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_COLOR, "-foreground", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, fgColor), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, fgColor), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-justify", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, justifyString), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, justifyString), TK_OPTION_NULL_OK, 0,0}, {TK_OPTION_STRING, "-lmargin1", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, lMargin1String), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, lMargin1String), TK_OPTION_NULL_OK,0,0}, {TK_OPTION_STRING, "-lmargin2", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, lMargin2String), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, lMargin2String), TK_OPTION_NULL_OK,0,0}, {TK_OPTION_STRING, "-offset", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, offsetString), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, offsetString), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-overstrike", (char *) NULL, (char *) NULL, (char *) NULL, -1, Tk_Offset(TkTextTag, overstrikeString), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-relief", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, reliefString), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, reliefString), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-rmargin", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, rMarginString), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, rMarginString), TK_OPTION_NULL_OK, 0,0}, {TK_OPTION_STRING, "-spacing1", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, spacing1String), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, spacing1String), TK_OPTION_NULL_OK,0,0}, {TK_OPTION_STRING, "-spacing2", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, spacing2String), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, spacing2String), TK_OPTION_NULL_OK,0,0}, {TK_OPTION_STRING, "-spacing3", (char *) NULL, (char *) NULL, - (char *) NULL, -1, Tk_Offset(TkTextTag, spacing3String), TK_OPTION_NULL_OK, 0, 0}, + NULL, -1, Tk_Offset(TkTextTag, spacing3String), TK_OPTION_NULL_OK,0,0}, {TK_OPTION_STRING, "-tabs", (char *) NULL, (char *) NULL, - (char *) NULL, Tk_Offset(TkTextTag, tabStringPtr), -1, TK_OPTION_NULL_OK, 0, 0}, + NULL, Tk_Offset(TkTextTag, tabStringPtr), -1, TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-underline", (char *) NULL, (char *) NULL, (char *) NULL, -1, Tk_Offset(TkTextTag, underlineString), TK_OPTION_NULL_OK, 0, 0}, @@ -80,29 +80,26 @@ static Tk_OptionSpec tagOptionSpecs[] = { }; /* - * Forward declarations for procedures defined later in this file: + * Forward declarations for functions defined later in this file: */ -static void ChangeTagPriority _ANSI_ARGS_((TkText *textPtr, - TkTextTag *tagPtr, int prio)); -static TkTextTag * FindTag _ANSI_ARGS_((Tcl_Interp *interp, - TkText *textPtr, Tcl_Obj *tagName)); -static void SortTags _ANSI_ARGS_((int numTags, - TkTextTag **tagArrayPtr)); -static int TagSortProc _ANSI_ARGS_((CONST VOID *first, - CONST VOID *second)); -static void TagBindEvent _ANSI_ARGS_((TkText *textPtr, XEvent *eventPtr, - int numTags, TkTextTag **tagArrayPtr)); - +static void ChangeTagPriority(TkText *textPtr, TkTextTag *tagPtr, + int prio); +static TkTextTag * FindTag(Tcl_Interp *interp, TkText *textPtr, + Tcl_Obj *tagName); +static void SortTags(int numTags, TkTextTag **tagArrayPtr); +static int TagSortProc(CONST VOID *first, CONST VOID *second); +static void TagBindEvent(TkText *textPtr, XEvent *eventPtr, + int numTags, TkTextTag **tagArrayPtr); /* *-------------------------------------------------------------- * * TkTextTagCmd -- * - * This procedure is invoked to process the "tag" options of - * the widget command for text widgets. See the user documentation - * for details on what it does. + * This function is invoked to process the "tag" options of the widget + * command for text widgets. See the user documentation for details on + * what it does. * * Results: * A standard Tcl result. @@ -123,11 +120,11 @@ TkTextTagCmd(textPtr, interp, objc, objv) * objv[1] is "tag". */ { int optionIndex; - + static CONST char *tagOptionStrings[] = { "add", "bind", "cget", "configure", "delete", "lower", - "names", "nextrange", "prevrange", "raise", "ranges", - "remove", (char *) NULL + "names", "nextrange", "prevrange", "raise", "ranges", + "remove", (char *) NULL }; enum tagOptions { TAG_ADD, TAG_BIND, TAG_CGET, TAG_CONFIGURE, TAG_DELETE, @@ -143,753 +140,764 @@ TkTextTagCmd(textPtr, interp, objc, objv) Tcl_WrongNumArgs(interp, 2, objv, "option ?arg arg ...?"); return TCL_ERROR; } - - if (Tcl_GetIndexFromObj(interp, objv[2], tagOptionStrings, - "tag option", 0, &optionIndex) != TCL_OK) { + + if (Tcl_GetIndexFromObj(interp, objv[2], tagOptionStrings, + "tag option", 0, &optionIndex) != TCL_OK) { return TCL_ERROR; } switch ((enum tagOptions)optionIndex) { - case TAG_ADD: - case TAG_REMOVE: { - int addTag; - if (((enum tagOptions)optionIndex) == TAG_ADD) { - addTag = 1; - } else { - addTag = 0; - } - if (objc < 5) { - Tcl_WrongNumArgs(interp, 3, objv, - "tagName index1 ?index2 index1 index2 ...?"); + case TAG_ADD: + case TAG_REMOVE: { + int addTag; + + if (((enum tagOptions)optionIndex) == TAG_ADD) { + addTag = 1; + } else { + addTag = 0; + } + if (objc < 5) { + Tcl_WrongNumArgs(interp, 3, objv, + "tagName index1 ?index2 index1 index2 ...?"); + return TCL_ERROR; + } + tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL); + for (i = 4; i < objc; i += 2) { + if (TkTextGetObjIndex(interp, textPtr, objv[i], + &index1) != TCL_OK) { return TCL_ERROR; } - tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL); - for (i = 4; i < objc; i += 2) { - if (TkTextGetObjIndex(interp, textPtr, objv[i], - &index1) != TCL_OK) { + if (objc > (i+1)) { + if (TkTextGetObjIndex(interp, textPtr, objv[i+1], + &index2) != TCL_OK) { return TCL_ERROR; } - if (objc > (i+1)) { - if (TkTextGetObjIndex(interp, textPtr, objv[i+1], &index2) - != TCL_OK) { - return TCL_ERROR; - } - if (TkTextIndexCmp(&index1, &index2) >= 0) { - return TCL_OK; - } - } else { - index2 = index1; - TkTextIndexForwChars(NULL,&index2, 1, &index2, - COUNT_INDICES); + if (TkTextIndexCmp(&index1, &index2) >= 0) { + return TCL_OK; } + } else { + index2 = index1; + TkTextIndexForwChars(NULL,&index2, 1, &index2, COUNT_INDICES); + } - if (tagPtr->affectsDisplay) { - TkTextRedrawTag(textPtr->sharedTextPtr, NULL, - &index1, &index2, tagPtr, !addTag); - } else { - /* - * Still need to trigger enter/leave events on tags that - * have changed. - */ + if (tagPtr->affectsDisplay) { + TkTextRedrawTag(textPtr->sharedTextPtr, NULL, &index1, &index2, + tagPtr, !addTag); + } else { + /* + * Still need to trigger enter/leave events on tags that have + * changed. + */ - TkTextEventuallyRepick(textPtr); - } - if (TkBTreeTag(&index1, &index2, tagPtr, addTag)) { + TkTextEventuallyRepick(textPtr); + } + if (TkBTreeTag(&index1, &index2, tagPtr, addTag)) { + /* + * If the tag is "sel", and we actually adjusted something + * then grab the selection if we're supposed to export it and + * don't already have it. + * + * Also, invalidate partially-completed selection retrievals. + * We only need to check whether the tag is "sel" for this + * textPtr (not for other peer widget's "sel" tags) because we + * cannot reach this code path with a different widget's "sel" + * tag. + */ + + if (tagPtr == textPtr->selTagPtr) { /* - * If the tag is "sel", and we actually adjusted - * something then grab the selection if we're - * supposed to export it and don't already have it. - * - * Also, invalidate partially-completed selection - * retrievals. We only need to check whether the - * tag is "sel" for this textPtr (not for other peer - * widget's "sel" tags) because we cannot reach this - * code path with a different widget's "sel" tag. + * Send an event that the selection changed. This is + * equivalent to: + * event generate $textWidget <<Selection>> */ - if (tagPtr == textPtr->selTagPtr) { - /* - * Send an event that the selection changed. - * This is equivalent to - * "event generate $textWidget <<Selection>>" - */ - - TkTextSelectionEvent(textPtr); + TkTextSelectionEvent(textPtr); - if (addTag && textPtr->exportSelection - && !(textPtr->flags & GOT_SELECTION)) { - Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY, - TkTextLostSelection, (ClientData) textPtr); - textPtr->flags |= GOT_SELECTION; - } - textPtr->abortSelections = 1; + if (addTag && textPtr->exportSelection + && !(textPtr->flags & GOT_SELECTION)) { + Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY, + TkTextLostSelection, (ClientData) textPtr); + textPtr->flags |= GOT_SELECTION; } + textPtr->abortSelections = 1; } } - break; } - case TAG_BIND: { - if ((objc < 4) || (objc > 6)) { - Tcl_WrongNumArgs(interp, 3, objv, - "tagName ?sequence? ?command?"); - return TCL_ERROR; - } - tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL); + break; + } + case TAG_BIND: + if ((objc < 4) || (objc > 6)) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName ?sequence? ?command?"); + return TCL_ERROR; + } + tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), NULL); - /* - * Make a binding table if the widget doesn't already have - * one. - */ + /* + * Make a binding table if the widget doesn't already have one. + */ - if (textPtr->sharedTextPtr->bindingTable == NULL) { - textPtr->sharedTextPtr->bindingTable = Tk_CreateBindingTable(interp); - } + if (textPtr->sharedTextPtr->bindingTable == NULL) { + textPtr->sharedTextPtr->bindingTable = + Tk_CreateBindingTable(interp); + } - if (objc == 6) { - int append = 0; - unsigned long mask; - char *fifth = Tcl_GetString(objv[5]); + if (objc == 6) { + int append = 0; + unsigned long mask; + char *fifth = Tcl_GetString(objv[5]); - if (fifth[0] == 0) { - return Tk_DeleteBinding(interp, textPtr->sharedTextPtr->bindingTable, - (ClientData) tagPtr->name, Tcl_GetString(objv[4])); - } - if (fifth[0] == '+') { - fifth++; - append = 1; - } - mask = Tk_CreateBinding(interp, textPtr->sharedTextPtr->bindingTable, - (ClientData) tagPtr->name, Tcl_GetString(objv[4]), - fifth, append); - if (mask == 0) { - return TCL_ERROR; - } - if (mask & (unsigned) ~(ButtonMotionMask|Button1MotionMask - |Button2MotionMask|Button3MotionMask|Button4MotionMask - |Button5MotionMask|ButtonPressMask|ButtonReleaseMask - |EnterWindowMask|LeaveWindowMask|KeyPressMask - |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) { - Tk_DeleteBinding(interp, textPtr->sharedTextPtr->bindingTable, - (ClientData) tagPtr->name, Tcl_GetString(objv[4])); - Tcl_ResetResult(interp); - Tcl_AppendResult(interp, "requested illegal events; ", - "only key, button, motion, enter, leave, and virtual ", - "events may be used", (char *) NULL); - return TCL_ERROR; - } - } else if (objc == 5) { - CONST char *command; - - command = Tk_GetBinding(interp, textPtr->sharedTextPtr->bindingTable, + if (fifth[0] == 0) { + return Tk_DeleteBinding(interp, + textPtr->sharedTextPtr->bindingTable, + (ClientData) tagPtr->name, Tcl_GetString(objv[4])); + } + if (fifth[0] == '+') { + fifth++; + append = 1; + } + mask = Tk_CreateBinding(interp, + textPtr->sharedTextPtr->bindingTable, + (ClientData) tagPtr->name, Tcl_GetString(objv[4]), fifth, + append); + if (mask == 0) { + return TCL_ERROR; + } + if (mask & (unsigned) ~(ButtonMotionMask|Button1MotionMask + |Button2MotionMask|Button3MotionMask|Button4MotionMask + |Button5MotionMask|ButtonPressMask|ButtonReleaseMask + |EnterWindowMask|LeaveWindowMask|KeyPressMask + |KeyReleaseMask|PointerMotionMask|VirtualEventMask)) { + Tk_DeleteBinding(interp, textPtr->sharedTextPtr->bindingTable, (ClientData) tagPtr->name, Tcl_GetString(objv[4])); - if (command == NULL) { - CONST char *string = Tcl_GetStringResult(interp); + Tcl_ResetResult(interp); + Tcl_AppendResult(interp, "requested illegal events; ", + "only key, button, motion, enter, leave, and virtual ", + "events may be used", (char *) NULL); + return TCL_ERROR; + } + } else if (objc == 5) { + CONST char *command; - /* - * Ignore missing binding errors. This is a special hack - * that relies on the error message returned by FindSequence - * in tkBind.c. - */ + command = Tk_GetBinding(interp, + textPtr->sharedTextPtr->bindingTable, + (ClientData) tagPtr->name, Tcl_GetString(objv[4])); + if (command == NULL) { + CONST char *string = Tcl_GetStringResult(interp); - if (string[0] != '\0') { - return TCL_ERROR; - } else { - Tcl_ResetResult(interp); - } + /* + * Ignore missing binding errors. This is a special hack that + * relies on the error message returned by FindSequence in + * tkBind.c. + */ + + if (string[0] != '\0') { + return TCL_ERROR; } else { - Tcl_SetResult(interp, (char *) command, TCL_STATIC); + Tcl_ResetResult(interp); } } else { - Tk_GetAllBindings(interp, textPtr->sharedTextPtr->bindingTable, - (ClientData) tagPtr->name); + Tcl_SetResult(interp, (char *) command, TCL_STATIC); } - break; + } else { + Tk_GetAllBindings(interp, textPtr->sharedTextPtr->bindingTable, + (ClientData) tagPtr->name); } - case TAG_CGET: { - if (objc != 5) { - Tcl_WrongNumArgs(interp, 1, objv, "tag cget tagName option"); + break; + case TAG_CGET: + if (objc != 5) { + Tcl_WrongNumArgs(interp, 1, objv, "tag cget tagName option"); + return TCL_ERROR; + } else { + Tcl_Obj *objPtr; + + tagPtr = FindTag(interp, textPtr, objv[3]); + if (tagPtr == NULL) { + return TCL_ERROR; + } + objPtr = Tk_GetOptionValue(interp, (char *) tagPtr, + tagPtr->optionTable, objv[4], textPtr->tkwin); + if (objPtr == NULL) { return TCL_ERROR; } else { - Tcl_Obj *objPtr; - - tagPtr = FindTag(interp, textPtr, objv[3]); - if (tagPtr == NULL) { - return TCL_ERROR; - } - objPtr = Tk_GetOptionValue(interp, (char *) tagPtr, - tagPtr->optionTable, objv[4], - textPtr->tkwin); - if (objPtr == NULL) { - return TCL_ERROR; - } else { - Tcl_SetObjResult(interp, objPtr); - return TCL_OK; - } + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; } - break; } - case TAG_CONFIGURE: { - int newTag; - if (objc < 4) { - Tcl_WrongNumArgs(interp, 3, objv, - "tagName ?option? ?value? ?option value ...?"); + break; + case TAG_CONFIGURE: { + int newTag; + + if (objc < 4) { + Tcl_WrongNumArgs(interp, 3, objv, + "tagName ?option? ?value? ?option value ...?"); + return TCL_ERROR; + } + tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), &newTag); + if (objc <= 5) { + Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, (char *) tagPtr, + tagPtr->optionTable, + (objc == 5) ? objv[4] : (Tcl_Obj *) NULL, textPtr->tkwin); + + if (objPtr == NULL) { return TCL_ERROR; - } - tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), &newTag); - if (objc <= 5) { - Tcl_Obj* objPtr = Tk_GetOptionInfo(interp, (char *) tagPtr, - tagPtr->optionTable, - (objc == 5) ? objv[4] : (Tcl_Obj *) NULL, - textPtr->tkwin); - if (objPtr == NULL) { - return TCL_ERROR; - } else { - Tcl_SetObjResult(interp, objPtr); - return TCL_OK; - } } else { - int result = TCL_OK; + Tcl_SetObjResult(interp, objPtr); + return TCL_OK; + } + } else { + int result = TCL_OK; + + if (Tk_SetOptions(interp, (char*)tagPtr, tagPtr->optionTable, + objc-4, objv+4, textPtr->tkwin, NULL, NULL) != TCL_OK) { + return TCL_ERROR; + } - if (Tk_SetOptions(interp, (char*)tagPtr, tagPtr->optionTable, - objc-4, objv+4, textPtr->tkwin, NULL, NULL) != TCL_OK) { + /* + * Some of the configuration options, like -underline and + * -justify, require additional translation (this is needed + * because we need to distinguish a particular value of an option + * from "unspecified"). + */ + + if (tagPtr->borderWidth < 0) { + tagPtr->borderWidth = 0; + } + if (tagPtr->reliefString != NULL) { + if (Tk_GetRelief(interp, tagPtr->reliefString, + &tagPtr->relief) != TCL_OK) { return TCL_ERROR; } - /* - * Some of the configuration options, like -underline - * and -justify, require additional translation (this is - * needed because we need to distinguish a particular value - * of an option from "unspecified"). - */ - - if (tagPtr->borderWidth < 0) { - tagPtr->borderWidth = 0; + } + if (tagPtr->justifyString != NULL) { + if (Tk_GetJustify(interp, tagPtr->justifyString, + &tagPtr->justify) != TCL_OK) { + return TCL_ERROR; } - if (tagPtr->reliefString != NULL) { - if (Tk_GetRelief(interp, tagPtr->reliefString, - &tagPtr->relief) != TCL_OK) { - return TCL_ERROR; - } + } + if (tagPtr->lMargin1String != NULL) { + if (Tk_GetPixels(interp, textPtr->tkwin, + tagPtr->lMargin1String, &tagPtr->lMargin1) != TCL_OK) { + return TCL_ERROR; } - if (tagPtr->justifyString != NULL) { - if (Tk_GetJustify(interp, tagPtr->justifyString, - &tagPtr->justify) != TCL_OK) { - return TCL_ERROR; - } + } + if (tagPtr->lMargin2String != NULL) { + if (Tk_GetPixels(interp, textPtr->tkwin, + tagPtr->lMargin2String, &tagPtr->lMargin2) != TCL_OK) { + return TCL_ERROR; } - if (tagPtr->lMargin1String != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->lMargin1String, &tagPtr->lMargin1) != TCL_OK) { - return TCL_ERROR; - } + } + if (tagPtr->offsetString != NULL) { + if (Tk_GetPixels(interp, textPtr->tkwin, tagPtr->offsetString, + &tagPtr->offset) != TCL_OK) { + return TCL_ERROR; } - if (tagPtr->lMargin2String != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->lMargin2String, &tagPtr->lMargin2) != TCL_OK) { - return TCL_ERROR; - } + } + if (tagPtr->overstrikeString != NULL) { + if (Tcl_GetBoolean(interp, tagPtr->overstrikeString, + &tagPtr->overstrike) != TCL_OK) { + return TCL_ERROR; } - if (tagPtr->offsetString != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->offsetString, - &tagPtr->offset) != TCL_OK) { - return TCL_ERROR; - } + } + if (tagPtr->rMarginString != NULL) { + if (Tk_GetPixels(interp, textPtr->tkwin, + tagPtr->rMarginString, &tagPtr->rMargin) != TCL_OK) { + return TCL_ERROR; } - if (tagPtr->overstrikeString != NULL) { - if (Tcl_GetBoolean(interp, tagPtr->overstrikeString, - &tagPtr->overstrike) != TCL_OK) { - return TCL_ERROR; - } + } + if (tagPtr->spacing1String != NULL) { + if (Tk_GetPixels(interp, textPtr->tkwin, + tagPtr->spacing1String, &tagPtr->spacing1) != TCL_OK) { + return TCL_ERROR; } - if (tagPtr->rMarginString != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->rMarginString, &tagPtr->rMargin) != TCL_OK) { - return TCL_ERROR; - } + if (tagPtr->spacing1 < 0) { + tagPtr->spacing1 = 0; } - if (tagPtr->spacing1String != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->spacing1String, &tagPtr->spacing1) != TCL_OK) { - return TCL_ERROR; - } - if (tagPtr->spacing1 < 0) { - tagPtr->spacing1 = 0; - } + } + if (tagPtr->spacing2String != NULL) { + if (Tk_GetPixels(interp, textPtr->tkwin, + tagPtr->spacing2String, &tagPtr->spacing2) != TCL_OK) { + return TCL_ERROR; } - if (tagPtr->spacing2String != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->spacing2String, &tagPtr->spacing2) != TCL_OK) { - return TCL_ERROR; - } - if (tagPtr->spacing2 < 0) { - tagPtr->spacing2 = 0; - } + if (tagPtr->spacing2 < 0) { + tagPtr->spacing2 = 0; } - if (tagPtr->spacing3String != NULL) { - if (Tk_GetPixels(interp, textPtr->tkwin, - tagPtr->spacing3String, &tagPtr->spacing3) != TCL_OK) { - return TCL_ERROR; - } - if (tagPtr->spacing3 < 0) { - tagPtr->spacing3 = 0; - } + } + if (tagPtr->spacing3String != NULL) { + if (Tk_GetPixels(interp, textPtr->tkwin, + tagPtr->spacing3String, &tagPtr->spacing3) != TCL_OK) { + return TCL_ERROR; } - if (tagPtr->tabArrayPtr != NULL) { - ckfree((char *) tagPtr->tabArrayPtr); - tagPtr->tabArrayPtr = NULL; + if (tagPtr->spacing3 < 0) { + tagPtr->spacing3 = 0; } - if (tagPtr->tabStringPtr != NULL) { - tagPtr->tabArrayPtr = TkTextGetTabs(interp, textPtr, - tagPtr->tabStringPtr); - if (tagPtr->tabArrayPtr == NULL) { - return TCL_ERROR; - } + } + if (tagPtr->tabArrayPtr != NULL) { + ckfree((char *) tagPtr->tabArrayPtr); + tagPtr->tabArrayPtr = NULL; + } + if (tagPtr->tabStringPtr != NULL) { + tagPtr->tabArrayPtr = + TkTextGetTabs(interp, textPtr, tagPtr->tabStringPtr); + if (tagPtr->tabArrayPtr == NULL) { + return TCL_ERROR; } - if (tagPtr->underlineString != NULL) { - if (Tcl_GetBoolean(interp, tagPtr->underlineString, - &tagPtr->underline) != TCL_OK) { - return TCL_ERROR; - } + } + if (tagPtr->underlineString != NULL) { + if (Tcl_GetBoolean(interp, tagPtr->underlineString, + &tagPtr->underline) != TCL_OK) { + return TCL_ERROR; } - if (tagPtr->elideString != NULL) { - if (Tcl_GetBoolean(interp, tagPtr->elideString, - &tagPtr->elide) != TCL_OK) { - return TCL_ERROR; - } + } + if (tagPtr->elideString != NULL) { + if (Tcl_GetBoolean(interp, tagPtr->elideString, + &tagPtr->elide) != TCL_OK) { + return TCL_ERROR; } + } + + /* + * If the "sel" tag was changed, be sure to mirror information + * from the tag back into the text widget record. NOTE: we don't + * have to free up information in the widget record before + * overwriting it, because it was mirrored in the tag and hence + * freed when the tag field was overwritten. + */ + + if (tagPtr == textPtr->selTagPtr) { + textPtr->selBorder = tagPtr->border; + textPtr->selBorderWidth = tagPtr->borderWidth; + textPtr->selBorderWidthPtr = tagPtr->borderWidthPtr; + textPtr->selFgColorPtr = tagPtr->fgColor; + } + tagPtr->affectsDisplay = 0; + tagPtr->affectsDisplayGeometry = 0; + if ((tagPtr->elideString != NULL) + || (tagPtr->tkfont != None) + || (tagPtr->justifyString != NULL) + || (tagPtr->lMargin1String != NULL) + || (tagPtr->lMargin2String != NULL) + || (tagPtr->offsetString != NULL) + || (tagPtr->rMarginString != NULL) + || (tagPtr->spacing1String != NULL) + || (tagPtr->spacing2String != NULL) + || (tagPtr->spacing3String != NULL) + || (tagPtr->tabStringPtr != NULL) + || (tagPtr->wrapMode != TEXT_WRAPMODE_NULL)) { + tagPtr->affectsDisplay = 1; + tagPtr->affectsDisplayGeometry = 1; + } + if ((tagPtr->border != NULL) + || (tagPtr->reliefString != NULL) + || (tagPtr->bgStipple != None) + || (tagPtr->fgColor != NULL) + || (tagPtr->fgStipple != None) + || (tagPtr->overstrikeString != NULL) + || (tagPtr->underlineString != NULL)) { + tagPtr->affectsDisplay = 1; + } + if (!newTag) { /* - * If the "sel" tag was changed, be sure to mirror information - * from the tag back into the text widget record. NOTE: we - * don't have to free up information in the widget record - * before overwriting it, because it was mirrored in the tag - * and hence freed when the tag field was overwritten. + * This line is not necessary if this is a new tag, since it + * can't possibly have been applied to anything yet. */ - if (tagPtr == textPtr->selTagPtr) { - textPtr->selBorder = tagPtr->border; - textPtr->selBorderWidth = tagPtr->borderWidth; - textPtr->selBorderWidthPtr = tagPtr->borderWidthPtr; - textPtr->selFgColorPtr = tagPtr->fgColor; - } - tagPtr->affectsDisplay = 0; - tagPtr->affectsDisplayGeometry = 0; - if ((tagPtr->elideString != NULL) - || (tagPtr->tkfont != None) - || (tagPtr->justifyString != NULL) - || (tagPtr->lMargin1String != NULL) - || (tagPtr->lMargin2String != NULL) - || (tagPtr->offsetString != NULL) - || (tagPtr->rMarginString != NULL) - || (tagPtr->spacing1String != NULL) - || (tagPtr->spacing2String != NULL) - || (tagPtr->spacing3String != NULL) - || (tagPtr->tabStringPtr != NULL) - || (tagPtr->wrapMode != TEXT_WRAPMODE_NULL)) { - tagPtr->affectsDisplay = 1; - tagPtr->affectsDisplayGeometry = 1; - } - if ((tagPtr->border != NULL) - || (tagPtr->reliefString != NULL) - || (tagPtr->bgStipple != None) - || (tagPtr->fgColor != NULL) - || (tagPtr->fgStipple != None) - || (tagPtr->overstrikeString != NULL) - || (tagPtr->underlineString != NULL)) { - tagPtr->affectsDisplay = 1; - } - if (!newTag) { - /* - * This line is not necessary if this is a new tag, - * since it can't possibly have been applied to - * anything yet. - */ - - /* - * VMD: If this is the 'sel' tag, then we don't - * need to call this for all peers, unless we - * actually want to synchronize sel-style changes - * across the peers. - */ - TkTextRedrawTag(textPtr->sharedTextPtr, NULL, - (TkTextIndex *) NULL, - (TkTextIndex *) NULL, tagPtr, 1); - } - return result; + /* + * VMD: If this is the 'sel' tag, then we don't need to call + * this for all peers, unless we actually want to synchronize + * sel-style changes across the peers. + */ + + TkTextRedrawTag(textPtr->sharedTextPtr, NULL, + (TkTextIndex *) NULL, (TkTextIndex *) NULL, tagPtr, 1); } - break; + return result; } - case TAG_DELETE: { - Tcl_HashEntry *hPtr; + break; + } + case TAG_DELETE: { + Tcl_HashEntry *hPtr; - if (objc < 4) { - Tcl_WrongNumArgs(interp, 3, objv, "tagName ?tagName ...?"); - return TCL_ERROR; - } - for (i = 3; i < objc; i++) { - hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->tagTable, - Tcl_GetString(objv[i])); - if (hPtr == NULL) { - /* Either this tag doesn't exist or it's the 'sel' - * tag (which is not in the hash table). Either - * way we don't want to delete it. - */ - continue; - } - tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); - if (tagPtr == textPtr->selTagPtr) { - continue; - } - if (tagPtr->affectsDisplay) { - TkTextRedrawTag(textPtr->sharedTextPtr, NULL, - (TkTextIndex *) NULL, - (TkTextIndex *) NULL, tagPtr, 1); - } - TkTextDeleteTag(textPtr, tagPtr); - Tcl_DeleteHashEntry(hPtr); - } - break; + if (objc < 4) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName ?tagName ...?"); + return TCL_ERROR; } - case TAG_LOWER: { - TkTextTag *tagPtr2; - int prio; + for (i = 3; i < objc; i++) { + hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->tagTable, + Tcl_GetString(objv[i])); + if (hPtr == NULL) { + /* + * Either this tag doesn't exist or it's the 'sel' tag (which + * is not in the hash table). Either way we don't want to + * delete it. + */ - if ((objc != 4) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 3, objv, "tagName ?belowThis?"); - return TCL_ERROR; + continue; } - tagPtr = FindTag(interp, textPtr, objv[3]); - if (tagPtr == NULL) { - return TCL_ERROR; + tagPtr = (TkTextTag *) Tcl_GetHashValue(hPtr); + if (tagPtr == textPtr->selTagPtr) { + continue; } - if (objc == 5) { - tagPtr2 = FindTag(interp, textPtr, objv[4]); - if (tagPtr2 == NULL) { - return TCL_ERROR; - } - if (tagPtr->priority < tagPtr2->priority) { - prio = tagPtr2->priority - 1; - } else { - prio = tagPtr2->priority; - } - } else { - prio = 0; + if (tagPtr->affectsDisplay) { + TkTextRedrawTag(textPtr->sharedTextPtr, NULL, + (TkTextIndex *) NULL, (TkTextIndex *) NULL, tagPtr, 1); } - ChangeTagPriority(textPtr, tagPtr, prio); - /* - * If this is the 'sel' tag, then we don't actually need - * to call this for all peers. - */ - TkTextRedrawTag(textPtr->sharedTextPtr, NULL, - (TkTextIndex *) NULL, - (TkTextIndex *) NULL, - tagPtr, 1); - break; + TkTextDeleteTag(textPtr, tagPtr); + Tcl_DeleteHashEntry(hPtr); } - case TAG_NAMES: { - TkTextTag **arrayPtr; - int arraySize; - Tcl_Obj *listObj; - - if ((objc != 3) && (objc != 4)) { - Tcl_WrongNumArgs(interp, 3, objv, "?index?"); + break; + } + case TAG_LOWER: { + TkTextTag *tagPtr2; + int prio; + + if ((objc != 4) && (objc != 5)) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName ?belowThis?"); + return TCL_ERROR; + } + tagPtr = FindTag(interp, textPtr, objv[3]); + if (tagPtr == NULL) { + return TCL_ERROR; + } + if (objc == 5) { + tagPtr2 = FindTag(interp, textPtr, objv[4]); + if (tagPtr2 == NULL) { return TCL_ERROR; } - if (objc == 3) { - Tcl_HashSearch search; - Tcl_HashEntry *hPtr; - - arrayPtr = (TkTextTag **) ckalloc((unsigned) - (textPtr->sharedTextPtr->numTags * sizeof(TkTextTag *))); - for (i = 0, - hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->tagTable, - &search); - hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) { - arrayPtr[i] = (TkTextTag *) Tcl_GetHashValue(hPtr); - } - /* The 'sel' tag is not in the hash table */ - arrayPtr[i] = textPtr->selTagPtr; - arraySize = textPtr->sharedTextPtr->numTags; + if (tagPtr->priority < tagPtr2->priority) { + prio = tagPtr2->priority - 1; } else { - if (TkTextGetObjIndex(interp, textPtr, objv[3], &index1) - != TCL_OK) { - return TCL_ERROR; - } - arrayPtr = TkBTreeGetTags(&index1, textPtr, &arraySize); - if (arrayPtr == NULL) { - return TCL_OK; - } - } - SortTags(arraySize, arrayPtr); - listObj = Tcl_NewListObj(0, NULL); - for (i = 0; i < arraySize; i++) { - tagPtr = arrayPtr[i]; - Tcl_ListObjAppendElement(interp, listObj, - Tcl_NewStringObj(tagPtr->name,-1)); + prio = tagPtr2->priority; } - Tcl_SetObjResult(interp, listObj); - ckfree((char *) arrayPtr); - break; + } else { + prio = 0; } - case TAG_NEXTRANGE: { - TkTextIndex last; - TkTextSearch tSearch; - char position[TK_POS_CHARS]; + ChangeTagPriority(textPtr, tagPtr, prio); - if ((objc != 5) && (objc != 6)) { - Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?"); - return TCL_ERROR; - } - tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, objv[3]); - if (tagPtr == NULL) { - return TCL_OK; + /* + * If this is the 'sel' tag, then we don't actually need to call this + * for all peers. + */ + + TkTextRedrawTag(textPtr->sharedTextPtr, NULL, (TkTextIndex *) NULL, + (TkTextIndex *) NULL, tagPtr, 1); + break; + } + case TAG_NAMES: { + TkTextTag **arrayPtr; + int arraySize; + Tcl_Obj *listObj; + + if ((objc != 3) && (objc != 4)) { + Tcl_WrongNumArgs(interp, 3, objv, "?index?"); + return TCL_ERROR; + } + if (objc == 3) { + Tcl_HashSearch search; + Tcl_HashEntry *hPtr; + + arrayPtr = (TkTextTag **) ckalloc((unsigned) + (textPtr->sharedTextPtr->numTags * sizeof(TkTextTag *))); + for (i=0, hPtr = Tcl_FirstHashEntry( + &textPtr->sharedTextPtr->tagTable, &search); + hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) { + arrayPtr[i] = (TkTextTag *) Tcl_GetHashValue(hPtr); } - if (TkTextGetObjIndex(interp, textPtr, objv[4], &index1) != TCL_OK) { + + /* + * The 'sel' tag is not in the hash table. + */ + + arrayPtr[i] = textPtr->selTagPtr; + arraySize = textPtr->sharedTextPtr->numTags; + } else { + if (TkTextGetObjIndex(interp, textPtr, objv[3], + &index1) != TCL_OK) { return TCL_ERROR; } - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), - 0, &last); - if (objc == 5) { - index2 = last; - } else if (TkTextGetObjIndex(interp, textPtr, objv[5], &index2) - != TCL_OK) { - return TCL_ERROR; + arrayPtr = TkBTreeGetTags(&index1, textPtr, &arraySize); + if (arrayPtr == NULL) { + return TCL_OK; } + } - /* - * The search below is a bit tricky. Rather than use the B-tree - * facilities to stop the search at index2, let it search up - * until the end of the file but check for a position past index2 - * ourselves. The reason for doing it this way is that we only - * care whether the *start* of the range is before index2; once - * we find the start, we don't want TkBTreeNextTag to abort the - * search because the end of the range is after index2. - */ + SortTags(arraySize, arrayPtr); + listObj = Tcl_NewListObj(0, NULL); - TkBTreeStartSearch(&index1, &last, tagPtr, &tSearch); - if (TkBTreeCharTagged(&index1, tagPtr)) { - TkTextSegment *segPtr; - int offset; + for (i = 0; i < arraySize; i++) { + tagPtr = arrayPtr[i]; + Tcl_ListObjAppendElement(interp, listObj, + Tcl_NewStringObj(tagPtr->name,-1)); + } + Tcl_SetObjResult(interp, listObj); + ckfree((char *) arrayPtr); + break; + } + case TAG_NEXTRANGE: { + TkTextIndex last; + TkTextSearch tSearch; + char position[TK_POS_CHARS]; + + if ((objc != 5) && (objc != 6)) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?"); + return TCL_ERROR; + } + tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, objv[3]); + if (tagPtr == NULL) { + return TCL_OK; + } + if (TkTextGetObjIndex(interp, textPtr, objv[4], &index1) != TCL_OK) { + return TCL_ERROR; + } + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, + TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), + 0, &last); + if (objc == 5) { + index2 = last; + } else if (TkTextGetObjIndex(interp, textPtr, objv[5], + &index2) != TCL_OK) { + return TCL_ERROR; + } - /* - * The first character is tagged. See if there is an - * on-toggle just before the character. If not, then - * skip to the end of this tagged range. - */ + /* + * The search below is a bit tricky. Rather than use the B-tree + * facilities to stop the search at index2, let it search up until the + * end of the file but check for a position past index2 ourselves. + * The reason for doing it this way is that we only care whether the + * *start* of the range is before index2; once we find the start, we + * don't want TkBTreeNextTag to abort the search because the end of + * the range is after index2. + */ - for (segPtr = index1.linePtr->segPtr, offset = index1.byteIndex; - offset >= 0; - offset -= segPtr->size, segPtr = segPtr->nextPtr) { - if ((offset == 0) && (segPtr->typePtr == &tkTextToggleOnType) - && (segPtr->body.toggle.tagPtr == tagPtr)) { - goto gotStart; - } - } - if (!TkBTreeNextTag(&tSearch)) { - return TCL_OK; - } - } + TkBTreeStartSearch(&index1, &last, tagPtr, &tSearch); + if (TkBTreeCharTagged(&index1, tagPtr)) { + TkTextSegment *segPtr; + int offset; /* - * Find the start of the tagged range. + * The first character is tagged. See if there is an on-toggle + * just before the character. If not, then skip to the end of this + * tagged range. */ - if (!TkBTreeNextTag(&tSearch)) { - return TCL_OK; + for (segPtr = index1.linePtr->segPtr, offset = index1.byteIndex; + offset >= 0; + offset -= segPtr->size, segPtr = segPtr->nextPtr) { + if ((offset == 0) && (segPtr->typePtr == &tkTextToggleOnType) + && (segPtr->body.toggle.tagPtr == tagPtr)) { + goto gotStart; + } } - gotStart: - if (TkTextIndexCmp(&tSearch.curIndex, &index2) >= 0) { + if (!TkBTreeNextTag(&tSearch)) { return TCL_OK; } - TkTextPrintIndex(textPtr, &tSearch.curIndex, position); - Tcl_AppendElement(interp, position); - TkBTreeNextTag(&tSearch); - TkTextPrintIndex(textPtr, &tSearch.curIndex, position); - Tcl_AppendElement(interp, position); - break; } - case TAG_PREVRANGE: { - TkTextIndex last; - TkTextSearch tSearch; - char position1[TK_POS_CHARS]; - char position2[TK_POS_CHARS]; - - if ((objc != 5) && (objc != 6)) { - Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?"); - return TCL_ERROR; - } - tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, objv[3]); - if (tagPtr == NULL) { - return TCL_OK; - } - if (TkTextGetObjIndex(interp, textPtr, objv[4], &index1) != TCL_OK) { - return TCL_ERROR; - } - if (objc == 5) { - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - 0, 0, &index2); - } else if (TkTextGetObjIndex(interp, textPtr, objv[5], &index2) - != TCL_OK) { - return TCL_ERROR; - } + /* + * Find the start of the tagged range. + */ + + if (!TkBTreeNextTag(&tSearch)) { + return TCL_OK; + } + + gotStart: + if (TkTextIndexCmp(&tSearch.curIndex, &index2) >= 0) { + return TCL_OK; + } + TkTextPrintIndex(textPtr, &tSearch.curIndex, position); + Tcl_AppendElement(interp, position); + TkBTreeNextTag(&tSearch); + TkTextPrintIndex(textPtr, &tSearch.curIndex, position); + Tcl_AppendElement(interp, position); + break; + } + case TAG_PREVRANGE: { + TkTextIndex last; + TkTextSearch tSearch; + char position1[TK_POS_CHARS]; + char position2[TK_POS_CHARS]; + + if ((objc != 5) && (objc != 6)) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName index1 ?index2?"); + return TCL_ERROR; + } + tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, objv[3]); + if (tagPtr == NULL) { + return TCL_OK; + } + if (TkTextGetObjIndex(interp, textPtr, objv[4], &index1) != TCL_OK) { + return TCL_ERROR; + } + if (objc == 5) { + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0, + &index2); + } else if (TkTextGetObjIndex(interp, textPtr, objv[5], + &index2) != TCL_OK) { + return TCL_ERROR; + } + + /* + * The search below is a bit weird. The previous toggle can be either + * an on or off toggle. If it is an on toggle, then we need to turn + * around and search forward for the end toggle. Otherwise we keep + * searching backwards. + */ + + TkBTreeStartSearchBack(&index1, &index2, tagPtr, &tSearch); + + if (!TkBTreePrevTag(&tSearch)) { /* - * The search below is a bit weird. The previous toggle can be - * either an on or off toggle. If it is an on toggle, then we - * need to turn around and search forward for the end toggle. - * Otherwise we keep searching backwards. + * Special case, there may be a tag off toggle at index1, and a + * tag on toggle before the start of a partial peer widget. In + * this case we missed it. */ - TkBTreeStartSearchBack(&index1, &index2, tagPtr, &tSearch); - - if (!TkBTreePrevTag(&tSearch)) { - /* - * Special case, there may be a tag off toggle at - * index1, and a tag on toggle before the start of a - * partial peer widget. In this case we missed it. - */ - if (textPtr->start != NULL && (textPtr->start == index2.linePtr) - && (index2.byteIndex == 0) && TkBTreeCharTagged(&index2, tagPtr) + if (textPtr->start != NULL && (textPtr->start == index2.linePtr) + && (index2.byteIndex == 0) + && TkBTreeCharTagged(&index2, tagPtr) && (TkTextIndexCmp(&index2, &index1) < 0)) { - /* - * The first character is tagged, so just add the - * range from the first char to the start of the - * range. - */ - TkTextPrintIndex(textPtr, &index2, position1); - TkTextPrintIndex(textPtr, &index1, position2); - Tcl_AppendElement(interp, position1); - Tcl_AppendElement(interp, position2); - } - return TCL_OK; + /* + * The first character is tagged, so just add the range from + * the first char to the start of the range. + */ + + TkTextPrintIndex(textPtr, &index2, position1); + TkTextPrintIndex(textPtr, &index1, position2); + Tcl_AppendElement(interp, position1); + Tcl_AppendElement(interp, position2); } - if (tSearch.segPtr->typePtr == &tkTextToggleOnType) { - TkTextPrintIndex(textPtr, &tSearch.curIndex, position1); - if (textPtr->start != NULL) { - /* - * Make sure the first index is not before the - * first allowed text index in this widget. - */ - TkTextIndex firstIndex; - firstIndex.linePtr = textPtr->start; - firstIndex.byteIndex = 0; - firstIndex.textPtr = NULL; - if (TkTextIndexCmp(&tSearch.curIndex, &firstIndex) < 0) { - if (TkTextIndexCmp(&firstIndex, &index1) >= 0) { - /* - * But now the new first index is actually - * too far along in the text, so nothing - * is returned. - */ - return TCL_OK; - } - TkTextPrintIndex(textPtr, &firstIndex, position1); + return TCL_OK; + } + + if (tSearch.segPtr->typePtr == &tkTextToggleOnType) { + TkTextPrintIndex(textPtr, &tSearch.curIndex, position1); + if (textPtr->start != NULL) { + /* + * Make sure the first index is not before the first allowed + * text index in this widget. + */ + + TkTextIndex firstIndex; + + firstIndex.linePtr = textPtr->start; + firstIndex.byteIndex = 0; + firstIndex.textPtr = NULL; + if (TkTextIndexCmp(&tSearch.curIndex, &firstIndex) < 0) { + if (TkTextIndexCmp(&firstIndex, &index1) >= 0) { + /* + * But now the new first index is actually too far + * along in the text, so nothing is returned. + */ + + return TCL_OK; } + TkTextPrintIndex(textPtr, &firstIndex, position1); } - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), - 0, &last); - TkBTreeStartSearch(&tSearch.curIndex, &last, tagPtr, &tSearch); - TkBTreeNextTag(&tSearch); - TkTextPrintIndex(textPtr, &tSearch.curIndex, position2); - } else { - TkTextPrintIndex(textPtr, &tSearch.curIndex, position2); - TkBTreePrevTag(&tSearch); - TkTextPrintIndex(textPtr, &tSearch.curIndex, position1); - if (TkTextIndexCmp(&tSearch.curIndex, &index2) < 0) { - if (textPtr->start != NULL - && index2.linePtr == textPtr->start + } + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, + TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), + 0, &last); + TkBTreeStartSearch(&tSearch.curIndex, &last, tagPtr, &tSearch); + TkBTreeNextTag(&tSearch); + TkTextPrintIndex(textPtr, &tSearch.curIndex, position2); + } else { + TkTextPrintIndex(textPtr, &tSearch.curIndex, position2); + TkBTreePrevTag(&tSearch); + TkTextPrintIndex(textPtr, &tSearch.curIndex, position1); + if (TkTextIndexCmp(&tSearch.curIndex, &index2) < 0) { + if (textPtr->start != NULL && index2.linePtr == textPtr->start && index2.byteIndex == 0) { - /* It's ok */ - TkTextPrintIndex(textPtr, &index2, position1); - } else { - return TCL_OK; - } + /* It's ok */ + TkTextPrintIndex(textPtr, &index2, position1); + } else { + return TCL_OK; } } - Tcl_AppendElement(interp, position1); - Tcl_AppendElement(interp, position2); - break; } - case TAG_RAISE: { - TkTextTag *tagPtr2; - int prio; + Tcl_AppendElement(interp, position1); + Tcl_AppendElement(interp, position2); + break; + } + case TAG_RAISE: { + TkTextTag *tagPtr2; + int prio; - if ((objc != 4) && (objc != 5)) { - Tcl_WrongNumArgs(interp, 3, objv, "tagName ?aboveThis?"); - return TCL_ERROR; - } - tagPtr = FindTag(interp, textPtr, objv[3]); - if (tagPtr == NULL) { + if ((objc != 4) && (objc != 5)) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName ?aboveThis?"); + return TCL_ERROR; + } + tagPtr = FindTag(interp, textPtr, objv[3]); + if (tagPtr == NULL) { + return TCL_ERROR; + } + if (objc == 5) { + tagPtr2 = FindTag(interp, textPtr, objv[4]); + if (tagPtr2 == NULL) { return TCL_ERROR; } - if (objc == 5) { - tagPtr2 = FindTag(interp, textPtr, objv[4]); - if (tagPtr2 == NULL) { - return TCL_ERROR; - } - if (tagPtr->priority <= tagPtr2->priority) { - prio = tagPtr2->priority; - } else { - prio = tagPtr2->priority + 1; - } + if (tagPtr->priority <= tagPtr2->priority) { + prio = tagPtr2->priority; } else { - prio = textPtr->sharedTextPtr->numTags-1; + prio = tagPtr2->priority + 1; } - ChangeTagPriority(textPtr, tagPtr, prio); - /* - * If this is the 'sel' tag, then we don't actually need - * to call this for all peers. - */ - TkTextRedrawTag(textPtr->sharedTextPtr, NULL, - (TkTextIndex *) NULL, (TkTextIndex *) NULL, - tagPtr, 1); - break; + } else { + prio = textPtr->sharedTextPtr->numTags-1; } - case TAG_RANGES: { - TkTextIndex first, last; - TkTextSearch tSearch; - Tcl_Obj *listObj = Tcl_NewListObj(0, NULL); - int count = 0; - - if (objc != 4) { - Tcl_WrongNumArgs(interp, 3, objv, "tagName"); - return TCL_ERROR; - } - tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, objv[3]); - if (tagPtr == NULL) { - return TCL_OK; - } - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - 0, 0, &first); - TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), - 0, &last); - TkBTreeStartSearch(&first, &last, tagPtr, &tSearch); - if (TkBTreeCharTagged(&first, tagPtr)) { - Tcl_ListObjAppendElement(interp, listObj, + ChangeTagPriority(textPtr, tagPtr, prio); + + /* + * If this is the 'sel' tag, then we don't actually need to call this + * for all peers. + */ + + TkTextRedrawTag(textPtr->sharedTextPtr, NULL, (TkTextIndex *) NULL, + (TkTextIndex *) NULL, tagPtr, 1); + break; + } + case TAG_RANGES: { + TkTextIndex first, last; + TkTextSearch tSearch; + Tcl_Obj *listObj = Tcl_NewListObj(0, NULL); + int count = 0; + + if (objc != 4) { + Tcl_WrongNumArgs(interp, 3, objv, "tagName"); + return TCL_ERROR; + } + tagPtr = FindTag((Tcl_Interp *) NULL, textPtr, objv[3]); + if (tagPtr == NULL) { + return TCL_OK; + } + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0, + &first); + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, + TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), + 0, &last); + TkBTreeStartSearch(&first, &last, tagPtr, &tSearch); + if (TkBTreeCharTagged(&first, tagPtr)) { + Tcl_ListObjAppendElement(interp, listObj, TkTextNewIndexObj(textPtr, &first)); - count++; - } - while (TkBTreeNextTag(&tSearch)) { - Tcl_ListObjAppendElement(interp, listObj, + count++; + } + while (TkBTreeNextTag(&tSearch)) { + Tcl_ListObjAppendElement(interp, listObj, TkTextNewIndexObj(textPtr, &tSearch.curIndex)); - count++; - } - if (count % 2 == 1) { - /* - * If a text widget uses '-end', it won't necessarily - * run to the end of the B-tree, and therefore the - * tag range might not be closed. In this case we - * add the end of the range. - */ - Tcl_ListObjAppendElement(interp, listObj, + count++; + } + if (count % 2 == 1) { + /* + * If a text widget uses '-end', it won't necessarily run to the + * end of the B-tree, and therefore the tag range might not be + * closed. In this case we add the end of the range. + */ + + Tcl_ListObjAppendElement(interp, listObj, TkTextNewIndexObj(textPtr, &last)); - } - Tcl_SetObjResult(interp, listObj); - break; } + Tcl_SetObjResult(interp, listObj); + break; + } } return TCL_OK; } @@ -899,15 +907,15 @@ TkTextTagCmd(textPtr, interp, objc, objv) * * TkTextCreateTag -- * - * Find the record describing a tag within a given text widget, - * creating a new record if one doesn't already exist. + * Find the record describing a tag within a given text widget, creating + * a new record if one doesn't already exist. * * Results: * The return value is a pointer to the TkTextTag record for tagName. * * Side effects: - * A new tag record is created if there isn't one already defined - * for tagName. + * A new tag record is created if there isn't one already defined for + * tagName. * *---------------------------------------------------------------------- */ @@ -916,14 +924,14 @@ TkTextTag * TkTextCreateTag(textPtr, tagName, newTag) TkText *textPtr; /* Widget in which tag is being used. */ CONST char *tagName; /* Name of desired tag. */ - int *newTag; /* If non-NULL, then return 1 if new, - * or 0 if already exists. */ + int *newTag; /* If non-NULL, then return 1 if new, or 0 if + * already exists. */ { register TkTextTag *tagPtr; Tcl_HashEntry *hPtr = NULL; int new; CONST char *name; - + if (!strcmp(tagName, "sel")) { if (textPtr->selTagPtr != NULL) { if (newTag != NULL) { @@ -937,8 +945,8 @@ TkTextCreateTag(textPtr, tagName, newTag) } name = "sel"; } else { - hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->tagTable, - tagName, &new); + hPtr = Tcl_CreateHashEntry(&textPtr->sharedTextPtr->tagTable, + tagName, &new); if (newTag != NULL) { *newTag = new; } @@ -949,8 +957,8 @@ TkTextCreateTag(textPtr, tagName, newTag) } /* - * No existing entry. Create a new one, initialize it, and add a - * pointer to it to the hash table entry. + * No existing entry. Create a new one, initialize it, and add a pointer + * to it to the hash table entry. */ tagPtr = (TkTextTag *) ckalloc(sizeof(TkTextTag)); @@ -1002,7 +1010,8 @@ TkTextCreateTag(textPtr, tagName, newTag) } else { Tcl_SetHashValue(hPtr, tagPtr); } - tagPtr->optionTable = Tk_CreateOptionTable(textPtr->interp, tagOptionSpecs); + tagPtr->optionTable = + Tk_CreateOptionTable(textPtr->interp, tagOptionSpecs); return tagPtr; } @@ -1014,10 +1023,9 @@ TkTextCreateTag(textPtr, tagName, newTag) * See if tag is defined for a given widget. * * Results: - * If tagName is defined in textPtr, a pointer to its TkTextTag - * structure is returned. Otherwise NULL is returned and an - * error message is recorded in the interp's result unless interp - * is NULL. + * If tagName is defined in textPtr, a pointer to its TkTextTag structure + * is returned. Otherwise NULL is returned and an error message is + * recorded in the interp's result unless interp is NULL. * * Side effects: * None. @@ -1027,8 +1035,8 @@ TkTextCreateTag(textPtr, tagName, newTag) static TkTextTag * FindTag(interp, textPtr, tagName) - Tcl_Interp *interp; /* Interpreter to use for error message; - * if NULL, then don't record an error + Tcl_Interp *interp; /* Interpreter to use for error message; if + * NULL, then don't record an error * message. */ TkText *textPtr; /* Widget in which tag is being used. */ Tcl_Obj *tagName; /* Name of desired tag. */ @@ -1036,12 +1044,13 @@ FindTag(interp, textPtr, tagName) Tcl_HashEntry *hPtr; int len; CONST char *str; + str = Tcl_GetStringFromObj(tagName, &len); if (len == 3 && !strcmp(str,"sel")) { return textPtr->selTagPtr; } - hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->tagTable, - Tcl_GetString(tagName)); + hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->tagTable, + Tcl_GetString(tagName)); if (hPtr != NULL) { return (TkTextTag *) Tcl_GetHashValue(hPtr); } @@ -1057,47 +1066,44 @@ FindTag(interp, textPtr, tagName) * * TkTextDeleteTag -- * - * This procedure is called to carry out most actions associated - * with the 'tag delete' sub-command. It will remove all - * evidence of the tag from the B-tree, and then call - * TkTextFreeTag to clean up the tag structure itself. - * - * The only actions this doesn't carry out it to check if - * the deletion of the tag requires something to be - * re-displayed, and to remove the tag from the tagTable - * (hash table) if that is necessary (i.e. if it's not the - * 'sel' tag). It is expected that the caller carry out both - * of these actions. + * This function is called to carry out most actions associated with the + * 'tag delete' sub-command. It will remove all evidence of the tag from + * the B-tree, and then call TkTextFreeTag to clean up the tag structure + * itself. + * + * The only actions this doesn't carry out it to check if the deletion of + * the tag requires something to be re-displayed, and to remove the tag + * from the tagTable (hash table) if that is necessary (i.e. if it's not + * the 'sel' tag). It is expected that the caller carry out both of these + * actions. * * Results: * None. * * Side effects: - * Memory and other resources are freed, the B-tree is - * manipulated. + * Memory and other resources are freed, the B-tree is manipulated. * *---------------------------------------------------------------------- */ void TkTextDeleteTag(textPtr, tagPtr) - TkText *textPtr; /* Info about overall widget. */ - register TkTextTag *tagPtr; /* Tag being deleted. */ + TkText *textPtr; /* Info about overall widget. */ + register TkTextTag *tagPtr; /* Tag being deleted. */ { TkTextIndex first, last; TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0, &first); TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, - TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), - 0, &last), + TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr), 0, &last), TkBTreeTag(&first, &last, tagPtr, 0); - + if (tagPtr == textPtr->selTagPtr) { /* - * Send an event that the selection changed. - * This is equivalent to - * "event generate $textWidget <<Selection>>" + * Send an event that the selection changed. This is equivalent to: + * event generate $textWidget <<Selection>> */ + TkTextSelectionEvent(textPtr); } else { /* @@ -1105,6 +1111,7 @@ TkTextDeleteTag(textPtr, tagPtr) * don't want removal of one sel tag to remove bindings which * are still valid in other peer widgets. */ + if (textPtr->sharedTextPtr->bindingTable != NULL) { Tk_DeleteAllBindings(textPtr->sharedTextPtr->bindingTable, (ClientData) tagPtr->name); @@ -1115,11 +1122,10 @@ TkTextDeleteTag(textPtr, tagPtr) * Update the tag priorities to reflect the deletion of this tag. */ - ChangeTagPriority(textPtr, tagPtr, - textPtr->sharedTextPtr->numTags-1); + ChangeTagPriority(textPtr, tagPtr, + textPtr->sharedTextPtr->numTags-1); textPtr->sharedTextPtr->numTags -= 1; TkTextFreeTag(textPtr, tagPtr); - } /* @@ -1127,8 +1133,8 @@ TkTextDeleteTag(textPtr, tagPtr) * * TkTextFreeTag -- * - * This procedure is called when a tag is deleted to free up the - * memory and other resources associated with the tag. + * This function is called when a tag is deleted to free up the memory + * and other resources associated with the tag. * * Results: * None. @@ -1141,19 +1147,30 @@ TkTextDeleteTag(textPtr, tagPtr) void TkTextFreeTag(textPtr, tagPtr) - TkText *textPtr; /* Info about overall widget. */ - register TkTextTag *tagPtr; /* Tag being deleted. */ + TkText *textPtr; /* Info about overall widget. */ + register TkTextTag *tagPtr; /* Tag being deleted. */ { int i; - - /* Let Tk do most of the hard work for us */ + + /* + * Let Tk do most of the hard work for us. + */ + Tk_FreeConfigOptions((char *) tagPtr, tagPtr->optionTable, - textPtr->tkwin); - /* This associated information is managed by us */ + textPtr->tkwin); + + /* + * This associated information is managed by us. + */ + if (tagPtr->tabArrayPtr != NULL) { ckfree((char *) tagPtr->tabArrayPtr); } - /* Make sure this tag isn't referenced from the 'current' tag array */ + + /* + * Make sure this tag isn't referenced from the 'current' tag array. + */ + for (i = 0; i < textPtr->numCurTags; i++) { if (textPtr->curTagArrayPtr[i] == tagPtr) { for (; i < textPtr->numCurTags-1; i++) { @@ -1164,10 +1181,12 @@ TkTextFreeTag(textPtr, tagPtr) break; } } - /* - * If this tag is widget-specific (peer widgets) then clean - * up the refCount it holds. + + /* + * If this tag is widget-specific (peer widgets) then clean up the + * refCount it holds. */ + if (tagPtr->textPtr != NULL) { if (textPtr != tagPtr->textPtr) { Tcl_Panic("Tag being deleted from wrong widget"); @@ -1178,7 +1197,11 @@ TkTextFreeTag(textPtr, tagPtr) } tagPtr->textPtr = NULL; } - /* Finally free the tag's memory */ + + /* + * Finally free the tag's memory. + */ + ckfree((char *) tagPtr); } @@ -1187,9 +1210,8 @@ TkTextFreeTag(textPtr, tagPtr) * * SortTags -- * - * This procedure sorts an array of tag pointers in increasing - * order of priority, optimizing for the common case where the - * array is small. + * This function sorts an array of tag pointers in increasing order of + * priority, optimizing for the common case where the array is small. * * Results: * None. @@ -1228,7 +1250,7 @@ SortTags(numTags, tagArrayPtr) } } else { qsort((VOID *) tagArrayPtr, (unsigned) numTags, sizeof (TkTextTag *), - TagSortProc); + TagSortProc); } } @@ -1237,14 +1259,14 @@ SortTags(numTags, tagArrayPtr) * * TagSortProc -- * - * This procedure is called by qsort when sorting an array of - * tags in priority order. + * This function is called by qsort() when sorting an array of tags in + * priority order. * * Results: - * The return value is -1 if the first argument should be before - * the second element (i.e. it has lower priority), 0 if it's - * equivalent (this should never happen!), and 1 if it should be - * after the second element. + * The return value is -1 if the first argument should be before the + * second element (i.e. it has lower priority), 0 if it's equivalent + * (this should never happen!), and 1 if it should be after the second + * element. * * Side effects: * None. @@ -1268,29 +1290,26 @@ TagSortProc(first, second) * * ChangeTagPriority -- * - * This procedure changes the priority of a tag by modifying - * its priority and the priorities of other tags that are affected - * by the change. + * This function changes the priority of a tag by modifying its priority + * and the priorities of other tags that are affected by the change. * * Results: * None. * * Side effects: - * Priorities may be changed for some or all of the tags in - * textPtr. The tags will be arranged so that there is exactly one - * tag at each priority level between 0 and - * textPtr->sharedTextPtr->numTags-1, with tagPtr at priority - * "prio". + * Priorities may be changed for some or all of the tags in textPtr. The + * tags will be arranged so that there is exactly one tag at each + * priority level between 0 and textPtr->sharedTextPtr->numTags-1, with + * tagPtr at priority "prio". * *---------------------------------------------------------------------- */ static void ChangeTagPriority(textPtr, tagPtr, prio) - TkText *textPtr; /* Information about text widget. */ - TkTextTag *tagPtr; /* Tag whose priority is to be - * changed. */ - int prio; /* New priority for tag. */ + TkText *textPtr; /* Information about text widget. */ + TkTextTag *tagPtr; /* Tag whose priority is to be changed. */ + int prio; /* New priority for tag. */ { int low, high, delta; register TkTextTag *tagPtr2; @@ -1314,11 +1333,13 @@ ChangeTagPriority(textPtr, tagPtr, prio) high = prio; delta = -1; } - /* + + /* * Adjust first the 'sel' tag, then all others from the hash table */ - if ((textPtr->selTagPtr->priority >= low) - && (textPtr->selTagPtr->priority <= high)) { + + if ((textPtr->selTagPtr->priority >= low) + && (textPtr->selTagPtr->priority <= high)) { textPtr->selTagPtr->priority += delta; } for (hPtr = Tcl_FirstHashEntry(&textPtr->sharedTextPtr->tagTable, &search); @@ -1336,37 +1357,36 @@ ChangeTagPriority(textPtr, tagPtr, prio) * * TkTextBindProc -- * - * This procedure is invoked by the Tk dispatcher to handle - * events associated with bindings on items. + * This function is invoked by the Tk dispatcher to handle events + * associated with bindings on items. * * Results: * None. * * Side effects: - * Depends on the command invoked as part of the binding - * (if there was any). + * Depends on the command invoked as part of the binding (if there was + * any). * *-------------------------------------------------------------- */ void TkTextBindProc(clientData, eventPtr) - ClientData clientData; /* Pointer to canvas structure. */ - XEvent *eventPtr; /* Pointer to X event that just - * happened. */ + ClientData clientData; /* Pointer to canvas structure. */ + XEvent *eventPtr; /* Pointer to X event that just happened. */ { TkText *textPtr = (TkText *) clientData; int repick = 0; -# define AnyButtonMask (Button1Mask|Button2Mask|Button3Mask\ - |Button4Mask|Button5Mask) +# define AnyButtonMask \ + (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask) textPtr->refCount++; /* - * This code simulates grabs for mouse buttons by keeping track - * of whether a button is pressed and refusing to pick a new current - * character while a button is pressed. + * This code simulates grabs for mouse buttons by keeping track of whether + * a button is pressed and refusing to pick a new current character while + * a button is pressed. */ if (eventPtr->type == ButtonPress) { @@ -1375,24 +1395,24 @@ TkTextBindProc(clientData, eventPtr) int mask; switch (eventPtr->xbutton.button) { - case Button1: - mask = Button1Mask; - break; - case Button2: - mask = Button2Mask; - break; - case Button3: - mask = Button3Mask; - break; - case Button4: - mask = Button4Mask; - break; - case Button5: - mask = Button5Mask; - break; - default: - mask = 0; - break; + case Button1: + mask = Button1Mask; + break; + case Button2: + mask = Button2Mask; + break; + case Button3: + mask = Button3Mask; + break; + case Button4: + mask = Button4Mask; + break; + case Button5: + mask = Button5Mask; + break; + default: + mask = 0; + break; } if ((eventPtr->xbutton.state & AnyButtonMask) == (unsigned) mask) { textPtr->flags &= ~BUTTON_DOWN; @@ -1415,10 +1435,11 @@ TkTextBindProc(clientData, eventPtr) } TkTextPickCurrent(textPtr, eventPtr); } - if ((textPtr->numCurTags > 0) && (textPtr->sharedTextPtr->bindingTable != NULL) + if ((textPtr->numCurTags > 0) + && (textPtr->sharedTextPtr->bindingTable != NULL) && (textPtr->tkwin != NULL) && !(textPtr->flags & DESTROYED)) { - TagBindEvent(textPtr, eventPtr, textPtr->numCurTags, - textPtr->curTagArrayPtr); + TagBindEvent(textPtr, eventPtr, textPtr->numCurTags, + textPtr->curTagArrayPtr); } if (repick) { unsigned int oldState; @@ -1432,7 +1453,7 @@ TkTextBindProc(clientData, eventPtr) eventPtr->xbutton.state = oldState; } - done: + done: if (--textPtr->refCount == 0) { ckfree((char *) textPtr); } @@ -1443,57 +1464,55 @@ TkTextBindProc(clientData, eventPtr) * * TkTextPickCurrent -- * - * Find the character containing the coordinates in an event - * and place the "current" mark on that character. If the - * "current" mark has moved then generate a fake leave event - * on the old current character and a fake enter event on the new - * current character. + * Find the character containing the coordinates in an event and place + * the "current" mark on that character. If the "current" mark has moved + * then generate a fake leave event on the old current character and a + * fake enter event on the new current character. * * Results: * None. * * Side effects: - * The current mark for textPtr may change. If it does, - * then the commands associated with character entry and leave - * could do just about anything. For example, the text widget - * might be deleted. It is up to the caller to protect itself - * by incrementing the refCount of the text widget. + * The current mark for textPtr may change. If it does, then the commands + * associated with character entry and leave could do just about + * anything. For example, the text widget might be deleted. It is up to + * the caller to protect itself by incrementing the refCount of the text + * widget. * *-------------------------------------------------------------- */ void TkTextPickCurrent(textPtr, eventPtr) - register TkText *textPtr; /* Text widget in which to select - * current character. */ - XEvent *eventPtr; /* Event describing location of - * mouse cursor. Must be EnterWindow, - * LeaveWindow, ButtonRelease, or - * MotionNotify. */ + register TkText *textPtr; /* Text widget in which to select current + * character. */ + XEvent *eventPtr; /* Event describing location of mouse cursor. + * Must be EnterWindow, LeaveWindow, + * ButtonRelease, or MotionNotify. */ { TkTextIndex index; TkTextTag **oldArrayPtr, **newArrayPtr; - TkTextTag **copyArrayPtr = NULL; /* Initialization needed to prevent - * compiler warning. */ - + TkTextTag **copyArrayPtr = NULL; + /* Initialization needed to prevent compiler + * warning. */ int numOldTags, numNewTags, i, j, size, nearby; XEvent event; /* - * If a button is down, then don't do anything at all; we'll be - * called again when all buttons are up, and we can repick then. - * This implements a form of mouse grabbing. + * If a button is down, then don't do anything at all; we'll be called + * again when all buttons are up, and we can repick then. This implements + * a form of mouse grabbing. */ if (textPtr->flags & BUTTON_DOWN) { - if (((eventPtr->type == EnterNotify) || (eventPtr->type == LeaveNotify)) + if (((eventPtr->type == EnterNotify) + || (eventPtr->type == LeaveNotify)) && ((eventPtr->xcrossing.mode == NotifyGrab) || (eventPtr->xcrossing.mode == NotifyUngrab))) { /* - * Special case: the window is being entered or left because - * of a grab or ungrab. In this case, repick after all. - * Furthermore, clear BUTTON_DOWN to release the simulated - * grab. + * Special case: the window is being entered or left because of a + * grab or ungrab. In this case, repick after all. Furthermore, + * clear BUTTON_DOWN to release the simulated grab. */ textPtr->flags &= ~BUTTON_DOWN; @@ -1503,12 +1522,12 @@ TkTextPickCurrent(textPtr, eventPtr) } /* - * Save information about this event in the widget in case we have - * to synthesize more enter and leave events later (e.g. because a - * character was deleted, causing a new character to be underneath - * the mouse cursor). Also translate MotionNotify events into - * EnterNotify events, since that's what gets reported to event - * handlers when the current character changes. + * Save information about this event in the widget in case we have to + * synthesize more enter and leave events later (e.g. because a character + * was deleted, causing a new character to be underneath the mouse + * cursor). Also translate MotionNotify events into EnterNotify events, + * since that's what gets reported to event handlers when the current + * character changes. */ if (eventPtr != &textPtr->pickEvent) { @@ -1539,8 +1558,8 @@ TkTextPickCurrent(textPtr, eventPtr) } /* - * Find the new current character, then find and sort all of the - * tags associated with it. + * Find the new current character, then find and sort all of the tags + * associated with it. */ if (textPtr->pickEvent.type != LeaveNotify) { @@ -1559,11 +1578,10 @@ TkTextPickCurrent(textPtr, eventPtr) } /* - * Resort the tags associated with the previous marked character - * (the priorities might have changed), then make a copy of the - * new tags, and compare the old tags to the copy, nullifying - * any tags that are present in both groups (i.e. the tags that - * haven't changed). + * Resort the tags associated with the previous marked character (the + * priorities might have changed), then make a copy of the new tags, and + * compare the old tags to the copy, nullifying any tags that are present + * in both groups (i.e. the tags that haven't changed). */ SortTags(textPtr->numCurTags, textPtr->curTagArrayPtr); @@ -1583,13 +1601,12 @@ TkTextPickCurrent(textPtr, eventPtr) } /* - * Invoke the binding system with a LeaveNotify event for all of - * the tags that have gone away. We have to be careful here, - * because it's possible that the binding could do something - * (like calling tkwait) that eventually modifies - * textPtr->curTagArrayPtr. To avoid problems in situations like - * this, update curTagArrayPtr to its new value before invoking - * any bindings, and don't use it any more here. + * Invoke the binding system with a LeaveNotify event for all of the tags + * that have gone away. We have to be careful here, because it's possible + * that the binding could do something (like calling tkwait) that + * eventually modifies textPtr->curTagArrayPtr. To avoid problems in + * situations like this, update curTagArrayPtr to its new value before + * invoking any bindings, and don't use it any more here. */ numOldTags = textPtr->numCurTags; @@ -1597,15 +1614,16 @@ TkTextPickCurrent(textPtr, eventPtr) oldArrayPtr = textPtr->curTagArrayPtr; textPtr->curTagArrayPtr = newArrayPtr; if (numOldTags != 0) { - if ((textPtr->sharedTextPtr->bindingTable != NULL) && (textPtr->tkwin != NULL) - && !(textPtr->flags & DESTROYED)) { + if ((textPtr->sharedTextPtr->bindingTable != NULL) + && (textPtr->tkwin != NULL) + && !(textPtr->flags & DESTROYED)) { event = textPtr->pickEvent; event.type = LeaveNotify; /* - * Always use a detail of NotifyAncestor. Besides being - * consistent, this avoids problems where the binding code - * will discard NotifyInferior events. + * Always use a detail of NotifyAncestor. Besides being + * consistent, this avoids problems where the binding code will + * discard NotifyInferior events. */ event.xcrossing.detail = NotifyAncestor; @@ -1615,18 +1633,19 @@ TkTextPickCurrent(textPtr, eventPtr) } /* - * Reset the "current" mark (be careful to recompute its location, - * since it might have changed during an event binding). Then - * invoke the binding system with an EnterNotify event for all of - * the tags that have just appeared. + * Reset the "current" mark (be careful to recompute its location, since + * it might have changed during an event binding). Then invoke the binding + * system with an EnterNotify event for all of the tags that have just + * appeared. */ TkTextPixelIndex(textPtr, textPtr->pickEvent.xcrossing.x, textPtr->pickEvent.xcrossing.y, &index, &nearby); TkTextSetMark(textPtr, "current", &index); if (numNewTags != 0) { - if ((textPtr->sharedTextPtr->bindingTable != NULL) && (textPtr->tkwin != NULL) - && !(textPtr->flags & DESTROYED) && !nearby) { + if ((textPtr->sharedTextPtr->bindingTable != NULL) + && (textPtr->tkwin != NULL) + && !(textPtr->flags & DESTROYED) && !nearby) { event = textPtr->pickEvent; event.type = EnterNotify; event.xcrossing.detail = NotifyAncestor; @@ -1641,65 +1660,74 @@ TkTextPickCurrent(textPtr, eventPtr) * * TagBindEvent -- * - * Trigger given events for all tags that match the - * relevant bindings. To handle the "sel" tag - * correctly in all peer widgets, we must use the + * Trigger given events for all tags that match the relevant bindings. + * To handle the "sel" tag correctly in all peer widgets, we must use the * name of the tags as the binding table element. * * Results: * None. * * Side effects: - * Almost anything can be triggered by tag bindings, - * including deletion of the text widget. + * Almost anything can be triggered by tag bindings, including deletion + * of the text widget. * *-------------------------------------------------------------- */ static void TagBindEvent(textPtr, eventPtr, numTags, tagArrayPtr) - TkText *textPtr; /* Text widget to fire bindings - * in. */ - XEvent *eventPtr; /* What actually happened. */ - int numTags; /* Number of relevant tags. */ - TkTextTag **tagArrayPtr; /* Array of relevant tags. */ + TkText *textPtr; /* Text widget to fire bindings in. */ + XEvent *eventPtr; /* What actually happened. */ + int numTags; /* Number of relevant tags. */ + TkTextTag **tagArrayPtr; /* Array of relevant tags. */ { #define NUM_BIND_TAGS 10 CONST char *nameArray[NUM_BIND_TAGS]; CONST char **nameArrPtr; int i; - - /* - * Try to avoid allocation unless there are lots of tags + + /* + * Try to avoid allocation unless there are lots of tags. */ + if (numTags > NUM_BIND_TAGS) { nameArrPtr = (CONST char**) ckalloc (numTags * sizeof(CONST char*)); } else { nameArrPtr = nameArray; } - /* - * We use tag names as keys in the hash table. We do this instead - * of using the actual tagPtr objects because we want one "sel" tag - * binding for all peer widgets, despite the fact that each has its - * own tagPtr object. + + /* + * We use tag names as keys in the hash table. We do this instead of using + * the actual tagPtr objects because we want one "sel" tag binding for all + * peer widgets, despite the fact that each has its own tagPtr object. */ + for (i = 0; i < numTags; i++) { TkTextTag *tagPtr = tagArrayPtr[i]; if (tagPtr != NULL) { nameArrPtr[i] = tagPtr->name; } else { - /* - * Tag has been deleted elsewhere, and therefore nulled - * out in this array. Tk_BindEvent is clever enough to - * cope with NULLs being thrown at it. + /* + * Tag has been deleted elsewhere, and therefore nulled out in + * this array. Tk_BindEvent is clever enough to cope with NULLs + * being thrown at it. */ + nameArrPtr[i] = NULL; } } - Tk_BindEvent(textPtr->sharedTextPtr->bindingTable, eventPtr, textPtr->tkwin, - numTags, (ClientData *) nameArrPtr); + Tk_BindEvent(textPtr->sharedTextPtr->bindingTable, eventPtr, + textPtr->tkwin, numTags, (ClientData *) nameArrPtr); if (numTags > NUM_BIND_TAGS) { ckfree((char*)nameArrPtr); } } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/unix/tkUnix.c b/unix/tkUnix.c index 0f93e93..677569e 100644 --- a/unix/tkUnix.c +++ b/unix/tkUnix.c @@ -10,7 +10,7 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkUnix.c,v 1.10 2005/06/02 10:08:07 rmax Exp $ + * RCS: @(#) $Id: tkUnix.c,v 1.11 2005/08/10 22:02:22 dkf Exp $ */ #include <tkInt.h> @@ -115,8 +115,8 @@ Tk_UpdatePointer(tkwin, x, y, state) * * TkpBuildRegionFromAlphaData -- * - * Set up a rectangle of the given region based on the supplied - * alpha data. + * Set up a rectangle of the given region based on the supplied alpha + * data. * * Results: * None @@ -130,14 +130,14 @@ Tk_UpdatePointer(tkwin, x, y, state) void TkpBuildRegionFromAlphaData(region, x, y, width, height, dataPtr, pixelStride, lineStride) - TkRegion region; - unsigned int x, y; /* Where in region to update. */ - unsigned int width, height; /* Size of rectangle to update. */ - unsigned char *dataPtr; /* Data to read from. */ - unsigned int pixelStride; /* num bytes from one piece of alpha - * data to the next in the line. */ - unsigned int lineStride; /* num bytes from one line of alpha - * data to the next line. */ + TkRegion region; /* Region to be updated. */ + unsigned int x, y; /* Where in region to update. */ + unsigned int width, height; /* Size of rectangle to update. */ + unsigned char *dataPtr; /* Data to read from. */ + unsigned int pixelStride; /* Num bytes from one piece of alpha data to + * the next in the line. */ + unsigned int lineStride; /* Num bytes from one line of alpha data to + * the next line. */ { unsigned char *lineDataPtr; unsigned int x1, y1, end; @@ -146,13 +146,20 @@ TkpBuildRegionFromAlphaData(region, x, y, width, height, dataPtr, for (y1 = 0; y1 < height; y1++) { lineDataPtr = dataPtr; for (x1 = 0; x1 < width; x1 = end) { - /* search for first non-transparent pixel */ + /* + * Search for first non-transparent pixel. + */ + while ((x1 < width) && !*lineDataPtr) { x1++; lineDataPtr += pixelStride; } end = x1; - /* search for first transparent pixel */ + + /* + * Search for first transparent pixel. + */ + while ((end < width) && *lineDataPtr) { end++; lineDataPtr += pixelStride; diff --git a/win/tkWinDialog.c b/win/tkWinDialog.c index f794174..4d56b69 100644 --- a/win/tkWinDialog.c +++ b/win/tkWinDialog.c @@ -5,29 +5,30 @@ * * Copyright (c) 1996-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinDialog.c,v 1.37 2004/12/20 10:34:21 vincentdarley Exp $ + * RCS: @(#) $Id: tkWinDialog.c,v 1.38 2005/08/10 22:02:22 dkf Exp $ * */ #include "tkWinInt.h" #include "tkFileFilter.h" -#include <commdlg.h> /* includes common dialog functionality */ +#include <commdlg.h> /* includes common dialog functionality */ #ifdef _MSC_VER # pragma comment (lib, "comdlg32.lib") #endif -#include <dlgs.h> /* includes common dialog template defines */ -#include <cderr.h> /* includes the common dialog error codes */ +#include <dlgs.h> /* includes common dialog template defines */ +#include <cderr.h> /* includes the common dialog error codes */ /* * This controls the use of the new style tk_chooseDirectory dialog. */ + #define USE_NEW_CHOOSEDIR 1 #ifdef USE_NEW_CHOOSEDIR -#include <shlobj.h> /* includes SHBrowseForFolder */ +#include <shlobj.h> /* includes SHBrowseForFolder */ #ifdef _MSC_VER # pragma comment (lib, "shell32.lib") #endif @@ -36,47 +37,50 @@ #ifndef BIF_EDITBOX #define BIF_EDITBOX 0x10 #endif + #ifndef BIF_VALIDATE #define BIF_VALIDATE 0x0020 #endif + #ifndef BFFM_VALIDATEFAILED #ifdef UNICODE #define BFFM_VALIDATEFAILED 4 #else #define BFFM_VALIDATEFAILED 3 #endif -#endif +#endif /* BFFM_VALIDATEFAILED */ /* - * The following structure is used by the new Tk_ChooseDirectoryObjCmd - * to pass data between it and its callback. Unqiue to Winodws platform. + * The following structure is used by the new Tk_ChooseDirectoryObjCmd to pass + * data between it and its callback. Unqiue to Winodws platform. */ + typedef struct ChooseDirData { - TCHAR utfInitDir[MAX_PATH]; /* Initial folder to use */ - TCHAR utfRetDir[MAX_PATH]; /* Returned folder to use */ + TCHAR utfInitDir[MAX_PATH]; /* Initial folder to use */ + TCHAR utfRetDir[MAX_PATH]; /* Returned folder to use */ Tcl_Interp *interp; - int mustExist; /* true if file must exist to return from - * callback */ + int mustExist; /* True if file must exist to return from + * callback */ } CHOOSEDIRDATA; #endif -typedef struct ThreadSpecificData { - int debugFlag; /* Flags whether we should output debugging - * information while displaying a builtin - * dialog. */ - Tcl_Interp *debugInterp; /* Interpreter to used for debugging. */ - UINT WM_LBSELCHANGED; /* Holds a registered windows event used for - * communicating between the Directory - * Chooser dialog and its hook proc. */ - HHOOK hMsgBoxHook; /* Hook proc for tk_messageBox and the */ - HICON hSmallIcon; /* icons used by a parent to be used in */ - HICON hBigIcon; /* the message box */ +typedef struct ThreadSpecificData { + int debugFlag; /* Flags whether we should output debugging + * information while displaying a builtin + * dialog. */ + Tcl_Interp *debugInterp; /* Interpreter to used for debugging. */ + UINT WM_LBSELCHANGED; /* Holds a registered windows event used for + * communicating between the Directory Chooser + * dialog and its hook proc. */ + HHOOK hMsgBoxHook; /* Hook proc for tk_messageBox and the */ + HICON hSmallIcon; /* icons used by a parent to be used in */ + HICON hBigIcon; /* the message box */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; /* - * The following structures are used by Tk_MessageBoxCmd() to parse - * arguments and return results. + * The following structures are used by Tk_MessageBoxCmd() to parse arguments + * and return results. */ static const TkStateMap iconMap[] = { @@ -86,10 +90,10 @@ static const TkStateMap iconMap[] = { {MB_ICONWARNING, "warning"}, {-1, NULL} }; - + static const TkStateMap typeMap[] = { {MB_ABORTRETRYIGNORE, "abortretryignore"}, - {MB_OK, "ok"}, + {MB_OK, "ok"}, {MB_OKCANCEL, "okcancel"}, {MB_RETRYCANCEL, "retrycancel"}, {MB_YESNO, "yesno"}, @@ -114,72 +118,73 @@ static const int buttonFlagMap[] = { static const struct {int type; int btnIds[3];} allowedTypes[] = { {MB_ABORTRETRYIGNORE, {IDABORT, IDRETRY, IDIGNORE}}, - {MB_OK, {IDOK, -1, -1 }}, - {MB_OKCANCEL, {IDOK, IDCANCEL, -1 }}, - {MB_RETRYCANCEL, {IDRETRY, IDCANCEL, -1 }}, - {MB_YESNO, {IDYES, IDNO, -1 }}, - {MB_YESNOCANCEL, {IDYES, IDNO, IDCANCEL}} + {MB_OK, {IDOK, -1, -1 }}, + {MB_OKCANCEL, {IDOK, IDCANCEL, -1 }}, + {MB_RETRYCANCEL, {IDRETRY, IDCANCEL, -1 }}, + {MB_YESNO, {IDYES, IDNO, -1 }}, + {MB_YESNOCANCEL, {IDYES, IDNO, IDCANCEL}} }; #define NUM_TYPES (sizeof(allowedTypes) / sizeof(allowedTypes[0])) /* - * The value of TK_MULTI_MAX_PATH dictactes how many files can - * be retrieved with tk_get*File -multiple 1. It must be allocated - * on the stack, so make it large enough but not too large. -- hobbs - * The data is stored as <dir>\0<file1>\0<file2>\0...<fileN>\0\0. - * MAX_PATH == 260 on Win2K/NT, so *40 is ~10K. + * The value of TK_MULTI_MAX_PATH dictactes how many files can be retrieved + * with tk_get*File -multiple 1. It must be allocated on the stack, so make it + * large enough but not too large. - hobbs + * + * The data is stored as <dir>\0<file1>\0<file2>\0...<fileN>\0\0. Since + * MAX_PATH == 260 on Win2K/NT, *40 is ~10Kbytes. */ #define TK_MULTI_MAX_PATH (MAX_PATH*40) /* * The following structure is used to pass information between the directory - * chooser procedure, Tk_ChooseDirectoryObjCmd(), and its dialog hook proc. + * chooser function, Tk_ChooseDirectoryObjCmd(), and its dialog hook proc. */ typedef struct ChooseDir { - Tcl_Interp *interp; /* Interp, used only if debug is turned on, + Tcl_Interp *interp; /* Interp, used only if debug is turned on, * for setting the "tk_dialog" variable. */ int lastCtrl; /* Used by hook proc to keep track of last - * control that had input focus, so when OK - * is pressed we know whether to browse a - * new directory or return. */ - int lastIdx; /* Last item that was selected in directory + * control that had input focus, so when OK is + * pressed we know whether to browse a new + * directory or return. */ + int lastIdx; /* Last item that was selected in directory * browser listbox. */ - TCHAR path[MAX_PATH]; /* On return from choose directory dialog, - * holds the selected path. Cannot return + TCHAR path[MAX_PATH]; /* On return from choose directory dialog, + * holds the selected path. Cannot return * selected path in ofnPtr->lpstrFile because - * the default dialog proc stores a '\0' in - * it, since, of course, no _file_ was + * the default dialog proc stores a '\0' in + * it, since, of course, no _file_ was * selected. */ OPENFILENAME *ofnPtr; /* pointer to the OFN structure */ } ChooseDir; /* - * Definitions of procedures used only in this file. + * Definitions of functions used only in this file. */ #ifdef USE_NEW_CHOOSEDIR static UINT APIENTRY ChooseDirectoryValidateProc(HWND hdlg, UINT uMsg, LPARAM wParam, LPARAM lParam); #else -static UINT APIENTRY ChooseDirectoryHookProc(HWND hdlg, UINT uMsg, +static UINT APIENTRY ChooseDirectoryHookProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam); #endif static UINT CALLBACK ColorDlgHookProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -static int GetFileNameA(ClientData clientData, - Tcl_Interp *interp, int objc, +static int GetFileNameA(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int isOpen); -static int GetFileNameW(ClientData clientData, - Tcl_Interp *interp, int objc, +static int GetFileNameW(ClientData clientData, + Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], int isOpen); -static int MakeFilter(Tcl_Interp *interp, Tcl_Obj *valuePtr, +static int MakeFilter(Tcl_Interp *interp, Tcl_Obj *valuePtr, Tcl_DString *dsPtr); -static UINT APIENTRY OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam, +static UINT APIENTRY OFNHookProc(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam); -static UINT APIENTRY OFNHookProcW(HWND hdlg, UINT uMsg, WPARAM wParam, +static UINT APIENTRY OFNHookProcW(HWND hdlg, UINT uMsg, WPARAM wParam, LPARAM lParam); static LRESULT CALLBACK MsgBoxCBTProc(int nCode, WPARAM wParam, LPARAM lParam); static void SetTkDialog(ClientData clientData); @@ -189,24 +194,23 @@ static void SetTkDialog(ClientData clientData); * * EatSpuriousMessageBugFix -- * - * In the file open/save dialog, double clicking on a list item - * causes the dialog box to close, but an unwanted WM_LBUTTONUP - * message is sent to the window underneath. If the window underneath - * happens to be a windows control (eg a button) then it will be - * activated by accident. - * - * This problem does not occur in dialog boxes, because windows - * must do some special processing to solve the problem. (separate - * message processing functions are used to cope with keyboard - * navigation of controls.) - * - * Here is one solution. After returning, we poll the message queue - * for 1/4s looking for WM_LBUTTON up messages. If we see one it's - * consumed. If we get a WM_LBUTTONDOWN message, then we exit early, - * since the user must be doing something new. This fix only works - * for the current application, so the problem will still occur if - * the open dialog happens to be over another applications button. - * However this is a fairly rare occurrance. + * In the file open/save dialog, double clicking on a list item causes + * the dialog box to close, but an unwanted WM_LBUTTONUP message is sent + * to the window underneath. If the window underneath happens to be a + * windows control (eg a button) then it will be activated by accident. + * + * This problem does not occur in dialog boxes, because windows must do + * some special processing to solve the problem. (separate message + * processing functions are used to cope with keyboard navigation of + * controls.) + * + * Here is one solution. After returning, we poll the message queue for + * 1/4s looking for WM_LBUTTON up messages. If we see one it's consumed. + * If we get a WM_LBUTTONDOWN message, then we exit early, since the user + * must be doing something new. This fix only works for the current + * application, so the problem will still occur if the open dialog + * happens to be over another applications button. However this is a + * fairly rare occurrance. * * Results: * None. @@ -217,15 +221,16 @@ static void SetTkDialog(ClientData clientData); *------------------------------------------------------------------------- */ -static void EatSpuriousMessageBugFix( void ) +static void EatSpuriousMessageBugFix(void) { MSG msg; DWORD nTime = GetTickCount() + 250; - while( GetTickCount() < nTime ) - { - if( PeekMessage(&msg,0,WM_LBUTTONDOWN,WM_LBUTTONDOWN,PM_NOREMOVE) ) + + while (GetTickCount() < nTime) { + if (PeekMessage(&msg, 0, WM_LBUTTONDOWN, WM_LBUTTONDOWN, PM_NOREMOVE)){ break; - PeekMessage(&msg,0,WM_LBUTTONUP,WM_LBUTTONUP,PM_REMOVE); + } + PeekMessage(&msg, 0, WM_LBUTTONUP, WM_LBUTTONUP, PM_REMOVE); } } @@ -235,8 +240,8 @@ static void EatSpuriousMessageBugFix( void ) * TkWinDialogDebug -- * * Function to turn on/off debugging support for common dialogs under - * windows. The variable "tk_debug" is set to the identifier of the - * dialog window when the modal dialog window pops up and it is safe to + * windows. The variable "tk_debug" is set to the identifier of the + * dialog window when the modal dialog window pops up and it is safe to * send messages to the dialog. * * Results: @@ -248,12 +253,12 @@ static void EatSpuriousMessageBugFix( void ) *------------------------------------------------------------------------- */ -void +void TkWinDialogDebug( int debug) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); tsdPtr->debugFlag = debug; } @@ -263,15 +268,14 @@ TkWinDialogDebug( * * Tk_ChooseColorObjCmd -- * - * This procedure implements the color dialog box for the Windows - * platform. See the user documentation for details on what it - * does. + * This function implements the color dialog box for the Windows + * platform. See the user documentation for details on what it does. * * Results: * See user documentation. * * Side effects: - * A dialog window is created the first time this procedure is called. + * A dialog window is created the first time this function is called. * This window is not destroyed and will be reused the next time the * application invokes the "tk_chooseColor" command. * @@ -302,11 +306,12 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv) result = TCL_OK; if (inited == 0) { /* - * dwCustColors stores the custom color which the user can - * modify. We store these colors in a static array so that the next - * time the color dialog pops up, the same set of custom colors - * remain in the dialog. + * dwCustColors stores the custom color which the user can modify. We + * store these colors in a static array so that the next time the + * color dialog pops up, the same set of custom colors remain in the + * dialog. */ + for (i = 0; i < 16; i++) { dwCustColors[i] = RGB(255-i * 10, i, i * 10); } @@ -318,7 +323,7 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv) parent = tkwin; chooseColor.lStructSize = sizeof(CHOOSECOLOR); - chooseColor.hwndOwner = NULL; + chooseColor.hwndOwner = NULL; chooseColor.hInstance = NULL; chooseColor.rgbResult = oldColor; chooseColor.lpCustColors = dwCustColors; @@ -340,36 +345,34 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv) return TCL_ERROR; } if (i + 1 == objc) { - string = Tcl_GetStringFromObj(optionPtr, NULL); - Tcl_AppendResult(interp, "value for \"", string, "\" missing", + string = Tcl_GetString(optionPtr); + Tcl_AppendResult(interp, "value for \"", string, "\" missing", (char *) NULL); return TCL_ERROR; } - string = Tcl_GetStringFromObj(valuePtr, NULL); + string = Tcl_GetString(valuePtr); switch ((enum options) index) { - case COLOR_INITIAL: { - XColor *colorPtr; + case COLOR_INITIAL: { + XColor *colorPtr; - colorPtr = Tk_GetColor(interp, tkwin, string); - if (colorPtr == NULL) { - return TCL_ERROR; - } - chooseColor.rgbResult = RGB(colorPtr->red / 0x100, - colorPtr->green / 0x100, colorPtr->blue / 0x100); - break; - } - case COLOR_PARENT: { - parent = Tk_NameToWindow(interp, string, tkwin); - if (parent == NULL) { - return TCL_ERROR; - } - break; + colorPtr = Tk_GetColor(interp, tkwin, string); + if (colorPtr == NULL) { + return TCL_ERROR; } - case COLOR_TITLE: { - chooseColor.lCustData = (LPARAM) string; - break; + chooseColor.rgbResult = RGB(colorPtr->red / 0x100, + colorPtr->green / 0x100, colorPtr->blue / 0x100); + break; + } + case COLOR_PARENT: + parent = Tk_NameToWindow(interp, string, tkwin); + if (parent == NULL) { + return TCL_ERROR; } + break; + case COLOR_TITLE: + chooseColor.lCustData = (LPARAM) string; + break; } } @@ -377,16 +380,17 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv) chooseColor.hwndOwner = NULL; hWnd = Tk_GetHWND(Tk_WindowId(parent)); chooseColor.hwndOwner = hWnd; - + oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); winCode = ChooseColor(&chooseColor); (void) Tcl_SetServiceMode(oldMode); /* - * Ensure that hWnd is enabled, because it can happen that we - * have updated the wrapper of the parent, which causes us to - * leave this child disabled (Windows loses sync). + * Ensure that hWnd is enabled, because it can happen that we have updated + * the wrapper of the parent, which causes us to leave this child disabled + * (Windows loses sync). */ + EnableWindow(hWnd, 1); /* @@ -407,10 +411,10 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv) char color[100]; sprintf(color, "#%02x%02x%02x", - GetRValue(chooseColor.rgbResult), - GetGValue(chooseColor.rgbResult), + GetRValue(chooseColor.rgbResult), + GetGValue(chooseColor.rgbResult), GetBValue(chooseColor.rgbResult)); - Tcl_AppendResult(interp, color, NULL); + Tcl_AppendResult(interp, color, NULL); oldColor = chooseColor.rgbResult; result = TCL_OK; } @@ -423,12 +427,12 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv) * * ColorDlgHookProc -- * - * Provides special handling of messages for the Color common dialog - * box. Used to set the title when the dialog first appears. + * Provides special handling of messages for the Color common dialog box. + * Used to set the title when the dialog first appears. * * Results: - * The return value is 0 if the default dialog box procedure should - * handle the message, non-zero otherwise. + * The return value is 0 if the default dialog box function should handle + * the message, non-zero otherwise. * * Side effects: * Changes the title of the dialog window. @@ -436,39 +440,38 @@ Tk_ChooseColorObjCmd(clientData, interp, objc, objv) *---------------------------------------------------------------------- */ -static UINT CALLBACK +static UINT CALLBACK ColorDlgHookProc(hDlg, uMsg, wParam, lParam) HWND hDlg; /* Handle to the color dialog. */ UINT uMsg; /* Type of message. */ WPARAM wParam; /* First message parameter. */ LPARAM lParam; /* Second message parameter. */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); switch (uMsg) { - case WM_INITDIALOG: { - const char *title; - CHOOSECOLOR *ccPtr; - Tcl_DString ds; + case WM_INITDIALOG: { + const char *title; + CHOOSECOLOR *ccPtr; + Tcl_DString ds; - /* - * Set the title string of the dialog. - */ + /* + * Set the title string of the dialog. + */ - ccPtr = (CHOOSECOLOR *) lParam; - title = (const char *) ccPtr->lCustData; - if ((title != NULL) && (title[0] != '\0')) { - (*tkWinProcs->setWindowText)(hDlg, - Tcl_WinUtfToTChar(title, -1, &ds)); - Tcl_DStringFree(&ds); - } - if (tsdPtr->debugFlag) { - tsdPtr->debugInterp = (Tcl_Interp *) ccPtr->lpTemplateName; - Tcl_DoWhenIdle(SetTkDialog, (ClientData) hDlg); - } - return TRUE; + ccPtr = (CHOOSECOLOR *) lParam; + title = (const char *) ccPtr->lCustData; + if ((title != NULL) && (title[0] != '\0')) { + (*tkWinProcs->setWindowText)(hDlg,Tcl_WinUtfToTChar(title,-1,&ds)); + Tcl_DStringFree(&ds); + } + if (tsdPtr->debugFlag) { + tsdPtr->debugInterp = (Tcl_Interp *) ccPtr->lpTemplateName; + Tcl_DoWhenIdle(SetTkDialog, (ClientData) hDlg); } + return TRUE; + } } return FALSE; } @@ -478,15 +481,14 @@ ColorDlgHookProc(hDlg, uMsg, wParam, lParam) * * Tk_GetOpenFileCmd -- * - * This procedure implements the "open file" dialog box for the - * Windows platform. See the user documentation for details on what - * it does. + * This function implements the "open file" dialog box for the Windows + * platform. See the user documentation for details on what it does. * * Results: * See user documentation. * * Side effects: - * A dialog window is created the first this procedure is called. + * A dialog window is created the first this function is called. * *---------------------------------------------------------------------- */ @@ -552,14 +554,14 @@ Tk_GetSaveFileObjCmd(clientData, interp, objc, objv) *---------------------------------------------------------------------- */ -static int +static int GetFileNameW(clientData, interp, objc, objv, open) ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ - int open; /* 1 to call GetOpenFileName(), 0 to - * call GetSaveFileName(). */ + int open; /* 1 to call GetOpenFileName(), 0 to call + * GetSaveFileName(). */ { OPENFILENAMEW ofn; WCHAR file[TK_MULTI_MAX_PATH]; @@ -570,8 +572,8 @@ GetFileNameW(clientData, interp, objc, objv, open) Tcl_DString utfFilterString, utfDirString; Tcl_DString extString, filterString, dirString, titleString; Tcl_Encoding unicodeEncoding = TkWinGetUnicodeEncoding(); - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); static CONST char *saveOptionStrings[] = { "-defaultextension", "-filetypes", "-initialdir", "-initialfile", "-parent", "-title", NULL @@ -619,81 +621,76 @@ GetFileNameW(clientData, interp, objc, objv, open) "option", 0, &index) != TCL_OK) { goto end; } + /* * We want to maximize code sharing between the open and save file * dialog implementations; in particular, the switch statement below. * We use different sets of option strings from the GetIndexFromObj - * call above, but a single enumeration for both. The save file - * dialog doesn't support -multiple, but it falls in the middle of - * the enumeration. Ultimately, this means that when the index found - * by GetIndexFromObj is >= FILE_MULTIPLE, when doing a save file - * dialog, we have to increment the index, so that it matches the - * open file dialog enumeration. + * call above, but a single enumeration for both. The save file dialog + * doesn't support -multiple, but it falls in the middle of the + * enumeration. Ultimately, this means that when the index found by + * GetIndexFromObj is >= FILE_MULTIPLE, when doing a save file dialog, + * we have to increment the index, so that it matches the open file + * dialog enumeration. */ + if (!open && index >= FILE_MULTIPLE) { index++; } if (i + 1 == objc) { - string = Tcl_GetStringFromObj(optionPtr, NULL); - Tcl_AppendResult(interp, "value for \"", string, "\" missing", + string = Tcl_GetString(optionPtr); + Tcl_AppendResult(interp, "value for \"", string, "\" missing", (char *) NULL); goto end; } - string = Tcl_GetStringFromObj(valuePtr, NULL); + string = Tcl_GetString(valuePtr); switch ((enum options) index) { - case FILE_DEFAULT: { - if (string[0] == '.') { - string++; - } - extension = string; - break; + case FILE_DEFAULT: + if (string[0] == '.') { + string++; } - case FILE_TYPES: { - Tcl_DStringFree(&utfFilterString); - if (MakeFilter(interp, valuePtr, &utfFilterString) != TCL_OK) { - goto end; - } - filter = Tcl_DStringValue(&utfFilterString); - break; + extension = string; + break; + case FILE_TYPES: + Tcl_DStringFree(&utfFilterString); + if (MakeFilter(interp, valuePtr, &utfFilterString) != TCL_OK) { + goto end; } - case FILE_INITDIR: { - Tcl_DStringFree(&utfDirString); - if (Tcl_TranslateFileName(interp, string, - &utfDirString) == NULL) { - goto end; - } - break; + filter = Tcl_DStringValue(&utfFilterString); + break; + case FILE_INITDIR: + Tcl_DStringFree(&utfDirString); + if (Tcl_TranslateFileName(interp, string, + &utfDirString) == NULL) { + goto end; } - case FILE_INITFILE: { - Tcl_DString ds; + break; + case FILE_INITFILE: { + Tcl_DString ds; - if (Tcl_TranslateFileName(interp, string, &ds) == NULL) { - goto end; - } - Tcl_UtfToExternal(NULL, unicodeEncoding, Tcl_DStringValue(&ds), - Tcl_DStringLength(&ds), 0, NULL, (char *) file, - sizeof(file), NULL, NULL, NULL); - break; + if (Tcl_TranslateFileName(interp, string, &ds) == NULL) { + goto end; } - case FILE_MULTIPLE: { - if (Tcl_GetBooleanFromObj(interp, valuePtr, - &multi) != TCL_OK) { - return TCL_ERROR; - } - break; - } - case FILE_PARENT: { - tkwin = Tk_NameToWindow(interp, string, tkwin); - if (tkwin == NULL) { - goto end; - } - break; + Tcl_UtfToExternal(NULL, unicodeEncoding, Tcl_DStringValue(&ds), + Tcl_DStringLength(&ds), 0, NULL, (char *) file, + sizeof(file), NULL, NULL, NULL); + break; + } + case FILE_MULTIPLE: + if (Tcl_GetBooleanFromObj(interp, valuePtr, &multi) != TCL_OK) { + return TCL_ERROR; } - case FILE_TITLE: { - title = string; - break; + break; + case FILE_PARENT: + tkwin = Tk_NameToWindow(interp, string, tkwin); + if (tkwin == NULL) { + goto end; } + break; + case FILE_TITLE: + title = string; + break; } } @@ -707,21 +704,19 @@ GetFileNameW(clientData, interp, objc, objv, open) hWnd = Tk_GetHWND(Tk_WindowId(tkwin)); ZeroMemory(&ofn, sizeof(OPENFILENAMEW)); - ofn.lStructSize = sizeof(OPENFILENAMEW); - ofn.hwndOwner = hWnd; + ofn.lStructSize = sizeof(OPENFILENAMEW); + ofn.hwndOwner = hWnd; #ifdef _WIN64 - ofn.hInstance = (HINSTANCE) GetWindowLongPtr(ofn.hwndOwner, - GWLP_HINSTANCE); + ofn.hInstance = (HINSTANCE) GetWindowLongPtr(ofn.hwndOwner,GWLP_HINSTANCE); #else - ofn.hInstance = (HINSTANCE) GetWindowLong(ofn.hwndOwner, - GWL_HINSTANCE); + ofn.hInstance = (HINSTANCE) GetWindowLong(ofn.hwndOwner, GWL_HINSTANCE); #endif - ofn.lpstrFile = (WCHAR *) file; - ofn.nMaxFile = TK_MULTI_MAX_PATH; - ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST - | OFN_NOCHANGEDIR | OFN_EXPLORER; - ofn.lpfnHook = (LPOFNHOOKPROC) OFNHookProcW; - ofn.lCustData = (LPARAM) interp; + ofn.lpstrFile = (WCHAR *) file; + ofn.nMaxFile = TK_MULTI_MAX_PATH; + ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR + | OFN_EXPLORER; + ofn.lpfnHook = (LPOFNHOOKPROC) OFNHookProcW; + ofn.lCustData = (LPARAM) interp; if (open != 0) { ofn.Flags |= OFN_FILEMUSTEXIST; @@ -753,10 +748,10 @@ GetFileNameW(clientData, interp, objc, objv, open) Tcl_DStringLength(&utfDirString), &dirString); } else { /* - * NT 5.0 changed the meaning of lpstrInitialDir, so we have - * to ensure that we set the [pwd] if the user didn't specify - * anything else. + * NT 5.0 changed the meaning of lpstrInitialDir, so we have to ensure + * that we set the [pwd] if the user didn't specify anything else. */ + Tcl_DString cwd; Tcl_DStringFree(&utfDirString); @@ -791,10 +786,11 @@ GetFileNameW(clientData, interp, objc, objv, open) EatSpuriousMessageBugFix(); /* - * Ensure that hWnd is enabled, because it can happen that we - * have updated the wrapper of the parent, which causes us to - * leave this child disabled (Windows loses sync). + * Ensure that hWnd is enabled, because it can happen that we have updated + * the wrapper of the parent, which causes us to leave this child disabled + * (Windows loses sync). */ + EnableWindow(hWnd, 1); /* @@ -810,12 +806,12 @@ GetFileNameW(clientData, interp, objc, objv, open) if (winCode != 0) { if (ofn.Flags & OFN_ALLOWMULTISELECT) { - /* - * The result in custData->szFile contains many items, - * separated with null characters. It is terminated with - * two nulls in a row. The first element is the directory - * path. + /* + * The result in custData->szFile contains many items, separated + * with null characters. It is terminated with two nulls in a row. + * The first element is the directory path. */ + char *dir; char *p; char *file; @@ -831,13 +827,17 @@ GetFileNameW(clientData, interp, objc, objv, open) files = ofn.lpstrFile; Tcl_ExternalToUtfDString(unicodeEncoding, (char *) files, -1, &ds); - /* Get directory */ + /* + * Get directory. + */ + dir = Tcl_DStringValue(&ds); for (p = dir; p && *p; p++) { /* * Change the pathname to the Tcl "normalized" pathname, where * back slashes are used instead of forward slashes */ + if (*p == '\\') { *p = '/'; } @@ -868,10 +868,12 @@ GetFileNameW(clientData, interp, objc, objv, open) Tcl_DStringFree(&filename); } } + if (count == 0) { /* * Only one file was returned. */ + Tcl_ListObjAppendElement(interp, returnList, Tcl_NewStringObj(dir, -1)); } @@ -881,7 +883,7 @@ GetFileNameW(clientData, interp, objc, objv, open) } else { char *p; Tcl_DString ds; - + Tcl_ExternalToUtfDString(unicodeEncoding, (char *) ofn.lpstrFile, -1, &ds); for (p = Tcl_DStringValue(&ds); *p != '\0'; p++) { @@ -902,25 +904,26 @@ GetFileNameW(clientData, interp, objc, objv, open) * Use the CommDlgExtendedError() function to retrieve the error code. * This function can return one of about two dozen codes; most of * these indicate some sort of gross system failure (insufficient - * memory, bad window handles, etc.). Most of the error codes will be + * memory, bad window handles, etc.). Most of the error codes will be * ignored; as we find we want more specific error messages for * particular errors, we can extend the code as needed. * - * We could also check for FNERR_BUFFERTOOSMALL, but we can't - * really do anything about it when it happens. + * We could also check for FNERR_BUFFERTOOSMALL, but we can't really + * do anything about it when it happens. */ if (CommDlgExtendedError() == FNERR_INVALIDFILENAME) { char *p; Tcl_DString ds; - + Tcl_ExternalToUtfDString(unicodeEncoding, (char *) ofn.lpstrFile, -1, &ds); for (p = Tcl_DStringValue(&ds); *p != '\0'; p++) { /* - * Change the pathname to the Tcl "normalized" pathname, - * where back slashes are used instead of forward slashes + * Change the pathname to the Tcl "normalized" pathname, where + * back slashes are used instead of forward slashes */ + if (*p == '\\') { *p = '/'; } @@ -932,7 +935,7 @@ GetFileNameW(clientData, interp, objc, objv, open) result = TCL_OK; } } - + if (ofn.lpstrTitle != NULL) { Tcl_DStringFree(&titleString); } @@ -944,7 +947,7 @@ GetFileNameW(clientData, interp, objc, objv, open) Tcl_DStringFree(&extString); } - end: + end: Tcl_DStringFree(&utfDirString); Tcl_DStringFree(&utfFilterString); @@ -956,9 +959,8 @@ GetFileNameW(clientData, interp, objc, objv, open) * * OFNHookProcW -- * - * Hook procedure called only if debugging is turned on. Sets - * the "tk_dialog" variable when the dialog is ready to receive - * messages. + * Hook function called only if debugging is turned on. Sets the + * "tk_dialog" variable when the dialog is ready to receive messages. * * Results: * Returns 0 to allow default processing of messages to occur. @@ -969,15 +971,15 @@ GetFileNameW(clientData, interp, objc, objv, open) *------------------------------------------------------------------------- */ -static UINT APIENTRY +static UINT APIENTRY OFNHookProcW( - HWND hdlg, // handle to child dialog window - UINT uMsg, // message identifier - WPARAM wParam, // message parameter - LPARAM lParam) // message parameter + HWND hdlg, /* Handle to child dialog window. */ + UINT uMsg, /* Message identifier */ + WPARAM wParam, /* Message parameter */ + LPARAM lParam) /* Message parameter */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); OPENFILENAMEW *ofnPtr; if (uMsg == WM_INITDIALOG) { @@ -988,16 +990,15 @@ OFNHookProcW( #endif } else if (uMsg == WM_WINDOWPOSCHANGED) { /* - * This message is delivered at the right time to enable Tk - * to set the debug information. Unhooks itself so it - * won't set the debug information every time it gets a - * WM_WINDOWPOSCHANGED message. + * This message is delivered at the right time to enable Tk to set the + * debug information. Unhooks itself so it won't set the debug + * information every time it gets a WM_WINDOWPOSCHANGED message. */ #ifdef _WIN64 - ofnPtr = (OPENFILENAMEW *) GetWindowLongPtr(hdlg, GWLP_USERDATA); + ofnPtr = (OPENFILENAMEW *) GetWindowLongPtr(hdlg, GWLP_USERDATA); #else - ofnPtr = (OPENFILENAMEW *) GetWindowLong(hdlg, GWL_USERDATA); + ofnPtr = (OPENFILENAMEW *) GetWindowLong(hdlg, GWL_USERDATA); #endif if (ofnPtr != NULL) { hdlg = GetParent(hdlg); @@ -1029,14 +1030,14 @@ OFNHookProcW( *---------------------------------------------------------------------- */ -static int +static int GetFileNameA(clientData, interp, objc, objv, open) ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ - int open; /* 1 to call GetOpenFileName(), 0 to - * call GetSaveFileName(). */ + int open; /* 1 to call GetOpenFileName(), 0 to call + * GetSaveFileName(). */ { OPENFILENAME ofn; TCHAR file[TK_MULTI_MAX_PATH], savePath[MAX_PATH]; @@ -1046,8 +1047,8 @@ GetFileNameA(clientData, interp, objc, objv, open) HWND hWnd; Tcl_DString utfFilterString, utfDirString; Tcl_DString extString, filterString, dirString, titleString; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); static CONST char *saveOptionStrings[] = { "-defaultextension", "-filetypes", "-initialdir", "-initialfile", "-parent", "-title", NULL @@ -1095,81 +1096,75 @@ GetFileNameA(clientData, interp, objc, objv, open) "option", 0, &index) != TCL_OK) { goto end; } + /* * We want to maximize code sharing between the open and save file * dialog implementations; in particular, the switch statement below. * We use different sets of option strings from the GetIndexFromObj - * call above, but a single enumeration for both. The save file - * dialog doesn't support -multiple, but it falls in the middle of - * the enumeration. Ultimately, this means that when the index found - * by GetIndexFromObj is >= FILE_MULTIPLE, when doing a save file - * dialog, we have to increment the index, so that it matches the - * open file dialog enumeration. + * call above, but a single enumeration for both. The save file dialog + * doesn't support -multiple, but it falls in the middle of the + * enumeration. Ultimately, this means that when the index found by + * GetIndexFromObj is >= FILE_MULTIPLE, when doing a save file dialog, + * we have to increment the index, so that it matches the open file + * dialog enumeration. */ + if (!open && index >= FILE_MULTIPLE) { index++; } if (i + 1 == objc) { - string = Tcl_GetStringFromObj(optionPtr, NULL); - Tcl_AppendResult(interp, "value for \"", string, "\" missing", + string = Tcl_GetString(optionPtr); + Tcl_AppendResult(interp, "value for \"", string, "\" missing", (char *) NULL); goto end; } - string = Tcl_GetStringFromObj(valuePtr, NULL); + string = Tcl_GetString(valuePtr); switch ((enum options) index) { - case FILE_DEFAULT: { - if (string[0] == '.') { - string++; - } - extension = string; - break; + case FILE_DEFAULT: + if (string[0] == '.') { + string++; } - case FILE_TYPES: { - Tcl_DStringFree(&utfFilterString); - if (MakeFilter(interp, valuePtr, &utfFilterString) != TCL_OK) { - goto end; - } - filter = Tcl_DStringValue(&utfFilterString); - break; + extension = string; + break; + case FILE_TYPES: + Tcl_DStringFree(&utfFilterString); + if (MakeFilter(interp, valuePtr, &utfFilterString) != TCL_OK) { + goto end; } - case FILE_INITDIR: { - Tcl_DStringFree(&utfDirString); - if (Tcl_TranslateFileName(interp, string, - &utfDirString) == NULL) { - goto end; - } - break; + filter = Tcl_DStringValue(&utfFilterString); + break; + case FILE_INITDIR: + Tcl_DStringFree(&utfDirString); + if (Tcl_TranslateFileName(interp, string, &utfDirString) == NULL) { + goto end; } - case FILE_INITFILE: { - Tcl_DString ds; + break; + case FILE_INITFILE: { + Tcl_DString ds; - if (Tcl_TranslateFileName(interp, string, &ds) == NULL) { - goto end; - } - Tcl_UtfToExternal(NULL, NULL, Tcl_DStringValue(&ds), - Tcl_DStringLength(&ds), 0, NULL, (char *) file, - sizeof(file), NULL, NULL, NULL); - break; + if (Tcl_TranslateFileName(interp, string, &ds) == NULL) { + goto end; } - case FILE_MULTIPLE: { - if (Tcl_GetBooleanFromObj(interp, valuePtr, - &multi) != TCL_OK) { - return TCL_ERROR; - } - break; - } - case FILE_PARENT: { - tkwin = Tk_NameToWindow(interp, string, tkwin); - if (tkwin == NULL) { - goto end; - } - break; + Tcl_UtfToExternal(NULL, NULL, Tcl_DStringValue(&ds), + Tcl_DStringLength(&ds), 0, NULL, (char *) file, + sizeof(file), NULL, NULL, NULL); + break; + } + case FILE_MULTIPLE: + if (Tcl_GetBooleanFromObj(interp, valuePtr, &multi) != TCL_OK) { + return TCL_ERROR; } - case FILE_TITLE: { - title = string; - break; + break; + case FILE_PARENT: + tkwin = Tk_NameToWindow(interp, string, tkwin); + if (tkwin == NULL) { + goto end; } + break; + case FILE_TITLE: + title = string; + break; } } @@ -1182,33 +1177,31 @@ GetFileNameA(clientData, interp, objc, objv, open) Tk_MakeWindowExist(tkwin); hWnd = Tk_GetHWND(Tk_WindowId(tkwin)); - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hWnd; + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hWnd; #ifdef _WIN64 - ofn.hInstance = (HINSTANCE) GetWindowLongPtr(ofn.hwndOwner, - GWLP_HINSTANCE); + ofn.hInstance = (HINSTANCE) GetWindowLongPtr(ofn.hwndOwner,GWLP_HINSTANCE); #else - ofn.hInstance = (HINSTANCE) GetWindowLong(ofn.hwndOwner, - GWL_HINSTANCE); + ofn.hInstance = (HINSTANCE) GetWindowLong(ofn.hwndOwner, GWL_HINSTANCE); #endif - ofn.lpstrFilter = NULL; - ofn.lpstrCustomFilter = NULL; - ofn.nMaxCustFilter = 0; - ofn.nFilterIndex = 0; - ofn.lpstrFile = (LPTSTR) file; - ofn.nMaxFile = TK_MULTI_MAX_PATH; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.lpstrTitle = NULL; - ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST - | OFN_NOCHANGEDIR | OFN_EXPLORER; - ofn.nFileOffset = 0; - ofn.nFileExtension = 0; - ofn.lpstrDefExt = NULL; - ofn.lpfnHook = (LPOFNHOOKPROC) OFNHookProc; - ofn.lCustData = (LPARAM) interp; - ofn.lpTemplateName = NULL; + ofn.lpstrFilter = NULL; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = 0; + ofn.lpstrFile = (LPTSTR) file; + ofn.nMaxFile = TK_MULTI_MAX_PATH; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrTitle = NULL; + ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_NOCHANGEDIR + | OFN_EXPLORER; + ofn.nFileOffset = 0; + ofn.nFileExtension = 0; + ofn.lpstrDefExt = NULL; + ofn.lpfnHook = (LPOFNHOOKPROC) OFNHookProc; + ofn.lCustData = (LPARAM) interp; + ofn.lpTemplateName = NULL; if (open != 0) { ofn.Flags |= OFN_FILEMUSTEXIST; @@ -1237,10 +1230,10 @@ GetFileNameA(clientData, interp, objc, objv, open) Tcl_DStringLength(&utfDirString), &dirString); } else { /* - * NT 5.0 changed the meaning of lpstrInitialDir, so we have - * to ensure that we set the [pwd] if the user didn't specify - * anything else. + * NT 5.0 changed the meaning of lpstrInitialDir, so we have to ensure + * that we set the [pwd] if the user didn't specify anything else. */ + Tcl_DString cwd; Tcl_DStringFree(&utfDirString); @@ -1277,10 +1270,11 @@ GetFileNameA(clientData, interp, objc, objv, open) SetCurrentDirectory(savePath); /* - * Ensure that hWnd is enabled, because it can happen that we - * have updated the wrapper of the parent, which causes us to - * leave this child disabled (Windows loses sync). + * Ensure that hWnd is enabled, because it can happen that we have updated + * the wrapper of the parent, which causes us to leave this child disabled + * (Windows loses sync). */ + EnableWindow(hWnd, 1); /* @@ -1296,12 +1290,12 @@ GetFileNameA(clientData, interp, objc, objv, open) if (winCode != 0) { if (ofn.Flags & OFN_ALLOWMULTISELECT) { - /* - * The result in custData->szFile contains many items, - * separated with null characters. It is terminated with - * two nulls in a row. The first element is the directory - * path. + /* + * The result in custData->szFile contains many items, separated + * with null characters. It is terminated with two nulls in a row. + * The first element is the directory path. */ + char *dir; char *p; char *file; @@ -1317,13 +1311,17 @@ GetFileNameA(clientData, interp, objc, objv, open) files = ofn.lpstrFile; Tcl_ExternalToUtfDString(NULL, (char *) files, -1, &ds); - /* Get directory */ + /* + * Get directory. + */ + dir = Tcl_DStringValue(&ds); for (p = dir; p && *p; p++) { /* * Change the pathname to the Tcl "normalized" pathname, where * back slashes are used instead of forward slashes */ + if (*p == '\\') { *p = '/'; } @@ -1358,6 +1356,7 @@ GetFileNameA(clientData, interp, objc, objv, open) /* * Only one file was returned. */ + Tcl_ListObjAppendElement(interp, returnList, Tcl_NewStringObj(dir, -1)); } @@ -1374,6 +1373,7 @@ GetFileNameA(clientData, interp, objc, objv, open) * Change the pathname to the Tcl "normalized" pathname, where * back slashes are used instead of forward slashes */ + if (*p == '\\') { *p = '/'; } @@ -1387,13 +1387,14 @@ GetFileNameA(clientData, interp, objc, objv, open) * Use the CommDlgExtendedError() function to retrieve the error code. * This function can return one of about two dozen codes; most of * these indicate some sort of gross system failure (insufficient - * memory, bad window handles, etc.). Most of the error codes will be - * ignored;; as we find we want specific error messages for particular + * memory, bad window handles, etc.) Most of the error codes will be + * ignored; as we find we want specific error messages for particular * errors, we can extend the code as needed. * - * We could also check for FNERR_BUFFERTOOSMALL, but we can't - * really do anything about it when it happens. + * We could also check for FNERR_BUFFERTOOSMALL, but we can't really + * do anything about it when it happens. */ + if (CommDlgExtendedError() == FNERR_INVALIDFILENAME) { char *p; Tcl_DString ds; @@ -1401,9 +1402,10 @@ GetFileNameA(clientData, interp, objc, objv, open) Tcl_ExternalToUtfDString(NULL, (char *) ofn.lpstrFile, -1, &ds); for (p = Tcl_DStringValue(&ds); *p != '\0'; p++) { /* - * Change the pathname to the Tcl "normalized" pathname, - * where back slashes are used instead of forward slashes + * Change the pathname to the Tcl "normalized" pathname, where + * back slashes are used instead of forward slashes */ + if (*p == '\\') { *p = '/'; } @@ -1427,7 +1429,7 @@ GetFileNameA(clientData, interp, objc, objv, open) Tcl_DStringFree(&extString); } - end: + end: Tcl_DStringFree(&utfDirString); Tcl_DStringFree(&utfFilterString); @@ -1439,9 +1441,8 @@ GetFileNameA(clientData, interp, objc, objv, open) * * OFNHookProc -- * - * Hook procedure called only if debugging is turned on. Sets - * the "tk_dialog" variable when the dialog is ready to receive - * messages. + * Hook function called only if debugging is turned on. Sets the + * "tk_dialog" variable when the dialog is ready to receive messages. * * Results: * Returns 0 to allow default processing of messages to occur. @@ -1452,15 +1453,15 @@ GetFileNameA(clientData, interp, objc, objv, open) *------------------------------------------------------------------------- */ -static UINT APIENTRY +static UINT APIENTRY OFNHookProc( - HWND hdlg, // handle to child dialog window - UINT uMsg, // message identifier - WPARAM wParam, // message parameter - LPARAM lParam) // message parameter + HWND hdlg, /* handle to child dialog window */ + UINT uMsg, /* message identifier */ + WPARAM wParam, /* message parameter */ + LPARAM lParam) /* message parameter */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); OPENFILENAME *ofnPtr; if (uMsg == WM_INITDIALOG) { @@ -1471,17 +1472,16 @@ OFNHookProc( #endif } else if (uMsg == WM_WINDOWPOSCHANGED) { /* - * This message is delivered at the right time to both - * old-style and explorer-style hook procs to enable Tk - * to set the debug information. Unhooks itself so it - * won't set the debug information every time it gets a - * WM_WINDOWPOSCHANGED message. + * This message is delivered at the right time to both old-style and + * explorer-style hook procs to enable Tk to set the debug + * information. Unhooks itself so it won't set the debug information + * every time it gets a WM_WINDOWPOSCHANGED message. */ #ifdef _WIN64 - ofnPtr = (OPENFILENAME *) GetWindowLongPtr(hdlg, GWLP_USERDATA); + ofnPtr = (OPENFILENAME *) GetWindowLongPtr(hdlg, GWLP_USERDATA); #else - ofnPtr = (OPENFILENAME *) GetWindowLong(hdlg, GWL_USERDATA); + ofnPtr = (OPENFILENAME *) GetWindowLong(hdlg, GWL_USERDATA); #endif if (ofnPtr != NULL) { if (ofnPtr->Flags & OFN_EXPLORER) { @@ -1505,7 +1505,7 @@ OFNHookProc( * MakeFilter -- * * Allocate a buffer to store the filters in a format understood by - * Windows + * Windows. * * Results: * A standard TCL return value. @@ -1515,8 +1515,9 @@ OFNHookProc( * *---------------------------------------------------------------------- */ -static int -MakeFilter(interp, valuePtr, dsPtr) + +static int +MakeFilter(interp, valuePtr, dsPtr) Tcl_Interp *interp; /* Current interpreter. */ Tcl_Obj *valuePtr; /* Value of the -filetypes option */ Tcl_DString *dsPtr; /* Filled with windows filter string. */ @@ -1553,15 +1554,17 @@ MakeFilter(interp, valuePtr, dsPtr) } else { int len; + if (valuePtr == NULL) { len = 0; } else { CONST char* string = Tcl_GetStringFromObj(valuePtr, &len); } - - /* We format the filetype into a string understood by Windows: - * {"Text Documents" {.doc .txt} {TEXT}} becomes - * "Text Documents (*.doc,*.txt)\0*.doc;*.txt\0" + + /* + * We format the filetype into a string understood by Windows: {"Text + * Documents" {.doc .txt} {TEXT}} becomes "Text Documents + * (*.doc,*.txt)\0*.doc;*.txt\0" * * See the Windows OPENFILENAME manual page for details on the filter * string format. @@ -1571,16 +1574,18 @@ MakeFilter(interp, valuePtr, dsPtr) * Since we may only add asterisks (*) to the filter, we need at most * twice the size of the string to format the filter */ + filterStr = ckalloc((unsigned int) len * 3); for (filterPtr = flist.filters, p = filterStr; filterPtr; - filterPtr = filterPtr->next) { + filterPtr = filterPtr->next) { char *sep; FileFilterClause *clausePtr; /* - * First, put in the name of the file type + * First, put in the name of the file type. */ + strcpy(p, filterPtr->name); p+= strlen(filterPtr->name); *p++ = ' '; @@ -1588,24 +1593,24 @@ MakeFilter(interp, valuePtr, dsPtr) for (pass = 1; pass <= 2; pass++) { /* - * In the first pass, we format the extensions in the - * name field. In the second pass, we format the extensions in - * the filter pattern field + * In the first pass, we format the extensions in the name + * field. In the second pass, we format the extensions in the + * filter pattern field */ + sep = ""; for (clausePtr=filterPtr->clauses;clausePtr; - clausePtr=clausePtr->next) { + clausePtr=clausePtr->next) { GlobPattern *globPtr; - for (globPtr=clausePtr->patterns; globPtr; globPtr=globPtr->next) { strcpy(p, sep); - p+= strlen(sep); + p += strlen(sep); strcpy(p, globPtr->pattern); - p+= strlen(globPtr->pattern); + p += strlen(globPtr->pattern); - if (pass==1) { + if (pass == 1) { sep = ","; } else { sep = ";"; @@ -1613,11 +1618,9 @@ MakeFilter(interp, valuePtr, dsPtr) } } if (pass == 1) { - if (pass == 1) { - *p ++ = ')'; - } + *p ++ = ')'; } - *p ++ = '\0'; + *p++ = '\0'; } } @@ -1625,6 +1628,7 @@ MakeFilter(interp, valuePtr, dsPtr) * Windows requires the filter string to be ended by two NULL * characters. */ + *p++ = '\0'; *p = '\0'; } @@ -1642,77 +1646,78 @@ MakeFilter(interp, valuePtr, dsPtr) * * Tk_ChooseDirectoryObjCmd -- * - * This procedure implements the "tk_chooseDirectory" dialog box - * for the Windows platform. See the user documentation for details - * on what it does. Uses the newer SHBrowseForFolder explorer type - * interface. + * This function implements the "tk_chooseDirectory" dialog box for the + * Windows platform. See the user documentation for details on what it + * does. Uses the newer SHBrowseForFolder explorer type interface. * * Results: - * See user documentation. + * See user documentation. * * Side effects: - * A modal dialog window is created. Tcl_SetServiceMode() is - * called to allow background events to be processed + * A modal dialog window is created. Tcl_SetServiceMode() is called to + * allow background events to be processed * *---------------------------------------------------------------------- - -The procedure tk_chooseDirectory pops up a dialog box for the user to -select a directory. The following option-value pairs are possible as -command line arguments: - --initialdir dirname - -Specifies that the directories in directory should be displayed when the -dialog pops up. If this parameter is not specified, then the directories -in the current working directory are displayed. If the parameter specifies -a relative path, the return value will convert the relative path to an -absolute path. This option may not always work on the Macintosh. This is -not a bug. Rather, the General Controls control panel on the Mac allows -the end user to override the application default directory. - --parent window - -Makes window the logical parent of the dialog. The dialog is displayed on -top of its parent window. - --title titleString - -Specifies a string to display as the title of the dialog box. If this -option is not specified, then a default title will be displayed. - --mustexist boolean - -Specifies whether the user may specify non-existant directories. If this -parameter is true, then the user may only select directories that already -exist. The default value is false. - -New Behaviour: - -- If mustexist = 0 and a user entered folder does not exist, a prompt will - pop-up asking if the user wants another chance to change it. The old - dialog just returned the bogus entry. On mustexist = 1, the entries MUST - exist before exiting the box with OK. - - Bugs: - -- If valid abs directory name is entered into the entry box and Enter - pressed, the box will close returning the name. This is inconsistent when - entering relative names or names with forward slashes, which are - invalidated then corrected in the callback. After correction, the box is - held open to allow further modification by the user. - -- Not sure how to implement localization of message prompts. - -- -title is really -message. -ToDo: -- Fix bugs. -- test to see what platforms this really works on. May require v4.71 - of shell32.dll everywhere (what is standard?). * + * The function tk_chooseDirectory pops up a dialog box for the user to select + * a directory. The following option-value pairs are possible as command line + * arguments: + * + * -initialdir dirname + * + * Specifies that the directories in directory should be displayed when the + * dialog pops up. If this parameter is not specified, then the directories in + * the current working directory are displayed. If the parameter specifies a + * relative path, the return value will convert the relative path to an + * absolute path. This option may not always work on the Macintosh. This is + * not a bug. Rather, the General Controls control panel on the Mac allows the + * end user to override the application default directory. + * + * -parent window + * + * Makes window the logical parent of the dialog. The dialog is displayed on + * top of its parent window. + * + * -title titleString + * + * Specifies a string to display as the title of the dialog box. If this + * option is not specified, then a default title will be displayed. + * + * -mustexist boolean + * + * Specifies whether the user may specify non-existant directories. If this + * parameter is true, then the user may only select directories that already + * exist. The default value is false. + * + * New Behaviour: + * + * - If mustexist = 0 and a user entered folder does not exist, a prompt will + * pop-up asking if the user wants another chance to change it. The old + * dialog just returned the bogus entry. On mustexist = 1, the entries MUST + * exist before exiting the box with OK. + * + * Bugs: + * + * - If valid abs directory name is entered into the entry box and Enter + * pressed, the box will close returning the name. This is inconsistent when + * entering relative names or names with forward slashes, which are + * invalidated then corrected in the callback. After correction, the box is + * held open to allow further modification by the user. + * + * - Not sure how to implement localization of message prompts. + * + * - -title is really -message. + * ToDo: + * - Fix bugs. + * - test to see what platforms this really works on. May require v4.71 of + * shell32.dll everywhere (what is standard?). + * + *---------------------------------------------------------------------- */ + int Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) - ClientData clientData; /* Main window associated with interpreter. */ + ClientData clientData; /* Main window associated with interpreter. */ Tcl_Interp *interp; /* Current interpreter. */ int objc; /* Number of arguments. */ Tcl_Obj *CONST objv[]; /* Argument objects. */ @@ -1731,81 +1736,81 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) Tcl_DString titleString; /* UTF Title */ Tcl_DString initDirString; /* Initial directory */ static CONST char *optionStrings[] = { - "-initialdir", "-mustexist", "-parent", "-title", (char *) NULL + "-initialdir", "-mustexist", "-parent", "-title", (char *) NULL }; enum options { - DIR_INITIAL, DIR_EXIST, DIR_PARENT, FILE_TITLE + DIR_INITIAL, DIR_EXIST, DIR_PARENT, FILE_TITLE }; /* * Initialize */ - result = TCL_ERROR; - path[0] = '\0'; - utfTitle = NULL; + + result = TCL_ERROR; + path[0] = '\0'; + utfTitle = NULL; ZeroMemory(&cdCBData, sizeof(CHOOSEDIRDATA)); - cdCBData.interp = interp; + cdCBData.interp = interp; tkwin = (Tk_Window) clientData; + /* * Process the command line options */ + for (i = 1; i < objc; i += 2) { - int index; - char *string; - Tcl_Obj *optionPtr, *valuePtr; - - optionPtr = objv[i]; - valuePtr = objv[i + 1]; - - if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings, "option", - 0, &index) != TCL_OK) { - goto cleanup; - } - if (i + 1 == objc) { - string = Tcl_GetStringFromObj(optionPtr, NULL); - Tcl_AppendResult(interp, "value for \"", string, "\" missing", - (char *) NULL); - goto cleanup; - } + int index; + char *string; + Tcl_Obj *optionPtr, *valuePtr; + + optionPtr = objv[i]; + valuePtr = objv[i + 1]; + + if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings, "option", 0, + &index) != TCL_OK) { + goto cleanup; + } + if (i + 1 == objc) { + string = Tcl_GetString(optionPtr); + Tcl_AppendResult(interp, "value for \"", string, "\" missing", + (char *) NULL); + goto cleanup; + } string = Tcl_GetString(valuePtr); - switch ((enum options) index) { - case DIR_INITIAL: { - if (Tcl_TranslateFileName(interp, string, - &initDirString) == NULL) { - goto cleanup; - } - string = Tcl_DStringValue(&initDirString); - /* - * Convert possible relative path to full path to keep - * dialog happy - */ - GetFullPathName(string, MAX_PATH, saveDir, NULL); - lstrcpyn(cdCBData.utfInitDir, saveDir, MAX_PATH); - Tcl_DStringFree(&initDirString); - break; - } - case DIR_EXIST: { - if (Tcl_GetBooleanFromObj(interp, valuePtr, - &cdCBData.mustExist) != TCL_OK) { - goto cleanup; - } - break; - } - case DIR_PARENT: { - tkwin = Tk_NameToWindow(interp, string, tkwin); - if (tkwin == NULL) { - goto cleanup; - } - break; - } - case FILE_TITLE: { - utfTitle = string; - break; - } - } + switch ((enum options) index) { + case DIR_INITIAL: + if (Tcl_TranslateFileName(interp,string,&initDirString) == NULL) { + goto cleanup; + } + string = Tcl_DStringValue(&initDirString); + + /* + * Convert possible relative path to full path to keep dialog + * happy. + */ + + GetFullPathName(string, MAX_PATH, saveDir, NULL); + lstrcpyn(cdCBData.utfInitDir, saveDir, MAX_PATH); + Tcl_DStringFree(&initDirString); + break; + case DIR_EXIST: + if (Tcl_GetBooleanFromObj(interp, valuePtr, + &cdCBData.mustExist) != TCL_OK) { + goto cleanup; + } + break; + case DIR_PARENT: + tkwin = Tk_NameToWindow(interp, string, tkwin); + if (tkwin == NULL) { + goto cleanup; + } + break; + case FILE_TITLE: + utfTitle = string; + break; + } } /* @@ -1819,44 +1824,50 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) * Setup the parameters used by SHBrowseForFolder */ - bInfo.hwndOwner = hWnd; + bInfo.hwndOwner = hWnd; bInfo.pszDisplayName = path; - bInfo.pidlRoot = NULL; + bInfo.pidlRoot = NULL; if (lstrlen(cdCBData.utfInitDir) == 0) { - GetCurrentDirectory(MAX_PATH, cdCBData.utfInitDir); + GetCurrentDirectory(MAX_PATH, cdCBData.utfInitDir); } bInfo.lParam = (LPARAM) &cdCBData; if (utfTitle != NULL) { - Tcl_UtfToExternalDString(NULL, utfTitle, -1, &titleString); - bInfo.lpszTitle = (LPTSTR) Tcl_DStringValue(&titleString); + Tcl_UtfToExternalDString(NULL, utfTitle, -1, &titleString); + bInfo.lpszTitle = (LPTSTR) Tcl_DStringValue(&titleString); } else { - bInfo.lpszTitle = "Please choose a directory, then select OK."; + bInfo.lpszTitle = "Please choose a directory, then select OK."; } /* * Set flags to add edit box (needs 4.71 Shell DLLs), status text line, * validate edit box and */ - bInfo.ulFlags = BIF_EDITBOX | BIF_STATUSTEXT | BIF_RETURNFSANCESTORS - | BIF_VALIDATE; + + bInfo.ulFlags = BIF_EDITBOX | BIF_STATUSTEXT | BIF_RETURNFSANCESTORS + | BIF_VALIDATE; /* * Callback to handle events */ - bInfo.lpfn = (BFFCALLBACK) ChooseDirectoryValidateProc; + + bInfo.lpfn = (BFFCALLBACK) ChooseDirectoryValidateProc; /* - * Display dialog in background and process result. - * We look to give the user a chance to change their mind - * on an invalid folder if mustexist is 0; + * Display dialog in background and process result. We look to give the + * user a chance to change their mind on an invalid folder if mustexist is + * 0; */ oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); GetCurrentDirectory(MAX_PATH, saveDir); if (SHGetMalloc(&pMalloc) == NOERROR) { pidl = SHBrowseForFolder(&bInfo); - /* Null for cancel button or invalid dir, otherwise valid*/ + + /* + * Null for cancel button or invalid dir, otherwise valid. + */ + if (pidl != NULL) { if (!SHGetPathFromIDList(pidl, path)) { Tcl_SetResult(interp, "Error: Not a file system folder\n", @@ -1872,38 +1883,40 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) Tcl_SetServiceMode(oldMode); /* - * Ensure that hWnd is enabled, because it can happen that we - * have updated the wrapper of the parent, which causes us to - * leave this child disabled (Windows loses sync). + * Ensure that hWnd is enabled, because it can happen that we have updated + * the wrapper of the parent, which causes us to leave this child disabled + * (Windows loses sync). */ + EnableWindow(hWnd, 1); /* - * Change the pathname to the Tcl "normalized" pathname, where - * back slashes are used instead of forward slashes + * Change the pathname to the Tcl "normalized" pathname, where back + * slashes are used instead of forward slashes */ + Tcl_ResetResult(interp); if (*path) { - char *p; - Tcl_DString ds; + char *p; + Tcl_DString ds; - Tcl_ExternalToUtfDString(NULL, (char *) path, -1, &ds); - for (p = Tcl_DStringValue(&ds); *p != '\0'; p++) { - if (*p == '\\') { - *p = '/'; - } - } - Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL); - Tcl_DStringFree(&ds); + Tcl_ExternalToUtfDString(NULL, (char *) path, -1, &ds); + for (p = Tcl_DStringValue(&ds); *p != '\0'; p++) { + if (*p == '\\') { + *p = '/'; + } + } + Tcl_AppendResult(interp, Tcl_DStringValue(&ds), NULL); + Tcl_DStringFree(&ds); } result = TCL_OK; if (utfTitle != NULL) { - Tcl_DStringFree(&titleString); + Tcl_DStringFree(&titleString); } - cleanup: + cleanup: return result; } @@ -1912,15 +1925,17 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) * * ChooseDirectoryValidateProc -- * - * Hook procedure called by the explorer ChooseDirectory dialog when events - * occur. It is used to validate the text entry the user may have entered. + * Hook function called by the explorer ChooseDirectory dialog when + * events occur. It is used to validate the text entry the user may have + * entered. * * Results: - * Returns 0 to allow default processing of message, or 1 to - * tell default dialog procedure not to close. + * Returns 0 to allow default processing of message, or 1 to + * tell default dialog function not to close. * *---------------------------------------------------------------------- */ + static UINT APIENTRY ChooseDirectoryValidateProc ( HWND hwnd, @@ -1933,7 +1948,7 @@ ChooseDirectoryValidateProc ( Tcl_DString initDirString; char string[MAX_PATH]; ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); chooseDirSharedData = (CHOOSEDIRDATA *)lpData; @@ -1944,120 +1959,123 @@ ChooseDirectoryValidateProc ( #endif if (tsdPtr->debugFlag) { - tsdPtr->debugInterp = (Tcl_Interp *) chooseDirSharedData->interp; - Tcl_DoWhenIdle(SetTkDialog, (ClientData) hwnd); + tsdPtr->debugInterp = (Tcl_Interp *) chooseDirSharedData->interp; + Tcl_DoWhenIdle(SetTkDialog, (ClientData) hwnd); } chooseDirSharedData->utfRetDir[0] = '\0'; switch (message) { - case BFFM_VALIDATEFAILED: - /* - * First save and check to see if it is a valid path name, if - * so then make that path the one shown in the - * window. Otherwise, it failed the check and should be treated - * as such. Use Set/GetCurrentDirectory which allows relative - * path names and names with forward slashes. Use - * Tcl_TranslateFileName to make sure names like ~ are - * converted correctly. - */ - Tcl_TranslateFileName(chooseDirSharedData->interp, - (char *)lParam, &initDirString); - lstrcpyn (string, Tcl_DStringValue(&initDirString), MAX_PATH); - Tcl_DStringFree(&initDirString); - - if (SetCurrentDirectory((char *)string) == 0) { - LPTSTR lpFilePart[MAX_PATH]; - /* - * Get the full path name to the user entry, - * at this point it doesn't exist so see if - * it is supposed to. Otherwise just return it. - */ - GetFullPathName(string, MAX_PATH, - chooseDirSharedData->utfRetDir, /*unused*/ lpFilePart); - if (chooseDirSharedData->mustExist) { - /* - * User HAS to select a valid directory. - */ - wsprintf(selDir, TEXT("Directory '%.200s' does not exist,\nplease select or enter an existing directory."), chooseDirSharedData->utfRetDir); - MessageBox(NULL, selDir, NULL, MB_ICONEXCLAMATION|MB_OK); - return 1; - } - } else { - /* - * Changed to new folder OK, return immediatly with the - * current directory in utfRetDir. - */ - GetCurrentDirectory(MAX_PATH, chooseDirSharedData->utfRetDir); - return 0; - } - return 0; - - case BFFM_SELCHANGED: - /* - * Set the status window to the currently selected path. - * And enable the OK button if a file system folder, otherwise - * disable the OK button for things like server names. - * perhaps a new switch -enablenonfolders can be used to allow - * non folders to be selected. - * - * Not called when user changes edit box directly. - */ - - if (SHGetPathFromIDList((LPITEMIDLIST) lParam, selDir)) { - SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM) selDir); - // enable the OK button - SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1); - SetCurrentDirectory(selDir); - } else { - // disable the OK button - SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 0); - } - UpdateWindow(hwnd); - return 1; - - case BFFM_INITIALIZED: { - /* - * Directory browser intializing - tell it where to start from, - * user specified parameter. - */ - char *initDir = chooseDirSharedData->utfInitDir; - - SetCurrentDirectory(initDir); - if (*initDir == '\\') { + case BFFM_VALIDATEFAILED: + /* + * First save and check to see if it is a valid path name, if so then + * make that path the one shown in the window. Otherwise, it failed + * the check and should be treated as such. Use + * Set/GetCurrentDirectory which allows relative path names and names + * with forward slashes. Use Tcl_TranslateFileName to make sure names + * like ~ are converted correctly. + */ + + Tcl_TranslateFileName(chooseDirSharedData->interp, + (char *)lParam, &initDirString); + lstrcpyn (string, Tcl_DStringValue(&initDirString), MAX_PATH); + Tcl_DStringFree(&initDirString); + + if (SetCurrentDirectory((char *)string) == 0) { + LPTSTR lpFilePart[MAX_PATH]; + + /* + * Get the full path name to the user entry, at this point it + * doesn't exist so see if it is supposed to. Otherwise just + * return it. + */ + + GetFullPathName(string, MAX_PATH, + chooseDirSharedData->utfRetDir, /*unused*/ lpFilePart); + if (chooseDirSharedData->mustExist) { /* - * BFFM_SETSELECTION only understands UNC paths as pidls, - * so convert path to pidl using IShellFolder interface. + * User HAS to select a valid directory. */ - LPMALLOC pMalloc; - LPSHELLFOLDER psfFolder; - - if (SUCCEEDED(SHGetMalloc(&pMalloc))) { - if (SUCCEEDED(SHGetDesktopFolder(&psfFolder))) { - LPITEMIDLIST pidlMain; - ULONG ulCount, ulAttr; - Tcl_DString ds; - - Tcl_UtfToExternalDString(TkWinGetUnicodeEncoding(), - initDir, -1, &ds); - if (SUCCEEDED(psfFolder->lpVtbl->ParseDisplayName( - psfFolder, hwnd, NULL, - (WCHAR *) Tcl_DStringValue(&ds), - &ulCount, &pidlMain, &ulAttr)) - && (pidlMain != NULL)) { - SendMessage(hwnd, BFFM_SETSELECTION, FALSE, - (LPARAM)pidlMain); - pMalloc->lpVtbl->Free(pMalloc, pidlMain); - } - psfFolder->lpVtbl->Release(psfFolder); - Tcl_DStringFree(&ds); + + wsprintf(selDir, TEXT("Directory '%.200s' does not exist,\nplease select or enter an existing directory."), chooseDirSharedData->utfRetDir); + MessageBox(NULL, selDir, NULL, MB_ICONEXCLAMATION|MB_OK); + return 1; + } + } else { + /* + * Changed to new folder OK, return immediatly with the + * current directory in utfRetDir. + */ + GetCurrentDirectory(MAX_PATH, chooseDirSharedData->utfRetDir); + return 0; + } + return 0; + + case BFFM_SELCHANGED: + /* + * Set the status window to the currently selected path. And enable + * the OK button if a file system folder, otherwise disable the OK + * button for things like server names. Perhaps a new switch + * -enablenonfolders can be used to allow non folders to be selected. + * + * Not called when user changes edit box directly. + */ + + if (SHGetPathFromIDList((LPITEMIDLIST) lParam, selDir)) { + SendMessage(hwnd, BFFM_SETSTATUSTEXT, 0, (LPARAM) selDir); + // enable the OK button + SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1); + SetCurrentDirectory(selDir); + } else { + // disable the OK button + SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 0); + } + UpdateWindow(hwnd); + return 1; + + case BFFM_INITIALIZED: { + /* + * Directory browser intializing - tell it where to start from, user + * specified parameter. + */ + + char *initDir = chooseDirSharedData->utfInitDir; + + SetCurrentDirectory(initDir); + if (*initDir == '\\') { + /* + * BFFM_SETSELECTION only understands UNC paths as pidls, + * so convert path to pidl using IShellFolder interface. + */ + + LPMALLOC pMalloc; + LPSHELLFOLDER psfFolder; + + if (SUCCEEDED(SHGetMalloc(&pMalloc))) { + if (SUCCEEDED(SHGetDesktopFolder(&psfFolder))) { + LPITEMIDLIST pidlMain; + ULONG ulCount, ulAttr; + Tcl_DString ds; + + Tcl_UtfToExternalDString(TkWinGetUnicodeEncoding(), + initDir, -1, &ds); + if (SUCCEEDED(psfFolder->lpVtbl->ParseDisplayName( + psfFolder, hwnd, NULL, (WCHAR *) + Tcl_DStringValue(&ds), &ulCount,&pidlMain,&ulAttr)) + && (pidlMain != NULL)) { + SendMessage(hwnd, BFFM_SETSELECTION, FALSE, + (LPARAM)pidlMain); + pMalloc->lpVtbl->Free(pMalloc, pidlMain); } - pMalloc->lpVtbl->Release(pMalloc); + psfFolder->lpVtbl->Release(psfFolder); + Tcl_DStringFree(&ds); } - } else { - SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)initDir); + pMalloc->lpVtbl->Release(pMalloc); } - SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1); - break; + } else { + SendMessage(hwnd, BFFM_SETSELECTION, TRUE, (LPARAM)initDir); } + SendMessage(hwnd, BFFM_ENABLEOK, 0, (LPARAM) 1); + break; + } } return 0; @@ -2068,16 +2086,16 @@ ChooseDirectoryValidateProc ( * * Tk_ChooseDirectoryObjCmd -- * - * This procedure implements the "tk_chooseDirectory" dialog box - * for the Windows platform. See the user documentation for details - * on what it does. + * This function implements the "tk_chooseDirectory" dialog box for the + * Windows platform. See the user documentation for details on what it + * does. * * Results: * See user documentation. * * Side effects: - * A modal dialog window is created. Tcl_SetServiceMode() is - * called to allow background events to be processed + * A modal dialog window is created. Tcl_SetServiceMode() is called to + * allow background events to be processed * *---------------------------------------------------------------------- */ @@ -2098,8 +2116,8 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) char *utfTitle; Tcl_DString utfDirString; Tcl_DString titleString, dirString; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); static CONST char *optionStrings[] = { "-initialdir", "-mustexist", "-parent", "-title", NULL @@ -2109,9 +2127,9 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) }; if (tsdPtr->WM_LBSELCHANGED == 0) { - tsdPtr->WM_LBSELCHANGED = RegisterWindowMessage(LBSELCHSTRING); + tsdPtr->WM_LBSELCHANGED = RegisterWindowMessage(LBSELCHSTRING); } - + result = TCL_ERROR; path[0] = '\0'; @@ -2128,44 +2146,39 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) optionPtr = objv[i]; valuePtr = objv[i + 1]; - if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings, "option", - 0, &index) != TCL_OK) { + if (Tcl_GetIndexFromObj(interp, optionPtr, optionStrings, "option", 0, + &index) != TCL_OK) { goto cleanup; } if (i + 1 == objc) { - string = Tcl_GetStringFromObj(optionPtr, NULL); - Tcl_AppendResult(interp, "value for \"", string, "\" missing", + string = Tcl_GetString(optionPtr); + Tcl_AppendResult(interp, "value for \"", string, "\" missing", (char *) NULL); goto cleanup; } - string = Tcl_GetStringFromObj(valuePtr, NULL); + string = Tcl_GetString(valuePtr); switch ((enum options) index) { - case DIR_INITIAL: { - Tcl_DStringFree(&utfDirString); - if (Tcl_TranslateFileName(interp, string, - &utfDirString) == NULL) { - goto cleanup; - } - break; - } - case DIR_EXIST: { - if (Tcl_GetBooleanFromObj(interp, valuePtr, &mustExist) != TCL_OK) { - goto cleanup; - } - break; + case DIR_INITIAL: + Tcl_DStringFree(&utfDirString); + if (Tcl_TranslateFileName(interp, string, &utfDirString) == NULL) { + goto cleanup; } - case DIR_PARENT: { - tkwin = Tk_NameToWindow(interp, string, tkwin); - if (tkwin == NULL) { - goto cleanup; - } - break; + break; + case DIR_EXIST: + if (Tcl_GetBooleanFromObj(interp,valuePtr,&mustExist) != TCL_OK) { + goto cleanup; } - case FILE_TITLE: { - utfTitle = string; - break; + break; + case DIR_PARENT: + tkwin = Tk_NameToWindow(interp, string, tkwin); + if (tkwin == NULL) { + goto cleanup; } + break; + case FILE_TITLE: + utfTitle = string; + break; } } @@ -2175,43 +2188,40 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) cd.interp = interp; cd.ofnPtr = &ofn; - ofn.lStructSize = sizeof(ofn); - ofn.hwndOwner = hWnd; + ofn.lStructSize = sizeof(ofn); + ofn.hwndOwner = hWnd; #ifdef _WIN64 - ofn.hInstance = (HINSTANCE) GetWindowLongPtr(ofn.hwndOwner, - GWLP_HINSTANCE); + ofn.hInstance = (HINSTANCE) GetWindowLongPtr(ofn.hwndOwner,GWLP_HINSTANCE); #else - ofn.hInstance = (HINSTANCE) GetWindowLong(ofn.hwndOwner, - GWL_HINSTANCE); + ofn.hInstance = (HINSTANCE) GetWindowLong(ofn.hwndOwner, GWL_HINSTANCE); #endif - ofn.lpstrFilter = NULL; - ofn.lpstrCustomFilter = NULL; - ofn.nMaxCustFilter = 0; - ofn.nFilterIndex = 0; - ofn.lpstrFile = NULL; //(TCHAR *) path; - ofn.nMaxFile = MAX_PATH; - ofn.lpstrFileTitle = NULL; - ofn.nMaxFileTitle = 0; - ofn.lpstrInitialDir = NULL; - ofn.lpstrTitle = NULL; - ofn.Flags = OFN_HIDEREADONLY - | OFN_ENABLEHOOK | OFN_ENABLETEMPLATE; - ofn.nFileOffset = 0; - ofn.nFileExtension = 0; - ofn.lpstrDefExt = NULL; - ofn.lCustData = (LPARAM) &cd; - ofn.lpfnHook = (LPOFNHOOKPROC) ChooseDirectoryHookProc; - ofn.lpTemplateName = MAKEINTRESOURCE(FILEOPENORD); + ofn.lpstrFilter = NULL; + ofn.lpstrCustomFilter = NULL; + ofn.nMaxCustFilter = 0; + ofn.nFilterIndex = 0; + ofn.lpstrFile = NULL; //(TCHAR *) path; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = NULL; + ofn.lpstrTitle = NULL; + ofn.Flags = OFN_HIDEREADONLY | OFN_ENABLEHOOK | OFN_ENABLETEMPLATE; + ofn.nFileOffset = 0; + ofn.nFileExtension = 0; + ofn.lpstrDefExt = NULL; + ofn.lCustData = (LPARAM) &cd; + ofn.lpfnHook = (LPOFNHOOKPROC) ChooseDirectoryHookProc; + ofn.lpTemplateName = MAKEINTRESOURCE(FILEOPENORD); if (Tcl_DStringValue(&utfDirString)[0] != '\0') { - Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&utfDirString), + Tcl_UtfToExternalDString(NULL, Tcl_DStringValue(&utfDirString), Tcl_DStringLength(&utfDirString), &dirString); } else { /* - * NT 5.0 changed the meaning of lpstrInitialDir, so we have - * to ensure that we set the [pwd] if the user didn't specify - * anything else. + * NT 5.0 changed the meaning of lpstrInitialDir, so we have to ensure + * that we set the [pwd] if the user didn't specify anything else. */ + Tcl_DString cwd; Tcl_DStringFree(&utfDirString); @@ -2236,10 +2246,10 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) } /* - * Display dialog. The choose directory dialog doesn't preserve the + * Display dialog. The choose directory dialog doesn't preserve the * current directory, so it must be saved and restored here. */ - + GetCurrentDirectory(MAX_PATH, savePath); mode = Tcl_SetServiceMode(TCL_SERVICE_ALL); code = GetOpenFileName(&ofn); @@ -2247,17 +2257,18 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) SetCurrentDirectory(savePath); /* - * Ensure that hWnd is enabled, because it can happen that we - * have updated the wrapper of the parent, which causes us to - * leave this child disabled (Windows loses sync). + * Ensure that hWnd is enabled, because it can happen that we have updated + * the wrapper of the parent, which causes us to leave this child disabled + * (Windows loses sync). */ + EnableWindow(hWnd, 1); Tcl_ResetResult(interp); if (code != 0) { /* - * Change the pathname to the Tcl "normalized" pathname, where - * back slashes are used instead of forward slashes + * Change the pathname to the Tcl "normalized" pathname, where back + * slashes are used instead of forward slashes */ char *p; @@ -2281,7 +2292,7 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) } result = TCL_OK; - cleanup: + cleanup: Tcl_DStringFree(&utfDirString); return result; @@ -2292,35 +2303,33 @@ Tk_ChooseDirectoryObjCmd(clientData, interp, objc, objv) * * ChooseDirectoryHookProc -- * - * Hook procedure called by the ChooseDirectory dialog to modify - * its default behavior. The ChooseDirectory dialog is really an - * OpenFile dialog with certain controls rearranged and certain - * behaviors changed. For instance, typing a name in the - * ChooseDirectory dialog selects a directory, rather than - * selecting a file. + * Hook function called by the ChooseDirectory dialog to modify its + * default behavior. The ChooseDirectory dialog is really an OpenFile + * dialog with certain controls rearranged and certain behaviors changed. + * For instance, typing a name in the ChooseDirectory dialog selects a + * directory, rather than selecting a file. * * Results: - * Returns 0 to allow default processing of message, or 1 to - * tell default dialog procedure not to process the message. + * Returns 0 to allow default processing of message, or 1 to tell default + * dialog function not to process the message. * * Side effects: - * A dialog window is created the first this procedure is called. - * This window is not destroyed and will be reused the next time - * the application invokes the "tk_getOpenFile" or - * "tk_getSaveFile" command. + * A dialog window is created the first this function is called. This + * window is not destroyed and will be reused the next time the + * application invokes the "tk_getOpenFile" or "tk_getSaveFile" command. * *---------------------------------------------------------------------- */ -static UINT APIENTRY +static UINT APIENTRY ChooseDirectoryHookProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); OPENFILENAME *ofnPtr; ChooseDir *cdPtr; @@ -2353,7 +2362,7 @@ ChooseDirectoryHookProc( /* * GWL_USERDATA keeps track of cdPtr. */ - + #ifdef _WIN64 cdPtr = (ChooseDir *) GetWindowLongPtr(hwnd, GWLP_USERDATA); #else @@ -2366,15 +2375,15 @@ ChooseDirectoryHookProc( if (message == tsdPtr->WM_LBSELCHANGED) { /* - * Called when double-clicking on directory. - * If directory wasn't already open, browse that directory. - * If directory was already open, return selected directory. + * Called when double-clicking on directory. If directory wasn't + * already open, browse that directory. If directory was already open, + * return selected directory. */ int idCtrl, thisItem; idCtrl = (int) wParam; - thisItem = LOWORD(lParam); + thisItem = LOWORD(lParam); GetCurrentDirectory(MAX_PATH, cdPtr->path); if (idCtrl == lst2) { @@ -2404,18 +2413,17 @@ ChooseDirectoryHookProc( } /* - * Dialogs also get the message that OK was clicked when Enter - * is pressed in some other control. Find out what window - * we were really in when we got the supposed "OK", because the - * behavior is different. + * Dialogs also get the message that OK was clicked when Enter is + * pressed in some other control. Find out what window we were really + * in when we got the supposed "OK", because the behavior is + * different. */ if (cdPtr->lastCtrl == edt10) { /* - * Hit Enter or clicked OK while typing a directory name in the - * edit control. - * If it's a new name, try to go to that directory. - * If the name hasn't changed since last time, return selected + * Hit Enter or clicked OK while typing a directory name in the + * edit control. If it's a new name, try to go to that directory. + * If the name hasn't changed since last time, return selected * directory. */ @@ -2436,7 +2444,7 @@ ChooseDirectoryHookProc( if (ofnPtr->Flags & OFN_PATHMUSTEXIST) { /* - * Directory must exist. Complain, then rehighlight text. + * Directory must exist. Complain, then rehighlight text. */ wsprintf(tmp, _T("Cannot change directory to \"%.200s\"."), @@ -2444,46 +2452,45 @@ ChooseDirectoryHookProc( MessageBox(hwnd, tmp, NULL, MB_OK); SendDlgItemMessage(hwnd, edt10, EM_SETSEL, 0, -1); return 0; - } + } if (changed) { /* * Directory was invalid, but we want to keep displaying - * this name. Don't update the listbox that displays the + * this name. Don't update the listbox that displays the * current directory heirarchy, or it'll erase the name. */ - + SendDlgItemMessage(hwnd, edt10, EM_SETSEL, 0, -1); return 0; } } if (changed == 0) { /* - * Name hasn't changed since the last time we hit return - * or double-clicked on a directory, so return this. + * Name hasn't changed since the last time we hit return or + * double-clicked on a directory, so return this. */ EndDialog(hwnd, IDOK); return 1; } - + cdPtr->lastCtrl = IDOK; /* - * The following is the magic code, determined by running - * Spy++ on some other directory chooser, that it takes to - * get this dialog to update the listbox to display the - * current directory. + * The following is the magic code, determined by running Spy++ on + * some other directory chooser, that it takes to get this dialog + * to update the listbox to display the current directory. */ SetDlgItemText(hwnd, edt1, cdPtr->path); - SendMessage(hwnd, WM_COMMAND, (WPARAM) MAKELONG(cmb2, 0x8003), + SendMessage(hwnd, WM_COMMAND, (WPARAM) MAKELONG(cmb2, 0x8003), (LPARAM) GetDlgItem(hwnd, cmb2)); return 0; } else if (idCtrl == lst2) { /* - * Enter key was pressed while in listbox. - * If it's a new directory, allow default behavior to open dir. - * If the directory hasn't changed, return selected directory. + * Enter key was pressed while in listbox. If it's a new + * directory, allow default behavior to open dir. If the directory + * hasn't changed, return selected directory. */ int thisItem; @@ -2495,9 +2502,9 @@ ChooseDirectoryHookProc( return 1; } } else if (idCtrl == IDOK) { - /* + /* * The OK button was clicked. Return the value currently selected - * in the entry. + * in the entry. */ GetCurrentDirectory(MAX_PATH, cdPtr->path); @@ -2514,15 +2521,14 @@ ChooseDirectoryHookProc( * * Tk_MessageBoxObjCmd -- * - * This procedure implements the MessageBox window for the - * Windows platform. See the user documentation for details on what - * it does. + * This function implements the MessageBox window for the Windows + * platform. See the user documentation for details on what it does. * * Results: * See user documentation. * * Side effects: - * None. The MessageBox window will be destroy before this procedure + * None. The MessageBox window will be destroy before this function * returns. * *---------------------------------------------------------------------- @@ -2551,18 +2557,18 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv) MSG_DEFAULT, MSG_DETAIL, MSG_ICON, MSG_MESSAGE, MSG_PARENT, MSG_TITLE, MSG_TYPE }; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); tkwin = (Tk_Window) clientData; - defaultBtn = -1; - detail = NULL; - icon = MB_ICONINFORMATION; - message = NULL; - parent = tkwin; - title = NULL; - type = MB_OK; + defaultBtn = -1; + detail = NULL; + icon = MB_ICONINFORMATION; + message = NULL; + parent = tkwin; + title = NULL; + type = MB_OK; for (i = 1; i < objc; i += 2) { int index; @@ -2577,16 +2583,16 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv) return TCL_ERROR; } if (i + 1 == objc) { - string = Tcl_GetStringFromObj(optionPtr, NULL); - Tcl_AppendResult(interp, "value for \"", string, "\" missing", + string = Tcl_GetString(optionPtr); + Tcl_AppendResult(interp, "value for \"", string, "\" missing", (char *) NULL); return TCL_ERROR; } - string = Tcl_GetStringFromObj(valuePtr, NULL); + string = Tcl_GetString(valuePtr); switch ((enum options) index) { - case MSG_DEFAULT: - defaultBtn = TkFindStateNumObj(interp, optionPtr, buttonMap, + case MSG_DEFAULT: + defaultBtn = TkFindStateNumObj(interp, optionPtr, buttonMap, valuePtr); if (defaultBtn < 0) { return TCL_ERROR; @@ -2608,7 +2614,7 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv) message = string; break; - case MSG_PARENT: + case MSG_PARENT: parent = Tk_NameToWindow(interp, string, tkwin); if (parent == NULL) { return TCL_ERROR; @@ -2625,13 +2631,12 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv) return TCL_ERROR; } break; - } } Tk_MakeWindowExist(parent); hWnd = Tk_GetHWND(Tk_WindowId(parent)); - + flags = 0; if (defaultBtn >= 0) { int defaultBtnIdx; @@ -2649,7 +2654,7 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv) } if (defaultBtnIdx < 0) { Tcl_AppendResult(interp, "invalid default button \"", - TkFindStateString(buttonMap, defaultBtn), + TkFindStateString(buttonMap, defaultBtn), "\"", NULL); return TCL_ERROR; } @@ -2683,13 +2688,14 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv) oldMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); /* - * MessageBoxW exists for all platforms. Use it to allow unicode - * error message to be displayed correctly where possible by the OS. + * MessageBoxW exists for all platforms. Use it to allow unicode error + * message to be displayed correctly where possible by the OS. * - * In order to have the parent window icon reflected in a MessageBox, - * we have to create a hook that will trigger when the MessageBox is - * being created. + * In order to have the parent window icon reflected in a MessageBox, we + * have to create a hook that will trigger when the MessageBox is being + * created. */ + tsdPtr->hSmallIcon = TkWinGetIcon(parent, ICON_SMALL); tsdPtr->hBigIcon = TkWinGetIcon(parent, ICON_BIG); tsdPtr->hMsgBoxHook = SetWindowsHookEx(WH_CBT, MsgBoxCBTProc, NULL, @@ -2700,10 +2706,11 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv) (void) Tcl_SetServiceMode(oldMode); /* - * Ensure that hWnd is enabled, because it can happen that we - * have updated the wrapper of the parent, which causes us to - * leave this child disabled (Windows loses sync). + * Ensure that hWnd is enabled, because it can happen that we have updated + * the wrapper of the parent, which causes us to leave this child disabled + * (Windows loses sync). */ + EnableWindow(hWnd, 1); Tcl_DStringFree(&messageString); @@ -2716,41 +2723,50 @@ Tk_MessageBoxObjCmd(clientData, interp, objc, objv) static LRESULT CALLBACK MsgBoxCBTProc(int nCode, WPARAM wParam, LPARAM lParam) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (nCode == HCBT_CREATEWND) { /* - * Window owned by our task is being created. Since the hook is + * Window owned by our task is being created. Since the hook is * installed just before the MessageBox call and removed after the - * MessageBox call, the window being created is either the message - * box or one of its controls. Check that the class is WC_DIALOG - * to ensure that it's the one we want. + * MessageBox call, the window being created is either the message box + * or one of its controls. Check that the class is WC_DIALOG to ensure + * that it's the one we want. */ + LPCBT_CREATEWND lpcbtcreate = (LPCBT_CREATEWND)lParam; if (WC_DIALOG == lpcbtcreate->lpcs->lpszClass) { HWND hwnd = (HWND) wParam; SendMessage(hwnd, WM_SETICON, ICON_SMALL, (LPARAM) tsdPtr->hSmallIcon); - SendMessage(hwnd, WM_SETICON, ICON_BIG, - (LPARAM) tsdPtr->hBigIcon); + SendMessage(hwnd, WM_SETICON, ICON_BIG, (LPARAM) tsdPtr->hBigIcon); } } /* * Call the next hook proc, if there is one */ + return CallNextHookEx(tsdPtr->hMsgBoxHook, nCode, wParam, lParam); } -static void +static void SetTkDialog(ClientData clientData) { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); char buf[32]; sprintf(buf, "0x%p", (HWND) clientData); Tcl_SetVar(tsdPtr->debugInterp, "tk_dialog", buf, TCL_GLOBAL_ONLY); } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ diff --git a/win/tkWinMenu.c b/win/tkWinMenu.c index a33ddb8..0234f5a 100644 --- a/win/tkWinMenu.c +++ b/win/tkWinMenu.c @@ -1,15 +1,16 @@ -/* +/* * tkWinMenu.c -- * - * This module implements the Windows platform-specific features of menus. + * This module implements the Windows platform-specific features of + * menus. * * Copyright (c) 1996-1998 by Sun Microsystems, Inc. * Copyright (c) 1998-1999 by Scriptics Corporation. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. * - * RCS: @(#) $Id: tkWinMenu.c,v 1.44 2005/04/28 02:40:19 chengyemao Exp $ + * RCS: @(#) $Id: tkWinMenu.c,v 1.45 2005/08/10 22:02:22 dkf Exp $ */ #define OEMRESOURCE @@ -22,55 +23,55 @@ * The class of the window for popup menus. */ -#define MENU_CLASS_NAME "MenuWindowClass" -#define EMBEDDED_MENU_CLASS_NAME "EmbeddedMenuWindowClass" +#define MENU_CLASS_NAME "MenuWindowClass" +#define EMBEDDED_MENU_CLASS_NAME "EmbeddedMenuWindowClass" /* * Used to align a windows bitmap inside a rectangle */ -#define ALIGN_BITMAP_LEFT 0x00000001 -#define ALIGN_BITMAP_RIGHT 0x00000002 -#define ALIGN_BITMAP_TOP 0x00000004 -#define ALIGN_BITMAP_BOTTOM 0x00000008 +#define ALIGN_BITMAP_LEFT 0x00000001 +#define ALIGN_BITMAP_RIGHT 0x00000002 +#define ALIGN_BITMAP_TOP 0x00000004 +#define ALIGN_BITMAP_BOTTOM 0x00000008 /* * Platform-specific menu flags: * - * MENU_SYSTEM_MENU Non-zero means that the Windows menu handle - * was retrieved with GetSystemMenu and needs - * to be disposed of specially. + * MENU_SYSTEM_MENU Non-zero means that the Windows menu handle was + * retrieved with GetSystemMenu and needs to be disposed + * of specially. * MENU_RECONFIGURE_PENDING - * Non-zero means that an idle handler has - * been set up to reconfigure the Windows menu - * handle for this menu. + * Non-zero means that an idle handler has been set up to + * reconfigure the Windows menu handle for this menu. */ -#define MENU_SYSTEM_MENU MENU_PLATFORM_FLAG1 -#define MENU_RECONFIGURE_PENDING MENU_PLATFORM_FLAG2 +#define MENU_SYSTEM_MENU MENU_PLATFORM_FLAG1 +#define MENU_RECONFIGURE_PENDING MENU_PLATFORM_FLAG2 static int indicatorDimensions[2]; - /* The dimensions of the indicator space - * in a menu entry. Calculated at init - * time to save time. */ + /* The dimensions of the indicator space in a + * menu entry. Calculated at init time to save + * time. */ typedef struct ThreadSpecificData { Tcl_HashTable commandTable; /* A map of command ids to menu entries */ int inPostMenu; /* We cannot be re-entrant like X Windows. */ - WORD lastCommandID; /* The last command ID we allocated. */ + WORD lastCommandID; /* The last command ID we allocated. */ HWND menuHWND; /* A window to service popup-menu messages * in. */ - HWND embeddedMenuHWND; /* A window to service embedded menu messages */ - int oldServiceMode; /* Used while processing a menu; we need - * to set the event mode specially when we - * enter the menu processing modal loop - * and reset it when menus go away. */ + HWND embeddedMenuHWND; /* A window to service embedded menu + * messages */ + int oldServiceMode; /* Used while processing a menu; we need to + * set the event mode specially when we enter + * the menu processing modal loop and reset it + * when menus go away. */ TkMenu *modalMenuPtr; /* The menu we are processing inside the modal - * loop. We need this to reset all of the + * loop. We need this to reset all of the * active items when menus go away since - * Windows does not see fit to give this - * to us when it sends its WM_MENUSELECT. */ + * Windows does not see fit to give this to us + * when it sends its WM_MENUSELECT. */ Tcl_HashTable winMenuTable; /* Need this to map HMENUs back to menuPtrs */ } ThreadSpecificData; @@ -85,91 +86,78 @@ static Tcl_DString menuFontDString; /* A buffer to store the default menu font * string. */ /* - * Forward declarations for procedures defined later in this file: + * Forward declarations for functions defined later in this file: */ -static void DrawMenuEntryAccelerator _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, GC gc, Tk_Font tkfont, - CONST Tk_FontMetrics *fmPtr, - Tk_3DBorder activeBorder, int x, int y, - int width, int height)); -static void DrawMenuEntryArrow _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, GC gc, +static void DrawMenuEntryAccelerator(TkMenu *menuPtr, + TkMenuEntry *mePtr, Drawable d, GC gc, + Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, Tk_3DBorder activeBorder, int x, int y, - int width, int height, int drawArrow)); -static void DrawMenuEntryBackground _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, Tk_3DBorder activeBorder, - Tk_3DBorder bgBorder, int x, int y, - int width, int heigth)); -static void DrawMenuEntryIndicator _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Drawable d, GC gc, GC indicatorGC, - Tk_Font tkfont, + int width, int height); +static void DrawMenuEntryArrow(TkMenu *menuPtr, TkMenuEntry *mePtr, + Drawable d, GC gc, Tk_3DBorder activeBorder, + int x,int y, int width, int height, int drawArrow); +static void DrawMenuEntryBackground(TkMenu *menuPtr, + TkMenuEntry *mePtr, Drawable d, + Tk_3DBorder activeBorder, Tk_3DBorder bgBorder, + int x, int y, int width, int heigth); +static void DrawMenuEntryIndicator(TkMenu *menuPtr, + TkMenuEntry *mePtr, Drawable d, GC gc, + GC indicatorGC, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int x, int y, - int width, int height)); -static void DrawMenuEntryLabel _ANSI_ARGS_(( - TkMenu * menuPtr, TkMenuEntry *mePtr, Drawable d, - GC gc, Tk_Font tkfont, + int width, int height); +static void DrawMenuEntryLabel(TkMenu *menuPtr, TkMenuEntry *mePtr, + Drawable d, GC gc, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int x, int y, - int width, int height)); -static void DrawMenuSeparator _ANSI_ARGS_((TkMenu *menuPtr, - TkMenuEntry *mePtr, Drawable d, GC gc, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int x, int y, int width, int height)); -static void DrawTearoffEntry _ANSI_ARGS_((TkMenu *menuPtr, - TkMenuEntry *mePtr, Drawable d, GC gc, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int x, int y, int width, int height)); -static void DrawMenuUnderline _ANSI_ARGS_((TkMenu *menuPtr, + int width, int height); +static void DrawMenuSeparator(TkMenu *menuPtr, TkMenuEntry *mePtr, + Drawable d, GC gc, Tk_Font tkfont, + CONST Tk_FontMetrics *fmPtr, + int x, int y, int width, int height); +static void DrawTearoffEntry(TkMenu *menuPtr, + TkMenuEntry *mePtr, Drawable d, GC gc, + Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, + int x, int y, int width, int height); +static void DrawMenuUnderline(TkMenu *menuPtr, TkMenuEntry *mePtr, Drawable d, GC gc, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int x, - int y, int width, int height)); -static void DrawWindowsSystemBitmap _ANSI_ARGS_(( - Display *display, Drawable drawable, - GC gc, CONST RECT *rectPtr, int bitmapID, - int alignFlags)); -static void FreeID _ANSI_ARGS_((WORD commandID)); -static TCHAR * GetEntryText _ANSI_ARGS_((TkMenuEntry *mePtr)); -static void GetMenuAccelGeometry _ANSI_ARGS_((TkMenu *menuPtr, + int y, int width, int height); +static void DrawWindowsSystemBitmap(Display *display, + Drawable drawable, GC gc, CONST RECT *rectPtr, + int bitmapID, int alignFlags); +static void FreeID(WORD commandID); +static TCHAR * GetEntryText(TkMenuEntry *mePtr); +static void GetMenuAccelGeometry(TkMenu *menuPtr, TkMenuEntry *mePtr, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int *widthPtr, - int *heightPtr)); -static void GetMenuLabelGeometry _ANSI_ARGS_((TkMenuEntry *mePtr, + int *heightPtr); +static void GetMenuLabelGeometry(TkMenuEntry *mePtr, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int *widthPtr, int *heightPtr)); -static void GetMenuIndicatorGeometry _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int *widthPtr, int *heightPtr)); -static void GetMenuSeparatorGeometry _ANSI_ARGS_(( - TkMenu *menuPtr, TkMenuEntry *mePtr, - Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, - int *widthPtr, int *heightPtr)); -static void GetTearoffEntryGeometry _ANSI_ARGS_((TkMenu *menuPtr, + int *widthPtr, int *heightPtr); +static void GetMenuIndicatorGeometry(TkMenu *menuPtr, + TkMenuEntry *mePtr, Tk_Font tkfont, + CONST Tk_FontMetrics *fmPtr, + int *widthPtr, int *heightPtr); +static void GetMenuSeparatorGeometry(TkMenu *menuPtr, + TkMenuEntry *mePtr, Tk_Font tkfont, + CONST Tk_FontMetrics *fmPtr, + int *widthPtr, int *heightPtr); +static void GetTearoffEntryGeometry(TkMenu *menuPtr, TkMenuEntry *mePtr, Tk_Font tkfont, CONST Tk_FontMetrics *fmPtr, int *widthPtr, - int *heightPtr)); -static int GetNewID _ANSI_ARGS_((TkMenuEntry *mePtr, - WORD *menuIDPtr)); -static int TkWinMenuKeyObjCmd _ANSI_ARGS_((ClientData clientData, - Tcl_Interp *interp, int objc, - Tcl_Obj *CONST objv[])); -static void MenuSelectEvent _ANSI_ARGS_((TkMenu *menuPtr)); -static void ReconfigureWindowsMenu _ANSI_ARGS_(( - ClientData clientData)); -static void RecursivelyClearActiveMenu _ANSI_ARGS_(( - TkMenu *menuPtr)); -static void SetDefaults _ANSI_ARGS_((int firstTime)); -static LRESULT CALLBACK TkWinMenuProc _ANSI_ARGS_((HWND hwnd, - UINT message, WPARAM wParam, - LPARAM lParam)); -static LRESULT CALLBACK TkWinEmbeddedMenuProc _ANSI_ARGS_((HWND hwnd, - UINT message, WPARAM wParam, - LPARAM lParam)); - + int *heightPtr); +static int GetNewID(TkMenuEntry *mePtr, WORD *menuIDPtr); +static int TkWinMenuKeyObjCmd(ClientData clientData, + Tcl_Interp *interp, int objc, + Tcl_Obj *CONST objv[]); +static void MenuSelectEvent(TkMenu *menuPtr); +static void ReconfigureWindowsMenu(ClientData clientData); +static void RecursivelyClearActiveMenu(TkMenu *menuPtr); +static void SetDefaults(int firstTime); +static LRESULT CALLBACK TkWinMenuProc(HWND hwnd, UINT message, WPARAM wParam, + LPARAM lParam); +static LRESULT CALLBACK TkWinEmbeddedMenuProc(HWND hwnd, UINT message, + WPARAM wParam, LPARAM lParam); /* *---------------------------------------------------------------------- @@ -200,8 +188,8 @@ GetNewID(mePtr, menuIDPtr) int newEntry; Tcl_HashEntry *commandEntryPtr; WORD returnID; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); WORD curID = tsdPtr->lastCommandID + 1; @@ -209,7 +197,7 @@ GetNewID(mePtr, menuIDPtr) * The following code relies on WORD wrapping when the highest value is * incremented. */ - + while (curID != tsdPtr->lastCommandID) { commandEntryPtr = Tcl_CreateHashEntry(&tsdPtr->commandTable, (char *) curID, &newEntry); @@ -251,12 +239,12 @@ static void FreeID(commandID) WORD commandID; { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable, (char *) commandID); - + if (entryPtr != NULL) { Tcl_DeleteHashEntry(entryPtr); } @@ -282,17 +270,17 @@ FreeID(commandID) int TkpNewMenu(menuPtr) - TkMenu *menuPtr; /* The common structure we are making the - * platform structure for. */ + TkMenu *menuPtr; /* The common structure we are making the + * platform structure for. */ { HMENU winMenuHdl; Tcl_HashEntry *hashEntryPtr; int newEntry; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); winMenuHdl = CreatePopupMenu(); - + if (winMenuHdl == NULL) { Tcl_AppendResult(menuPtr->interp, "No more menus can be allocated.", (char *) NULL); @@ -300,12 +288,12 @@ TkpNewMenu(menuPtr) } /* - * We hash all of the HMENU's so that we can get their menu ptrs - * back when dispatch messages. + * We hash all of the HMENU's so that we can get their menu ptrs back when + * dispatch messages. */ - hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable, (char *) winMenuHdl, - &newEntry); + hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable, + (char *) winMenuHdl, &newEntry); Tcl_SetHashValue(hashEntryPtr, (char *) menuPtr); menuPtr->platformData = (TkMenuPlatformData) winMenuHdl; @@ -330,17 +318,17 @@ TkpNewMenu(menuPtr) void TkpDestroyMenu(menuPtr) - TkMenu *menuPtr; /* The common menu structure */ + TkMenu *menuPtr; /* The common menu structure */ { HMENU winMenuHdl = (HMENU) menuPtr->platformData; char *searchName; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) { Tcl_CancelIdleCall(ReconfigureWindowsMenu, (ClientData) menuPtr); } - + if (winMenuHdl == NULL) { return; } @@ -348,7 +336,7 @@ TkpDestroyMenu(menuPtr) if (menuPtr->menuFlags & MENU_SYSTEM_MENU) { TkMenuEntry *searchEntryPtr; Tcl_HashTable *tablePtr = TkGetMenuHashTable(menuPtr->interp); - char *menuName = Tcl_GetHashKey(tablePtr, + char *menuName = Tcl_GetHashKey(tablePtr, menuPtr->menuRefPtr->hashEntryPtr); /* @@ -358,29 +346,29 @@ TkpDestroyMenu(menuPtr) */ for (searchEntryPtr = menuPtr->menuRefPtr->parentEntryPtr; - searchEntryPtr != NULL; - searchEntryPtr = searchEntryPtr->nextCascadePtr) { - searchName = Tcl_GetStringFromObj(searchEntryPtr->namePtr, NULL); + searchEntryPtr != NULL; + searchEntryPtr = searchEntryPtr->nextCascadePtr) { + searchName = Tcl_GetString(searchEntryPtr->namePtr); if (strcmp(searchName, menuName) == 0) { Tk_Window parentTopLevelPtr = searchEntryPtr - ->menuPtr->parentTopLevelPtr; + ->menuPtr->parentTopLevelPtr; if (parentTopLevelPtr != NULL) { - GetSystemMenu(TkWinGetWrapperWindow(parentTopLevelPtr), - TRUE); + GetSystemMenu( + TkWinGetWrapperWindow(parentTopLevelPtr), TRUE); } break; } } } else { Tcl_HashEntry *hashEntryPtr; - + /* * Remove the menu from the menu hash table, then destroy the handle. */ - hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, - (char *) winMenuHdl); + hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, + (char *) winMenuHdl); if (hashEntryPtr != NULL) { Tcl_DeleteHashEntry(hashEntryPtr); } @@ -411,13 +399,13 @@ TkpDestroyMenu(menuPtr) void TkpDestroyMenuEntry(mePtr) - TkMenuEntry *mePtr; /* The entry to destroy */ + TkMenuEntry *mePtr; /* The entry to destroy */ { TkMenu *menuPtr = mePtr->menuPtr; HMENU winMenuHdl = (HMENU) menuPtr->platformData; if (NULL != winMenuHdl) { - if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) { + if (!(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) { menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr); } @@ -432,9 +420,9 @@ TkpDestroyMenuEntry(mePtr) * GetEntryText -- * * Given a menu entry, gives back the text that should go in it. - * Separators should be done by the caller, as they have to be - * handled specially. Allocates the memory with alloc. The caller - * should free the memory. + * Separators should be done by the caller, as they have to be handled + * specially. Allocates the memory with alloc. The caller should free the + * memory. * * Results: * itemText points to the new text for the item. @@ -465,18 +453,17 @@ GetEntryText(mePtr) strcpy(itemText, "( )"); } else { int i; - char *label = (mePtr->labelPtr == NULL) ? "" - : Tcl_GetStringFromObj(mePtr->labelPtr, NULL); - char *accel = (mePtr->accelPtr == NULL) ? "" - : Tcl_GetStringFromObj(mePtr->accelPtr, NULL); + char *label = (mePtr->labelPtr == NULL) ? "" + : Tcl_GetString(mePtr->labelPtr); + char *accel = (mePtr->accelPtr == NULL) ? "" + : Tcl_GetString(mePtr->accelPtr); CONST char *p, *next; Tcl_DString itemString; /* - * We have to construct the string with an ampersand - * preceeding the underline character, and a tab seperating - * the text and the accel text. We have to be careful with - * ampersands in the string. + * We have to construct the string with an ampersand preceeding the + * underline character, and a tab seperating the text and the accel + * text. We have to be careful with ampersands in the string. */ Tcl_DStringInit(&itemString); @@ -491,7 +478,7 @@ GetEntryText(mePtr) next = Tcl_UtfNext(p); Tcl_DStringAppend(&itemString, p, (int) (next - p)); } - if (mePtr->accelLength > 0) { + if (mePtr->accelLength > 0) { Tcl_DStringAppend(&itemString, "\t", 1); for (p = accel, i = 0; *p != '\0'; i++, p = next) { if (*p == '&') { @@ -500,7 +487,7 @@ GetEntryText(mePtr) next = Tcl_UtfNext(p); Tcl_DStringAppend(&itemString, p, (int) (next - p)); } - } + } itemText = ckalloc(Tcl_DStringLength(&itemString) + 1); strcpy(itemText, Tcl_DStringValue(&itemString)); @@ -520,15 +507,15 @@ GetEntryText(mePtr) * None. * * Side effects: - * Configuration information get set for mePtr; old resources - * get freed, if any need it. + * Configuration information get set for mePtr; old resources get freed, + * if any need it. * *---------------------------------------------------------------------- */ static void ReconfigureWindowsMenu( - ClientData clientData) /* The menu we are rebuilding */ + ClientData clientData) /* The menu we are rebuilding */ { TkMenu *menuPtr = (TkMenu *) clientData; TkMenuEntry *mePtr; @@ -539,7 +526,7 @@ ReconfigureWindowsMenu( UINT itemID; int i, count, systemMenu = 0, base; Tcl_DString translatedText; - + if (NULL == winMenuHdl) { return; } @@ -547,7 +534,6 @@ ReconfigureWindowsMenu( /* * Reconstruct the entire menu. Takes care of nasty system menu and index * problem. - * */ base = (menuPtr->menuFlags & MENU_SYSTEM_MENU) ? 7 : 0; @@ -582,37 +568,37 @@ ReconfigureWindowsMenu( /* * Set enabling and disabling correctly. */ - + if (mePtr->state == ENTRY_DISABLED) { flags |= MF_DISABLED | MF_GRAYED; } - + /* * Set the check mark for check entries and radio entries. */ - + if (((mePtr->type == CHECK_BUTTON_ENTRY) || (mePtr->type == RADIO_BUTTON_ENTRY)) && (mePtr->entryFlags & ENTRY_SELECTED)) { flags |= MF_CHECKED; } - + /* - * Set the SEPARATOR bit for separator entries. This bit is not - * used by our internal drawing functions, but it is used by the - * system when drawing the system menu (we do not draw the system menu - * ourselves). If this bit is not set, separator entries on the system + * Set the SEPARATOR bit for separator entries. This bit is not used + * by our internal drawing functions, but it is used by the system + * when drawing the system menu (we do not draw the system menu + * ourselves). If this bit is not set, separator entries on the system * menu will not be drawn correctly. */ if (mePtr->type == SEPARATOR_ENTRY) { flags |= MF_SEPARATOR; } - + if (mePtr->columnBreak) { flags |= MF_MENUBREAK; } - + itemID = (UINT) mePtr->platformEntryData; if ((mePtr->type == CASCADE_ENTRY) && (mePtr->childMenuRefPtr != NULL) @@ -620,44 +606,45 @@ ReconfigureWindowsMenu( HMENU childMenuHdl = (HMENU) mePtr->childMenuRefPtr->menuPtr ->platformData; if (childMenuHdl != NULL) { - /* - * Win32 draws the popup arrow in the wrong color - * for a disabled cascade menu, so do it by hand. - * Given it is disabled, there's no need for it to - * be connected to its child. + /* + * Win32 draws the popup arrow in the wrong color for a + * disabled cascade menu, so do it by hand. Given it is + * disabled, there's no need for it to be connected to its + * child. */ + if (mePtr->state != ENTRY_DISABLED) { flags |= MF_POPUP; /* - * If the MF_POPUP flag is set, then the id - * is interpreted as the handle of a submenu. + * If the MF_POPUP flag is set, then the id is interpreted + * as the handle of a submenu. */ itemID = (UINT) childMenuHdl; - } + } } - if ((menuPtr->menuType == MENUBAR) + if ((menuPtr->menuType == MENUBAR) && !(mePtr->childMenuRefPtr->menuPtr->menuFlags & MENU_SYSTEM_MENU)) { Tcl_DString ds; TkMenuReferences *menuRefPtr; TkMenu *systemMenuPtr = mePtr->childMenuRefPtr->menuPtr; - + Tcl_DStringInit(&ds); Tcl_DStringAppend(&ds, Tk_PathName(menuPtr->masterMenuPtr->tkwin), -1); Tcl_DStringAppend(&ds, ".system", 7); - + menuRefPtr = TkFindMenuReferences(menuPtr->interp, Tcl_DStringValue(&ds)); - + Tcl_DStringFree(&ds); - - if ((menuRefPtr != NULL) + + if ((menuRefPtr != NULL) && (menuRefPtr->menuPtr != NULL) && (menuPtr->parentTopLevelPtr != NULL) && (systemMenuPtr->masterMenuPtr == menuRefPtr->menuPtr)) { - HMENU systemMenuHdl = + HMENU systemMenuHdl = (HMENU) systemMenuPtr->platformData; HWND wrapper = TkWinGetWrapperWindow(menuPtr ->parentTopLevelPtr); @@ -665,12 +652,12 @@ ReconfigureWindowsMenu( DestroyMenu(systemMenuHdl); systemMenuHdl = GetSystemMenu(wrapper, FALSE); systemMenuPtr->menuFlags |= MENU_SYSTEM_MENU; - systemMenuPtr->platformData = - (TkMenuPlatformData) systemMenuHdl; - if (!(systemMenuPtr->menuFlags + systemMenuPtr->platformData = + (TkMenuPlatformData) systemMenuHdl; + if (!(systemMenuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) { - systemMenuPtr->menuFlags - |= MENU_RECONFIGURE_PENDING; + systemMenuPtr->menuFlags + |= MENU_RECONFIGURE_PENDING; Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) systemMenuPtr); } @@ -694,7 +681,7 @@ ReconfigureWindowsMenu( } - if ((menuPtr->menuType == MENUBAR) + if ((menuPtr->menuType == MENUBAR) && (menuPtr->parentTopLevelPtr != NULL)) { HANDLE bar; bar = TkWinGetWrapperWindow(menuPtr->parentTopLevelPtr); @@ -702,7 +689,7 @@ ReconfigureWindowsMenu( DrawMenuBar(bar); } } - + menuPtr->menuFlags &= ~(MENU_RECONFIGURE_PENDING); } @@ -735,8 +722,8 @@ TkpPostMenu(interp, menuPtr, x, y) POINT point; Tk_Window parentWindow = Tk_Parent(menuPtr->tkwin); int oldServiceMode = Tcl_GetServiceMode(); - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); tsdPtr->inPostMenu++; @@ -755,7 +742,7 @@ TkpPostMenu(interp, menuPtr, x, y) * The post commands could have deleted the menu, which means * we are dead and should go away. */ - + if (menuPtr->tkwin == NULL) { tsdPtr->inPostMenu--; return TCL_OK; @@ -776,7 +763,7 @@ TkpPostMenu(interp, menuPtr, x, y) } Tcl_SetServiceMode(TCL_SERVICE_NONE); - + /* * Make an assumption here. If the right button is down, * then we want to track it. Otherwise, track the left mouse button. @@ -797,7 +784,7 @@ TkpPostMenu(interp, menuPtr, x, y) } } - TrackPopupMenu(winMenuHdl, flags, x, y, 0, + TrackPopupMenu(winMenuHdl, flags, x, y, 0, tsdPtr->menuHWND, &noGoawayRect); Tcl_SetServiceMode(oldServiceMode); @@ -843,7 +830,7 @@ TkpMenuNewEntry(mePtr) menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr); } - + mePtr->platformEntryData = (TkMenuPlatformEntryData) commandID; return TCL_OK; @@ -887,11 +874,11 @@ TkWinMenuProc(hwnd, message, wParam, lParam) * * UpdateEmbeddedMenu -- * - * This function is used as work-around for updating the pull-down - * window of an embedded menu which may show as a blank popup window. + * This function is used as work-around for updating the pull-down window + * of an embedded menu which may show as a blank popup window. * * Results: - * Invalidate the client area of the embedded pull-down menu and + * Invalidate the client area of the embedded pull-down menu and * redraw it. * * Side effects: @@ -934,32 +921,37 @@ TkWinEmbeddedMenuProc(hwnd, message, wParam, lParam) { static nIdles = 0; LRESULT lResult = 1; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); switch(message) { - case WM_ENTERIDLE: - if((wParam == MSGF_MENU) && (nIdles < 1) && (hwnd == tsdPtr->embeddedMenuHWND)) { - Tcl_CreateTimerHandler(200, UpdateEmbeddedMenu, (ClientData)lParam); + case WM_ENTERIDLE: + if ((wParam == MSGF_MENU) && (nIdles < 1) + && (hwnd == tsdPtr->embeddedMenuHWND)) { + Tcl_CreateTimerHandler(200, UpdateEmbeddedMenu, + (ClientData) lParam); nIdles++; } break; - - case WM_INITMENUPOPUP: + + case WM_INITMENUPOPUP: nIdles = 0; break; - case WM_INITMENU: - case WM_SYSCOMMAND: - case WM_COMMAND: - case WM_MENUCHAR: - case WM_MEASUREITEM: - case WM_DRAWITEM: - case WM_MENUSELECT: - lResult = TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, &lResult); - if(lResult || (GetCapture() != hwnd)) break; + case WM_INITMENU: + case WM_SYSCOMMAND: + case WM_COMMAND: + case WM_MENUCHAR: + case WM_MEASUREITEM: + case WM_DRAWITEM: + case WM_MENUSELECT: + lResult = TkWinHandleMenuEvent(&hwnd, &message, &wParam, &lParam, + &lResult); + if (lResult || (GetCapture() != hwnd)) { + break; + } - default: + default: lResult = DefWindowProc(hwnd, message, wParam, lParam); break; } @@ -971,17 +963,17 @@ TkWinEmbeddedMenuProc(hwnd, message, wParam, lParam) * * TkWinHandleMenuEvent -- * - * Filters out menu messages from messages passed to a top-level. - * Will respond appropriately to WM_COMMAND, WM_MENUSELECT, - * WM_MEASUREITEM, WM_DRAWITEM + * Filters out menu messages from messages passed to a top-level. Will + * respond appropriately to WM_COMMAND, WM_MENUSELECT, WM_MEASUREITEM, + * WM_DRAWITEM * * Result: * Returns 1 if this handled the message; 0 if it did not. * * Side effects: - * All of the parameters may be modified so that the caller can - * think it is getting a different message. plResult points to - * the result that should be returned to windows from this message. + * All of the parameters may be modified so that the caller can think it + * is getting a different message. plResult points to the result that + * should be returned to windows from this message. * *---------------------------------------------------------------------- */ @@ -998,277 +990,270 @@ TkWinHandleMenuEvent(phwnd, pMessage, pwParam, plParam, plResult) int returnResult = 0; TkMenu *menuPtr; TkMenuEntry *mePtr; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); switch (*pMessage) { - case WM_INITMENU: - TkMenuInit(); - hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, - (char *) *pwParam); - if (hashEntryPtr != NULL) { - tsdPtr->oldServiceMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); - menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); - tsdPtr->modalMenuPtr = menuPtr; - if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) { - Tcl_CancelIdleCall(ReconfigureWindowsMenu, - (ClientData) menuPtr); - ReconfigureWindowsMenu((ClientData) menuPtr); - } - RecursivelyClearActiveMenu(menuPtr); - if (!tsdPtr->inPostMenu) { - Tcl_Interp *interp; - int code; - - interp = menuPtr->interp; - Tcl_Preserve((ClientData)interp); - code = TkPreprocessMenu(menuPtr); - if ((code != TCL_OK) && (code != TCL_CONTINUE) - && (code != TCL_BREAK)) { - Tcl_AddErrorInfo(interp, "\n (menu preprocess)"); - Tcl_BackgroundError(interp); - } - Tcl_Release((ClientData)interp); - } - TkActivateMenuEntry(menuPtr, -1); - *plResult = 0; - returnResult = 1; - } else { - tsdPtr->modalMenuPtr = NULL; - } - break; - - case WM_SYSCOMMAND: - case WM_COMMAND: { - TkMenuInit(); - if (HIWORD(*pwParam) != 0) { - break; - } - hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable, - (char *)LOWORD(*pwParam)); - if (hashEntryPtr == NULL) { - break; + case WM_INITMENU: + TkMenuInit(); + hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, + (char *) *pwParam); + if (hashEntryPtr != NULL) { + tsdPtr->oldServiceMode = Tcl_SetServiceMode(TCL_SERVICE_ALL); + menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); + tsdPtr->modalMenuPtr = menuPtr; + if (menuPtr->menuFlags & MENU_RECONFIGURE_PENDING) { + Tcl_CancelIdleCall(ReconfigureWindowsMenu, + (ClientData) menuPtr); + ReconfigureWindowsMenu((ClientData) menuPtr); } - mePtr = (TkMenuEntry *) Tcl_GetHashValue(hashEntryPtr); - if (mePtr != NULL) { - TkMenuReferences *menuRefPtr; - TkMenuEntry *parentEntryPtr; + RecursivelyClearActiveMenu(menuPtr); + if (!tsdPtr->inPostMenu) { Tcl_Interp *interp; int code; - /* - * We have to set the parent of this menu to be active - * if this is a submenu so that tearoffs will get the - * correct title. - */ - - menuPtr = mePtr->menuPtr; - menuRefPtr = TkFindMenuReferences(menuPtr->interp, - Tk_PathName(menuPtr->tkwin)); - if ((menuRefPtr != NULL) - && (menuRefPtr->parentEntryPtr != NULL)) { - char *name; - - for (parentEntryPtr = menuRefPtr->parentEntryPtr; - ; - parentEntryPtr = - parentEntryPtr->nextCascadePtr) { - name = Tcl_GetStringFromObj( - parentEntryPtr->namePtr, NULL); - if (strcmp(name, Tk_PathName(menuPtr->tkwin)) - == 0) { - break; - } - } - if (parentEntryPtr->menuPtr->entries[parentEntryPtr->index] - ->state != ENTRY_DISABLED) { - TkActivateMenuEntry(parentEntryPtr->menuPtr, - parentEntryPtr->index); - } - } - interp = menuPtr->interp; Tcl_Preserve((ClientData)interp); - code = TkInvokeMenu(interp, menuPtr, mePtr->index); - if (code != TCL_OK && code != TCL_CONTINUE - && code != TCL_BREAK) { - Tcl_AddErrorInfo(interp, "\n (menu invoke)"); + code = TkPreprocessMenu(menuPtr); + if ((code != TCL_OK) && (code != TCL_CONTINUE) + && (code != TCL_BREAK)) { + Tcl_AddErrorInfo(interp, "\n (menu preprocess)"); Tcl_BackgroundError(interp); } Tcl_Release((ClientData)interp); - *plResult = 0; - returnResult = 1; } + TkActivateMenuEntry(menuPtr, -1); + *plResult = 0; + returnResult = 1; + } else { + tsdPtr->modalMenuPtr = NULL; + } + break; + + case WM_SYSCOMMAND: + case WM_COMMAND: + TkMenuInit(); + if (HIWORD(*pwParam) != 0) { + break; + } + hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable, + (char *) LOWORD(*pwParam)); + if (hashEntryPtr == NULL) { break; } + mePtr = (TkMenuEntry *) Tcl_GetHashValue(hashEntryPtr); + if (mePtr != NULL) { + TkMenuReferences *menuRefPtr; + TkMenuEntry *parentEntryPtr; + Tcl_Interp *interp; + int code; - case WM_MENUCHAR: { - unsigned char menuChar = (unsigned char) LOWORD(*pwParam); - hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, - (char *) *plParam); - if (hashEntryPtr != NULL) { - int i; + /* + * We have to set the parent of this menu to be active if this is + * a submenu so that tearoffs will get the correct title. + */ - *plResult = 0; - menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); - for (i = 0; i < menuPtr->numEntries; i++) { - int underline; - char *label; - - underline = menuPtr->entries[i]->underline; - if (menuPtr->entries[i]->labelPtr != NULL) { - label = Tcl_GetStringFromObj( - menuPtr->entries[i]->labelPtr, NULL); - } - if ((-1 != underline) - && (NULL != menuPtr->entries[i]->labelPtr) - && (CharUpper((LPTSTR) menuChar) - == CharUpper((LPTSTR) (unsigned char) - label[underline]))) { - *plResult = (2 << 16) | i; - returnResult = 1; + menuPtr = mePtr->menuPtr; + menuRefPtr = TkFindMenuReferences(menuPtr->interp, + Tk_PathName(menuPtr->tkwin)); + if ((menuRefPtr != NULL) && (menuRefPtr->parentEntryPtr != NULL)) { + for (parentEntryPtr = menuRefPtr->parentEntryPtr ; ; + parentEntryPtr = parentEntryPtr->nextCascadePtr) { + char *name = Tcl_GetString(parentEntryPtr->namePtr); + + if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) { break; } } + if (parentEntryPtr->menuPtr->entries[parentEntryPtr->index] + ->state != ENTRY_DISABLED) { + TkActivateMenuEntry(parentEntryPtr->menuPtr, + parentEntryPtr->index); + } } - break; + + interp = menuPtr->interp; + Tcl_Preserve((ClientData)interp); + code = TkInvokeMenu(interp, menuPtr, mePtr->index); + if (code != TCL_OK && code != TCL_CONTINUE && code != TCL_BREAK) { + Tcl_AddErrorInfo(interp, "\n (menu invoke)"); + Tcl_BackgroundError(interp); + } + Tcl_Release((ClientData)interp); + *plResult = 0; + returnResult = 1; } + break; - case WM_MEASUREITEM: { - LPMEASUREITEMSTRUCT itemPtr = (LPMEASUREITEMSTRUCT) *plParam; - - if (itemPtr != NULL && tsdPtr->modalMenuPtr != NULL) { - mePtr = (TkMenuEntry *) itemPtr->itemData; - menuPtr = mePtr->menuPtr; - - TkRecomputeMenu(menuPtr); - itemPtr->itemHeight = mePtr->height; - itemPtr->itemWidth = mePtr->width; - if (mePtr->hideMargin) { - itemPtr->itemWidth += 2 - indicatorDimensions[1]; - } else { - int activeBorderWidth; - - Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin, - menuPtr->activeBorderWidthPtr, - &activeBorderWidth); - itemPtr->itemWidth += 2 * activeBorderWidth; + case WM_MENUCHAR: { + unsigned char menuChar = (unsigned char) LOWORD(*pwParam); + + hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, + (char *) *plParam); + if (hashEntryPtr != NULL) { + int i; + + *plResult = 0; + menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); + for (i = 0; i < menuPtr->numEntries; i++) { + int underline; + char *label; + + underline = menuPtr->entries[i]->underline; + if (menuPtr->entries[i]->labelPtr != NULL) { + label = Tcl_GetString(menuPtr->entries[i]->labelPtr); + } + if ((-1 != underline) + && (NULL != menuPtr->entries[i]->labelPtr) + && (CharUpper((LPTSTR) menuChar) + == CharUpper((LPTSTR) UCHAR(label[underline])))) { + *plResult = (2 << 16) | i; + returnResult = 1; + break; } - *plResult = 1; - returnResult = 1; } - break; } - - case WM_DRAWITEM: { - TkWinDrawable *twdPtr; - LPDRAWITEMSTRUCT itemPtr = (LPDRAWITEMSTRUCT) *plParam; - Tk_FontMetrics fontMetrics; - int drawArrow = 0; - - if (itemPtr != NULL && tsdPtr->modalMenuPtr != NULL) { - Tk_Font tkfont; - - mePtr = (TkMenuEntry *) itemPtr->itemData; - menuPtr = mePtr->menuPtr; - twdPtr = (TkWinDrawable *) ckalloc(sizeof(TkWinDrawable)); - twdPtr->type = TWD_WINDC; - twdPtr->winDC.hdc = itemPtr->hDC; + break; + } - if (mePtr->state != ENTRY_DISABLED) { - if (itemPtr->itemState & ODS_SELECTED) { - TkActivateMenuEntry(menuPtr, mePtr->index); - } else { - TkActivateMenuEntry(menuPtr, -1); - } - } else { - /* On windows, menu entries should highlight even if they - ** are disabled. (I know this seems dumb, but it is the way - ** native windows menus works so we ought to mimic it.) - ** The ENTRY_PLATFORM_FLAG1 flag will indicate that the - ** entry should be highlighted even though it is disabled. - */ - if (itemPtr->itemState & ODS_SELECTED) { - mePtr->entryFlags |= ENTRY_PLATFORM_FLAG1; - } else { - mePtr->entryFlags &= ~ENTRY_PLATFORM_FLAG1; - } - /* Also, set the drawArrow flag for a disabled cascade - ** menu since we need to draw the arrow ourselves. - */ - if (mePtr->type == CASCADE_ENTRY) { - drawArrow = 1; - } - } + case WM_MEASUREITEM: { + LPMEASUREITEMSTRUCT itemPtr = (LPMEASUREITEMSTRUCT) *plParam; - tkfont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); - Tk_GetFontMetrics(tkfont, &fontMetrics); - TkpDrawMenuEntry(mePtr, (Drawable) twdPtr, tkfont, - &fontMetrics, itemPtr->rcItem.left, - itemPtr->rcItem.top, itemPtr->rcItem.right - - itemPtr->rcItem.left, itemPtr->rcItem.bottom - - itemPtr->rcItem.top, 0, drawArrow); + if (itemPtr != NULL && tsdPtr->modalMenuPtr != NULL) { + mePtr = (TkMenuEntry *) itemPtr->itemData; + menuPtr = mePtr->menuPtr; - ckfree((char *) twdPtr); + TkRecomputeMenu(menuPtr); + itemPtr->itemHeight = mePtr->height; + itemPtr->itemWidth = mePtr->width; + if (mePtr->hideMargin) { + itemPtr->itemWidth += 2 - indicatorDimensions[1]; + } else { + int activeBorderWidth; + + Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin, + menuPtr->activeBorderWidthPtr, &activeBorderWidth); + itemPtr->itemWidth += 2 * activeBorderWidth; } - *plResult = 1; + *plResult = 1; returnResult = 1; - break; } + break; + } + + case WM_DRAWITEM: { + TkWinDrawable *twdPtr; + LPDRAWITEMSTRUCT itemPtr = (LPDRAWITEMSTRUCT) *plParam; + Tk_FontMetrics fontMetrics; + int drawArrow = 0; - case WM_MENUSELECT: { - UINT flags = HIWORD(*pwParam); + if (itemPtr != NULL && tsdPtr->modalMenuPtr != NULL) { + Tk_Font tkfont; - TkMenuInit(); + mePtr = (TkMenuEntry *) itemPtr->itemData; + menuPtr = mePtr->menuPtr; + twdPtr = (TkWinDrawable *) ckalloc(sizeof(TkWinDrawable)); + twdPtr->type = TWD_WINDC; + twdPtr->winDC.hdc = itemPtr->hDC; - if ((flags == 0xFFFF) && (*plParam == 0)) { - if (tsdPtr->modalMenuPtr != NULL) { - Tcl_SetServiceMode(tsdPtr->oldServiceMode); - RecursivelyClearActiveMenu(tsdPtr->modalMenuPtr); + if (mePtr->state != ENTRY_DISABLED) { + if (itemPtr->itemState & ODS_SELECTED) { + TkActivateMenuEntry(menuPtr, mePtr->index); + } else { + TkActivateMenuEntry(menuPtr, -1); } } else { - menuPtr = NULL; - if (*plParam != 0) { - hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, - (char *) *plParam); - if (hashEntryPtr != NULL) { - menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); - } + /* + * On windows, menu entries should highlight even if they are + * disabled. (I know this seems dumb, but it is the way native + * windows menus works so we ought to mimic it.) The + * ENTRY_PLATFORM_FLAG1 flag will indicate that the entry + * should be highlighted even though it is disabled. + */ + + if (itemPtr->itemState & ODS_SELECTED) { + mePtr->entryFlags |= ENTRY_PLATFORM_FLAG1; + } else { + mePtr->entryFlags &= ~ENTRY_PLATFORM_FLAG1; } - if (menuPtr != NULL) { - long entryIndex = LOWORD(*pwParam); - mePtr = NULL; - if (flags != 0xFFFF) { - if ((flags & MF_POPUP) && (entryIndex < menuPtr->numEntries)) { - mePtr = menuPtr->entries[entryIndex]; - } else { - hashEntryPtr = Tcl_FindHashEntry( - &tsdPtr->commandTable, - (char *) entryIndex); - if (hashEntryPtr != NULL) { - mePtr = (TkMenuEntry *) - Tcl_GetHashValue(hashEntryPtr); - } - } - } + /* + * Also, set the drawArrow flag for a disabled cascade menu + * since we need to draw the arrow ourselves. + */ + + if (mePtr->type == CASCADE_ENTRY) { + drawArrow = 1; + } + } + + tkfont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); + Tk_GetFontMetrics(tkfont, &fontMetrics); + TkpDrawMenuEntry(mePtr, (Drawable) twdPtr, tkfont, &fontMetrics, + itemPtr->rcItem.left, itemPtr->rcItem.top, + itemPtr->rcItem.right - itemPtr->rcItem.left, + itemPtr->rcItem.bottom - itemPtr->rcItem.top, 0,drawArrow); + + ckfree((char *) twdPtr); + } + *plResult = 1; + returnResult = 1; + break; + } + + case WM_MENUSELECT: { + UINT flags = HIWORD(*pwParam); + + TkMenuInit(); - if ((mePtr == NULL) || (mePtr->state == ENTRY_DISABLED)) { - TkActivateMenuEntry(menuPtr, -1); + if ((flags == 0xFFFF) && (*plParam == 0)) { + if (tsdPtr->modalMenuPtr != NULL) { + Tcl_SetServiceMode(tsdPtr->oldServiceMode); + RecursivelyClearActiveMenu(tsdPtr->modalMenuPtr); + } + } else { + menuPtr = NULL; + if (*plParam != 0) { + hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, + (char *) *plParam); + if (hashEntryPtr != NULL) { + menuPtr = (TkMenu *) Tcl_GetHashValue(hashEntryPtr); + } + } + + if (menuPtr != NULL) { + long entryIndex = LOWORD(*pwParam); + + mePtr = NULL; + if (flags != 0xFFFF) { + if ((flags&MF_POPUP) && (entryIndex<menuPtr->numEntries)) { + mePtr = menuPtr->entries[entryIndex]; } else { - if (mePtr->index >= menuPtr->numEntries) { - Tcl_Panic("Trying to activate an entry which doesn't exist."); + hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->commandTable, + (char *) entryIndex); + if (hashEntryPtr != NULL) { + mePtr = (TkMenuEntry *) + Tcl_GetHashValue(hashEntryPtr); } - TkActivateMenuEntry(menuPtr, mePtr->index); } - MenuSelectEvent(menuPtr); - Tcl_ServiceAll(); - *plResult = 0; - returnResult = 1; } + + if ((mePtr == NULL) || (mePtr->state == ENTRY_DISABLED)) { + TkActivateMenuEntry(menuPtr, -1); + } else { + if (mePtr->index >= menuPtr->numEntries) { + Tcl_Panic("Trying to activate an entry which doesn't exist."); + } + TkActivateMenuEntry(menuPtr, mePtr->index); + } + MenuSelectEvent(menuPtr); + Tcl_ServiceAll(); + *plResult = 0; + returnResult = 1; } - break; } + break; + } } return returnResult; } @@ -1295,7 +1280,7 @@ RecursivelyClearActiveMenu( { int i; TkMenuEntry *mePtr; - + TkActivateMenuEntry(menuPtr, -1); MenuSelectEvent(menuPtr); for (i = 0; i < menuPtr->numEntries; i++) { @@ -1332,25 +1317,26 @@ RecursivelyClearActiveMenu( void TkpSetWindowMenuBar(tkwin, menuPtr) - Tk_Window tkwin; /* The window we are putting the menubar into.*/ - TkMenu *menuPtr; /* The menu we are inserting */ + Tk_Window tkwin; /* The window we are putting the menubar + * into.*/ + TkMenu *menuPtr; /* The menu we are inserting */ { HMENU winMenuHdl; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (menuPtr != NULL) { Tcl_HashEntry *hashEntryPtr; int newEntry; winMenuHdl = (HMENU) menuPtr->platformData; - hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, - (char *) winMenuHdl); + hashEntryPtr = Tcl_FindHashEntry(&tsdPtr->winMenuTable, + (char *) winMenuHdl); Tcl_DeleteHashEntry(hashEntryPtr); DestroyMenu(winMenuHdl); winMenuHdl = CreateMenu(); - hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable, - (char *) winMenuHdl, &newEntry); + hashEntryPtr = Tcl_CreateHashEntry(&tsdPtr->winMenuTable, + (char *) winMenuHdl, &newEntry); Tcl_SetHashValue(hashEntryPtr, (char *) menuPtr); menuPtr->platformData = (TkMenuPlatformData) winMenuHdl; TkWinSetMenu(tkwin, winMenuHdl); @@ -1368,8 +1354,8 @@ TkpSetWindowMenuBar(tkwin, menuPtr) * * TkpSetMainMenubar -- * - * Puts the menu associated with a window into the menubar. Should - * only be called when the window is in front. + * Puts the menu associated with a window into the menubar. Should only + * be called when the window is in front. * * Results: * None. @@ -1379,13 +1365,13 @@ TkpSetWindowMenuBar(tkwin, menuPtr) * *---------------------------------------------------------------------- */ + void TkpSetMainMenubar( Tcl_Interp *interp, /* The interpreter of the application */ Tk_Window tkwin, /* The frame we are setting up */ - char *menuName) /* The name of the menu to put in front. - * If NULL, use the default menu bar. - */ + char *menuName) /* The name of the menu to put in front. If + * NULL, use the default menu bar. */ { /* * Nothing to do. @@ -1410,12 +1396,12 @@ TkpSetMainMenubar( void GetMenuIndicatorGeometry ( - TkMenu *menuPtr, /* The menu we are measuring */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* Precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* Precalculated font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ + TkMenu *menuPtr, /* The menu we are measuring */ + TkMenuEntry *mePtr, /* The entry we are measuring */ + Tk_Font tkfont, /* Precalculated font */ + CONST Tk_FontMetrics *fmPtr,/* Precalculated font metrics */ + int *widthPtr, /* The resulting width */ + int *heightPtr) /* The resulting height */ { *heightPtr = indicatorDimensions[0]; if (mePtr->hideMargin) { @@ -1447,12 +1433,12 @@ GetMenuIndicatorGeometry ( void GetMenuAccelGeometry ( - TkMenu *menuPtr, /* The menu we are measuring */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ + TkMenu *menuPtr, /* The menu we are measuring */ + TkMenuEntry *mePtr, /* The entry we are measuring */ + Tk_Font tkfont, /* The precalculated font */ + CONST Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ + int *widthPtr, /* The resulting width */ + int *heightPtr) /* The resulting height */ { *heightPtr = fmPtr->linespace; if (mePtr->type == CASCADE_ENTRY) { @@ -1460,7 +1446,8 @@ GetMenuAccelGeometry ( } else if (mePtr->accelPtr == NULL) { *widthPtr = 0; } else { - char *accel = Tcl_GetStringFromObj(mePtr->accelPtr, NULL); + char *accel = Tcl_GetString(mePtr->accelPtr); + *widthPtr = Tk_TextWidth(tkfont, accel, mePtr->accelLength); } } @@ -1483,12 +1470,12 @@ GetMenuAccelGeometry ( void GetTearoffEntryGeometry ( - TkMenu *menuPtr, /* The menu we are measuring */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ + TkMenu *menuPtr, /* The menu we are measuring */ + TkMenuEntry *mePtr, /* The entry we are measuring */ + Tk_Font tkfont, /* The precalculated font */ + CONST Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ + int *widthPtr, /* The resulting width */ + int *heightPtr) /* The resulting height */ { if (menuPtr->menuType != MASTER_MENU) { *heightPtr = 0; @@ -1516,12 +1503,12 @@ GetTearoffEntryGeometry ( void GetMenuSeparatorGeometry ( - TkMenu *menuPtr, /* The menu we are measuring */ - TkMenuEntry *mePtr, /* The entry we are measuring */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalcualted font metrics */ - int *widthPtr, /* The resulting width */ - int *heightPtr) /* The resulting height */ + TkMenu *menuPtr, /* The menu we are measuring */ + TkMenuEntry *mePtr, /* The entry we are measuring */ + Tk_Font tkfont, /* The precalculated font */ + CONST Tk_FontMetrics *fmPtr,/* The precalcualted font metrics */ + int *widthPtr, /* The resulting width */ + int *heightPtr) /* The resulting height */ { *widthPtr = 0; *heightPtr = fmPtr->linespace - (2 * fmPtr->descent); @@ -1532,10 +1519,10 @@ GetMenuSeparatorGeometry ( * * DrawWindowsSystemBitmap -- * - * Draws the windows system bitmap given by bitmapID into the rect - * given by rectPtr in the drawable. The bitmap is centered in the - * rectangle. It is not clipped, so if the bitmap is bigger than - * the rect it will bleed. + * Draws the windows system bitmap given by bitmapID into the rect given + * by rectPtr in the drawable. The bitmap is centered in the rectangle. + * It is not clipped, so if the bitmap is bigger than the rect it will + * bleed. * * Results: * None. @@ -1548,14 +1535,14 @@ GetMenuSeparatorGeometry ( static void DrawWindowsSystemBitmap(display, drawable, gc, rectPtr, bitmapID, alignFlags) - Display *display; /* The display we are drawing into */ - Drawable drawable; /* The drawable we are working with */ - GC gc; /* The GC to draw with */ - CONST RECT *rectPtr; /* The rectangle to draw into */ - int bitmapID; /* The windows id of the system - * bitmap to draw. */ - int alignFlags; /* How to align the bitmap inside the - * rectangle. */ + Display *display; /* The display we are drawing into */ + Drawable drawable; /* The drawable we are working with */ + GC gc; /* The GC to draw with */ + CONST RECT *rectPtr; /* The rectangle to draw into */ + int bitmapID; /* The windows id of the system bitmap to + * draw. */ + int alignFlags; /* How to align the bitmap inside the + * rectangle. */ { TkWinDCState state; HDC hdc = TkWinGetDrawableDC(display, drawable, &state); @@ -1565,7 +1552,7 @@ DrawWindowsSystemBitmap(display, drawable, gc, rectPtr, bitmapID, alignFlags) POINT ptSize; POINT ptOrg; int topOffset, leftOffset; - + SetBkColor(hdc, gc->background); SetTextColor(hdc, gc->foreground); @@ -1597,7 +1584,7 @@ DrawWindowsSystemBitmap(display, drawable, gc, rectPtr, bitmapID, alignFlags) } else { leftOffset = (rectPtr->right - rectPtr->left) / 2 - (ptSize.x / 2); } - + BitBlt(hdc, rectPtr->left + leftOffset, rectPtr->top + topOffset, ptSize.x, ptSize.y, scratchDC, ptOrg.x, ptOrg.y, SRCCOPY); DeleteDC(scratchDC); @@ -1611,38 +1598,39 @@ DrawWindowsSystemBitmap(display, drawable, gc, rectPtr, bitmapID, alignFlags) * * DrawMenuEntryIndicator -- * - * This procedure draws the indicator part of a menu. + * This function draws the indicator part of a menu. * * Results: * None. * * Side effects: - * Commands are output to X to display the menu in its - * current mode. + * Commands are output to X to display the menu in its current mode. * *---------------------------------------------------------------------- */ + void DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, fmPtr, x, y, width, height) - TkMenu *menuPtr; /* The menu we are drawing */ - TkMenuEntry *mePtr; /* The entry we are drawing */ - Drawable d; /* What we are drawing into */ - GC gc; /* The gc we are drawing with */ - GC indicatorGC; /* The gc for indicator objects */ - Tk_Font tkfont; /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr; /* The precalculated font metrics */ - int x; /* Left edge */ - int y; /* Top edge */ + TkMenu *menuPtr; /* The menu we are drawing */ + TkMenuEntry *mePtr; /* The entry we are drawing */ + Drawable d; /* What we are drawing into */ + GC gc; /* The gc we are drawing with */ + GC indicatorGC; /* The gc for indicator objects */ + Tk_Font tkfont; /* The precalculated font */ + CONST Tk_FontMetrics *fmPtr;/* The precalculated font metrics */ + int x; /* Left edge */ + int y; /* Top edge */ int width; int height; { - if ((mePtr->type == CHECK_BUTTON_ENTRY) + if ((mePtr->type == CHECK_BUTTON_ENTRY) || (mePtr->type == RADIO_BUTTON_ENTRY)) { if (mePtr->indicatorOn && (mePtr->entryFlags & ENTRY_SELECTED)) { RECT rect; GC whichGC; int borderWidth, activeBorderWidth; + if (mePtr->state != ENTRY_NORMAL) { whichGC = gc; } else { @@ -1662,21 +1650,21 @@ DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, fmPtr, x, && (menuPtr->disabledFgPtr != NULL)) { RECT hilightRect; COLORREF oldFgColor = whichGC->foreground; - + whichGC->foreground = GetSysColor(COLOR_3DHILIGHT); hilightRect.top = rect.top + 1; hilightRect.bottom = rect.bottom + 1; hilightRect.left = rect.left + 1; hilightRect.right = rect.right + 1; - DrawWindowsSystemBitmap(menuPtr->display, d, whichGC, + DrawWindowsSystemBitmap(menuPtr->display, d, whichGC, &hilightRect, OBM_CHECK, 0); whichGC->foreground = oldFgColor; } - DrawWindowsSystemBitmap(menuPtr->display, d, whichGC, &rect, + DrawWindowsSystemBitmap(menuPtr->display, d, whichGC, &rect, OBM_CHECK, 0); } - } + } } /* @@ -1684,11 +1672,10 @@ DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, fmPtr, x, * * DrawMenuEntryAccelerator -- * - * This procedure draws the accelerator part of a menu. - * For example, the string "CTRL-Z" could be drawn to - * to the right of the label text for an Undo menu entry. - * Need to decide what to draw here. Should we replace strings - * like "Control", "Command", etc? + * This function draws the accelerator part of a menu. For example, the + * string "CTRL-Z" could be drawn to to the right of the label text for + * an Undo menu entry. Need to decide what to draw here. Should we + * replace strings like "Control", "Command", etc? * * Results: * None. @@ -1701,49 +1688,52 @@ DrawMenuEntryIndicator(menuPtr, mePtr, d, gc, indicatorGC, tkfont, fmPtr, x, */ void -DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr, - activeBorder, x, y, width, height) - TkMenu *menuPtr; /* The menu we are drawing */ - TkMenuEntry *mePtr; /* The entry we are drawing */ - Drawable d; /* What we are drawing into */ - GC gc; /* The gc we are drawing with */ - Tk_Font tkfont; /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr; /* The precalculated font metrics */ - Tk_3DBorder activeBorder; /* The border when an item is active */ - int x; /* left edge */ - int y; /* top edge */ - int width; /* Width of menu entry */ - int height; /* Height of menu entry */ +DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr, activeBorder, + x, y, width, height) + TkMenu *menuPtr; /* The menu we are drawing */ + TkMenuEntry *mePtr; /* The entry we are drawing */ + Drawable d; /* What we are drawing into */ + GC gc; /* The gc we are drawing with */ + Tk_Font tkfont; /* The precalculated font */ + CONST Tk_FontMetrics *fmPtr;/* The precalculated font metrics */ + Tk_3DBorder activeBorder; /* The border when an item is active */ + int x; /* left edge */ + int y; /* top edge */ + int width; /* Width of menu entry */ + int height; /* Height of menu entry */ { int baseline; int leftEdge = x + mePtr->indicatorSpace + mePtr->labelWidth; char *accel; - + if (mePtr->accelPtr != NULL) { - accel = Tcl_GetStringFromObj(mePtr->accelPtr, NULL); + accel = Tcl_GetString(mePtr->accelPtr); } baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; - /* Draw disabled 3D text highlight only with the Win95/98 look. */ + /* + * Draw disabled 3D text highlight only with the Win95/98 look. + */ if (TkWinGetPlatformTheme() == TK_THEME_WIN_CLASSIC) { - if ((mePtr->state == ENTRY_DISABLED) && (menuPtr->disabledFgPtr != NULL) - && (mePtr->accelPtr != NULL)) { + if ((mePtr->state == ENTRY_DISABLED) + && (menuPtr->disabledFgPtr != NULL) + && (mePtr->accelPtr != NULL)) { COLORREF oldFgColor = gc->foreground; gc->foreground = GetSysColor(COLOR_3DHILIGHT); if ((mePtr->accelPtr != NULL) && - ((mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) == 0)) { - Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel, - mePtr->accelLength, leftEdge + 1, baseline + 1); + ((mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) == 0)) { + Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel, + mePtr->accelLength, leftEdge + 1, baseline + 1); } gc->foreground = oldFgColor; } } if (mePtr->accelPtr != NULL) { - Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel, + Tk_DrawChars(menuPtr->display, d, gc, tkfont, accel, mePtr->accelLength, leftEdge, baseline); } } @@ -1753,8 +1743,8 @@ DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr, * * DrawMenuEntryArrow -- * - * This function draws the arrow bitmap on the right side of a - * a menu entry. This function is currently unused. + * This function draws the arrow bitmap on the right side of a menu + * entry. This function is currently unused. * * Results: * None. @@ -1766,41 +1756,43 @@ DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr, */ void -DrawMenuEntryArrow(menuPtr, mePtr, d, gc, - activeBorder, x, y, width, height, drawArrow) - TkMenu *menuPtr; /* The menu we are drawing */ - TkMenuEntry *mePtr; /* The entry we are drawing */ - Drawable d; /* What we are drawing into */ - GC gc; /* The gc we are drawing with */ - Tk_3DBorder activeBorder; /* The border when an item is active */ - int x; /* left edge */ - int y; /* top edge */ - int width; /* Width of menu entry */ - int height; /* Height of menu entry */ - int drawArrow; /* For cascade menus, whether of not - * to draw the arraw. I cannot figure - * out Windows' algorithm for where - * to draw this. */ +DrawMenuEntryArrow(menuPtr, mePtr, d, gc, activeBorder, x, y, width, height, + drawArrow) + TkMenu *menuPtr; /* The menu we are drawing */ + TkMenuEntry *mePtr; /* The entry we are drawing */ + Drawable d; /* What we are drawing into */ + GC gc; /* The gc we are drawing with */ + Tk_3DBorder activeBorder; /* The border when an item is active */ + int x; /* left edge */ + int y; /* top edge */ + int width; /* Width of menu entry */ + int height; /* Height of menu entry */ + int drawArrow; /* For cascade menus, whether of not to draw + * the arraw. I cannot figure out Windows' + * algorithm for where to draw this. */ { COLORREF oldFgColor; COLORREF oldBgColor; RECT rect; - if (!drawArrow || (mePtr->type != CASCADE_ENTRY) || - (mePtr->state != ENTRY_DISABLED)) - return; + if (!drawArrow || (mePtr->type != CASCADE_ENTRY) + || (mePtr->state != ENTRY_DISABLED)) { + return; + } oldFgColor = gc->foreground; oldBgColor = gc->background; - /* Set bitmap bg to highlight color if the menu is highlighted */ + /* + * Set bitmap bg to highlight color if the menu is highlighted. + */ + if (mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) { - XColor *activeBgColor = Tk_3DBorderColor(Tk_Get3DBorderFromObj( - mePtr->menuPtr->tkwin, - (mePtr->activeBorderPtr == NULL) ? - mePtr->menuPtr->activeBorderPtr : - mePtr->activeBorderPtr)); - gc->background = activeBgColor->pixel; + XColor *activeBgColor = Tk_3DBorderColor(Tk_Get3DBorderFromObj( + mePtr->menuPtr->tkwin, (mePtr->activeBorderPtr == NULL) + ? mePtr->menuPtr->activeBorderPtr + : mePtr->activeBorderPtr)); + gc->background = activeBgColor->pixel; } gc->foreground = GetSysColor(COLOR_GRAYTEXT); @@ -1811,7 +1803,7 @@ DrawMenuEntryArrow(menuPtr, mePtr, d, gc, rect.right = x + width; DrawWindowsSystemBitmap(menuPtr->display, d, gc, &rect, OBM_MNARROW, - ALIGN_BITMAP_RIGHT); + ALIGN_BITMAP_RIGHT); gc->foreground = oldFgColor; gc->background = oldBgColor; @@ -1829,23 +1821,23 @@ DrawMenuEntryArrow(menuPtr, mePtr, d, gc, * None. * * Side effects: - * Commands are output to X to display the menu in its - * current mode. + * Commands are output to X to display the menu in its current mode. * *---------------------------------------------------------------------- */ + void DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height) - TkMenu *menuPtr; /* The menu we are drawing */ - TkMenuEntry *mePtr; /* The entry we are drawing */ - Drawable d; /* What we are drawing into */ - GC gc; /* The gc we are drawing with */ - Tk_Font tkfont; /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr; /* The precalculated font metrics */ - int x; /* left edge */ - int y; /* top edge */ - int width; /* width of item */ - int height; /* height of item */ + TkMenu *menuPtr; /* The menu we are drawing */ + TkMenuEntry *mePtr; /* The entry we are drawing */ + Drawable d; /* What we are drawing into */ + GC gc; /* The gc we are drawing with */ + Tk_Font tkfont; /* The precalculated font */ + CONST Tk_FontMetrics *fmPtr;/* The precalculated font metrics */ + int x; /* left edge */ + int y; /* top edge */ + int width; /* width of item */ + int height; /* height of item */ { XPoint points[2]; Tk_3DBorder border; @@ -1855,7 +1847,7 @@ DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height) points[1].x = x + width - 1; points[1].y = points[0].y; border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); - Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1, + Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1, TK_RELIEF_RAISED); } @@ -1864,41 +1856,40 @@ DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height) * * DrawMenuUnderline -- * - * On appropriate platforms, draw the underline character for the - * menu. + * On appropriate platforms, draw the underline character for the menu. * * Results: * None. * * Side effects: - * Commands are output to X to display the menu in its - * current mode. + * Commands are output to X to display the menu in its current mode. * *---------------------------------------------------------------------- */ + static void DrawMenuUnderline( - TkMenu *menuPtr, /* The menu to draw into */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* What we are drawing into */ - GC gc, /* The gc to draw into */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int x, /* Left Edge */ - int y, /* Top Edge */ - int width, /* Width of entry */ - int height) /* Height of entry */ + TkMenu *menuPtr, /* The menu to draw into */ + TkMenuEntry *mePtr, /* The entry we are drawing */ + Drawable d, /* What we are drawing into */ + GC gc, /* The gc to draw into */ + Tk_Font tkfont, /* The precalculated font */ + CONST Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ + int x, /* Left Edge */ + int y, /* Top Edge */ + int width, /* Width of entry */ + int height) /* Height of entry */ { if (mePtr->underline >= 0) { - char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL); + char *label = Tcl_GetString(mePtr->labelPtr); CONST char *start = Tcl_UtfAtIndex(label, mePtr->underline); CONST char *end = Tcl_UtfNext(start); Tk_UnderlineChars(menuPtr->display, d, gc, tkfont, label, x + mePtr->indicatorSpace, - y + (height + fmPtr->ascent - fmPtr->descent) / 2, + y + (height + fmPtr->ascent - fmPtr->descent) / 2, (int) (start - label), (int) (end - label)); - } + } } /* @@ -1906,17 +1897,16 @@ DrawMenuUnderline( * * TkWinMenuKeyObjCmd -- * - * This procedure is invoked when keys related to pulling - * down menus is pressed. The corresponding Windows events - * are generated and passed to DefWindowProc if appropriate. - * This cmd is registered as tk::WinMenuKey in the interp. + * This function is invoked when keys related to pulling down menus is + * pressed. The corresponding Windows events are generated and passed to + * DefWindowProc if appropriate. This cmd is registered as tk::WinMenuKey + * in the interp. * * Results: * Always returns TCL_OK. * * Side effects: - * The menu system may take over and process user events - * for menu input. + * The menu system may take over and process user events for menu input. * *-------------------------------------------------------------- */ @@ -1948,13 +1938,13 @@ TkWinMenuKeyObjCmd(clientData, interp, objc, objv) Tk_MainWindow(interp)); if (tkwin == NULL) { - return TCL_ERROR; + return TCL_ERROR; } winPtr = (TkWindow *)tkwin; if (Tcl_GetIntFromObj(interp, objv[2], &i) != TCL_OK) { - return TCL_ERROR; + return TCL_ERROR; } keySym = i; @@ -1963,8 +1953,7 @@ TkWinMenuKeyObjCmd(clientData, interp, objc, objv) case XK_Alt_L: scanCode = MapVirtualKey(VK_LMENU, 0); CallWindowProc(DefWindowProc, Tk_GetHWND(Tk_WindowId(tkwin)), - WM_SYSKEYDOWN, VK_MENU, (scanCode << 16) - | (1 << 29)); + WM_SYSKEYDOWN, VK_MENU, (scanCode << 16) | (1 << 29)); break; case XK_Alt_R: scanCode = MapVirtualKey(VK_RMENU, 0); @@ -1987,8 +1976,7 @@ TkWinMenuKeyObjCmd(clientData, interp, objc, objv) if (eventPtr->xkey.nbytes > 0) { for (i = 0; i < eventPtr->xkey.nbytes; i++) { CallWindowProc(DefWindowProc, - Tk_GetHWND(Tk_WindowId(tkwin)), - WM_SYSCHAR, + Tk_GetHWND(Tk_WindowId(tkwin)), WM_SYSCHAR, eventPtr->xkey.trans_chars[i], ((scanCode << 16) | (1 << 29))); } @@ -2033,86 +2021,63 @@ TkWinMenuKeyObjCmd(clientData, interp, objc, objv) * * TkpInitializeMenuBindings -- * - * For every interp, initializes the bindings for Windows - * menus. Does nothing on Mac or XWindows. + * For every interp, initializes the bindings for Windows menus. Does + * nothing on Mac or XWindows. * * Results: * None. * * Side effects: - * bindings are setup for the interp which will - * handle Alt-key sequences for menus without beeping - * or interfering with user-defined Alt-key bindings. + * bindings are setup for the interp which will handle Alt-key sequences + * for menus without beeping or interfering with user-defined Alt-key + * bindings. * *-------------------------------------------------------------- */ void TkpInitializeMenuBindings(interp, bindingTable) - Tcl_Interp *interp; /* The interpreter to set. */ - Tk_BindingTable bindingTable; /* The table to add to. */ + Tcl_Interp *interp; /* The interpreter to set. */ + Tk_BindingTable bindingTable; + /* The table to add to. */ { Tk_Uid uid = Tk_GetUid("all"); /* - * We need to set up the bindings for menubars. These have to - * recreate windows events, so we need to invoke C code to - * generate the WM_SYSKEYDOWNS and WM_SYSKEYUPs appropriately. - * Trick is, we can't create a C level binding directly since - * we may want to modify the binding in Tcl code. + * We need to set up the bindings for menubars. These have to recreate + * windows events, so we need to invoke C code to generate the + * WM_SYSKEYDOWNS and WM_SYSKEYUPs appropriately. Trick is, we can't + * create a C level binding directly since we may want to modify the + * binding in Tcl code. */ (void) Tcl_CreateObjCommand(interp, "tk::WinMenuKey", TkWinMenuKeyObjCmd, (ClientData) Tk_MainWindow(interp), (Tcl_CmdDeleteProc *) NULL); - (void) Tk_CreateBinding(interp, bindingTable, - (ClientData) uid, - "<Alt_L>", - "tk::WinMenuKey %W %N", - 0); - - (void) Tk_CreateBinding(interp, bindingTable, - (ClientData) uid, - "<KeyRelease-Alt_L>", - "tk::WinMenuKey %W %N", - 0); - - (void) Tk_CreateBinding(interp, bindingTable, - (ClientData) uid, - "<Alt_R>", - "tk::WinMenuKey %W %N", - 0); - - (void) Tk_CreateBinding(interp, bindingTable, - (ClientData) uid, - "<KeyRelease-Alt_R>", - "tk::WinMenuKey %W %N", - 0); - - (void) Tk_CreateBinding(interp, bindingTable, - (ClientData) uid, - "<Alt-KeyPress>", - "tk::WinMenuKey %W %N", - 0); - - (void) Tk_CreateBinding(interp, bindingTable, - (ClientData) uid, - "<Alt-KeyRelease>", - "tk::WinMenuKey %W %N", - 0); - - (void) Tk_CreateBinding(interp, bindingTable, - (ClientData) uid, - "<KeyPress-F10>", - "tk::WinMenuKey %W %N", - 0); - - (void) Tk_CreateBinding(interp, bindingTable, - (ClientData) uid, - "<KeyRelease-F10>", - "tk::WinMenuKey %W %N", - 0); + (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, + "<Alt_L>", "tk::WinMenuKey %W %N", 0); + + (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, + "<KeyRelease-Alt_L>", "tk::WinMenuKey %W %N", 0); + + (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, + "<Alt_R>", "tk::WinMenuKey %W %N", 0); + + (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, + "<KeyRelease-Alt_R>", "tk::WinMenuKey %W %N", 0); + + (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, + "<Alt-KeyPress>", "tk::WinMenuKey %W %N", 0); + + (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, + "<Alt-KeyRelease>", "tk::WinMenuKey %W %N", 0); + + (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, + "<KeyPress-F10>", "tk::WinMenuKey %W %N", 0); + + (void) Tk_CreateBinding(interp, bindingTable, (ClientData) uid, + "<KeyRelease-F10>", "tk::WinMenuKey %W %N", 0); } /* @@ -2120,7 +2085,7 @@ TkpInitializeMenuBindings(interp, bindingTable) * * DrawMenuEntryLabel -- * - * This procedure draws the label part of a menu. + * This function draws the label part of a menu. * * Results: * None. @@ -2131,20 +2096,21 @@ TkpInitializeMenuBindings(interp, bindingTable) * *---------------------------------------------------------------------- */ + static void DrawMenuEntryLabel( - TkMenu *menuPtr, /* The menu we are drawing */ - TkMenuEntry *mePtr, /* The entry we are drawing */ - Drawable d, /* What we are drawing into */ - GC gc, /* The gc we are drawing into */ - Tk_Font tkfont, /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr, /* The precalculated font metrics */ - int x, /* left edge */ - int y, /* right edge */ - int width, /* width of entry */ - int height) /* height of entry */ + TkMenu *menuPtr, /* The menu we are drawing */ + TkMenuEntry *mePtr, /* The entry we are drawing */ + Drawable d, /* What we are drawing into */ + GC gc, /* The gc we are drawing into */ + Tk_Font tkfont, /* The precalculated font */ + CONST Tk_FontMetrics *fmPtr,/* The precalculated font metrics */ + int x, /* left edge */ + int y, /* right edge */ + int width, /* width of entry */ + int height) /* height of entry */ { - int indicatorSpace = mePtr->indicatorSpace; + int indicatorSpace = mePtr->indicatorSpace; int activeBorderWidth; int leftEdge; int imageHeight, imageWidth; @@ -2163,21 +2129,22 @@ DrawMenuEntryLabel( if (mePtr->image != NULL) { Tk_SizeOfImage(mePtr->image, &imageWidth, &imageHeight); - haveImage = 1; + haveImage = 1; } else if (mePtr->bitmapPtr != NULL) { Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); Tk_SizeOfBitmap(menuPtr->display, bitmap, &imageWidth, &imageHeight); haveImage = 1; } if (!haveImage || (mePtr->compound != COMPOUND_NONE)) { - if (mePtr->labelLength > 0) { - char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL); + if (mePtr->labelLength > 0) { + char *label = Tcl_GetString(mePtr->labelPtr); + textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength); textHeight = fmPtr->linespace; haveText = 1; - } + } } - + /* * Now work out what the relative positions are. */ @@ -2185,56 +2152,53 @@ DrawMenuEntryLabel( if (haveImage && haveText) { int fullWidth = (imageWidth > textWidth ? imageWidth : textWidth); switch ((enum compound) mePtr->compound) { - case COMPOUND_TOP: { - textXOffset = (fullWidth - textWidth)/2; - textYOffset = imageHeight/2 + 2; - imageXOffset = (fullWidth - imageWidth)/2; - imageYOffset = -textHeight/2; - break; - } - case COMPOUND_BOTTOM: { - textXOffset = (fullWidth - textWidth)/2; - textYOffset = -imageHeight/2; - imageXOffset = (fullWidth - imageWidth)/2; - imageYOffset = textHeight/2 + 2; - break; - } - case COMPOUND_LEFT: { - /* - * The standard image position on Windows is in the indicator - * space to the left of the entries, unless this entry is a - * radio|check button because then the indicator space will - * be used. - */ - textXOffset = imageWidth + 2; - textYOffset = 0; - imageXOffset = 0; - imageYOffset = 0; - if ((mePtr->type != CHECK_BUTTON_ENTRY) - && (mePtr->type != RADIO_BUTTON_ENTRY)) { - textXOffset -= indicatorSpace; - if (textXOffset < 0) { - textXOffset = 0; - } - imageXOffset = -indicatorSpace; + case COMPOUND_TOP: + textXOffset = (fullWidth - textWidth)/2; + textYOffset = imageHeight/2 + 2; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = -textHeight/2; + break; + case COMPOUND_BOTTOM: + textXOffset = (fullWidth - textWidth)/2; + textYOffset = -imageHeight/2; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = textHeight/2 + 2; + break; + case COMPOUND_LEFT: + /* + * The standard image position on Windows is in the indicator + * space to the left of the entries, unless this entry is a + * radio|check button because then the indicator space will be + * used. + */ + + textXOffset = imageWidth + 2; + textYOffset = 0; + imageXOffset = 0; + imageYOffset = 0; + if ((mePtr->type != CHECK_BUTTON_ENTRY) + && (mePtr->type != RADIO_BUTTON_ENTRY)) { + textXOffset -= indicatorSpace; + if (textXOffset < 0) { + textXOffset = 0; } - break; - } - case COMPOUND_RIGHT: { - textXOffset = 0; - textYOffset = 0; - imageXOffset = textWidth + 2; - imageYOffset = 0; - break; - } - case COMPOUND_CENTER: { - textXOffset = (fullWidth - textWidth)/2; - textYOffset = 0; - imageXOffset = (fullWidth - imageWidth)/2; - imageYOffset = 0; - break; + imageXOffset = -indicatorSpace; } - case COMPOUND_NONE: {break;} + break; + case COMPOUND_RIGHT: + textXOffset = 0; + textYOffset = 0; + imageXOffset = textWidth + 2; + imageYOffset = 0; + break; + case COMPOUND_CENTER: + textXOffset = (fullWidth - textWidth)/2; + textYOffset = 0; + imageXOffset = (fullWidth - imageWidth)/2; + imageYOffset = 0; + break; + case COMPOUND_NONE: + break; } } else { textXOffset = 0; @@ -2242,7 +2206,7 @@ DrawMenuEntryLabel( imageXOffset = 0; imageYOffset = 0; } - + /* * Draw label and/or bitmap or image for entry. */ @@ -2252,42 +2216,45 @@ DrawMenuEntryLabel( && (mePtr->entryFlags & ENTRY_SELECTED)) { Tk_RedrawImage(mePtr->selectImage, 0, 0, imageWidth, imageHeight, d, leftEdge + imageXOffset, - (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset)); + (int) (y + (mePtr->height-imageHeight)/2 + imageYOffset)); } else { Tk_RedrawImage(mePtr->image, 0, 0, imageWidth, imageHeight, d, leftEdge + imageXOffset, - (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset)); + (int) (y + (mePtr->height-imageHeight)/2 + imageYOffset)); } } else if (mePtr->bitmapPtr != NULL) { Pixmap bitmap = Tk_GetBitmapFromObj(menuPtr->tkwin, mePtr->bitmapPtr); - XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0, - (unsigned) imageWidth, (unsigned) imageHeight, + XCopyPlane(menuPtr->display, bitmap, d, gc, 0, 0, + (unsigned) imageWidth, (unsigned) imageHeight, leftEdge + imageXOffset, (int) (y + (mePtr->height - imageHeight)/2 + imageYOffset), 1); } if ((mePtr->compound != COMPOUND_NONE) || !haveImage) { if (mePtr->labelLength > 0) { int baseline = y + (height + fmPtr->ascent - fmPtr->descent) / 2; - char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL); + char *label = Tcl_GetString(mePtr->labelPtr); + if (TkWinGetPlatformTheme() == TK_THEME_WIN_CLASSIC) { - /* Win 95/98 systems draw disabled menu text with a - * 3D highlight, unless the menu item is highlighted */ - if ((mePtr->state == ENTRY_DISABLED) && - ((mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) == 0)) { - COLORREF oldFgColor = gc->foreground; + /* + * Win 95/98 systems draw disabled menu text with a 3D + * highlight, unless the menu item is highlighted, + */ + + if ((mePtr->state == ENTRY_DISABLED) && + ((mePtr->entryFlags & ENTRY_PLATFORM_FLAG1) == 0)) { + COLORREF oldFgColor = gc->foreground; gc->foreground = GetSysColor(COLOR_3DHILIGHT); - Tk_DrawChars(menuPtr->display, d, gc, tkfont, label, - mePtr->labelLength, leftEdge + textXOffset + 1, - baseline + textYOffset + 1); + Tk_DrawChars(menuPtr->display, d, gc, tkfont, label, + mePtr->labelLength, leftEdge + textXOffset + 1, + baseline + textYOffset + 1); gc->foreground = oldFgColor; - } + } } - Tk_DrawChars(menuPtr->display, d, gc, tkfont, label, - mePtr->labelLength, leftEdge + textXOffset, + Tk_DrawChars(menuPtr->display, d, gc, tkfont, label, + mePtr->labelLength, leftEdge + textXOffset, baseline + textYOffset); - DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr, - x + textXOffset, y + textYOffset, - width, height); + DrawMenuUnderline(menuPtr, mePtr, d, gc, tkfont, fmPtr, + x + textXOffset, y + textYOffset, width, height); } } @@ -2295,7 +2262,7 @@ DrawMenuEntryLabel( if (menuPtr->disabledFgPtr == NULL) { XFillRectangle(menuPtr->display, d, menuPtr->disabledGC, x, y, (unsigned) width, (unsigned) height); - } else if ((mePtr->image != NULL) + } else if ((mePtr->image != NULL) && (menuPtr->disabledImageGC != None)) { XFillRectangle(menuPtr->display, d, menuPtr->disabledImageGC, leftEdge + imageXOffset, @@ -2310,16 +2277,15 @@ DrawMenuEntryLabel( * * TkpComputeMenubarGeometry -- * - * This procedure is invoked to recompute the size and - * layout of a menu that is a menubar clone. + * This function is invoked to recompute the size and layout of a menu + * that is a menubar clone. * * Results: * None. * * Side effects: - * Fields of menu entries are changed to reflect their - * current positions, and the size of the menu window - * itself may be changed. + * Fields of menu entries are changed to reflect their current positions, + * and the size of the menu window itself may be changed. * *-------------------------------------------------------------- */ @@ -2336,26 +2302,25 @@ TkpComputeMenubarGeometry(menuPtr) * * DrawTearoffEntry -- * - * This procedure draws the background part of a menu. + * This function draws the background part of a menu. * * Results: * None. * * Side effects: - * Commands are output to X to display the menu in its - * current mode. + * Commands are output to X to display the menu in its current mode. * *---------------------------------------------------------------------- */ void DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height) - TkMenu *menuPtr; /* The menu we are drawing */ - TkMenuEntry *mePtr; /* The entry we are drawing */ - Drawable d; /* The drawable we are drawing into */ - GC gc; /* The gc we are drawing with */ - Tk_Font tkfont; /* The font we are drawing with */ - CONST Tk_FontMetrics *fmPtr; /* The metrics we are drawing with */ + TkMenu *menuPtr; /* The menu we are drawing */ + TkMenuEntry *mePtr; /* The entry we are drawing */ + Drawable d; /* The drawable we are drawing into */ + GC gc; /* The gc we are drawing with */ + Tk_Font tkfont; /* The font we are drawing with */ + CONST Tk_FontMetrics *fmPtr;/* The metrics we are drawing with */ int x; int y; int width; @@ -2368,12 +2333,12 @@ DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height) if (menuPtr->menuType != MASTER_MENU) { return; } - + points[0].x = x; points[0].y = y + height/2; points[1].y = points[0].y; segmentWidth = 6; - maxX = width - 1; + maxX = width - 1; border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); while (points[0].x < maxX) { @@ -2395,21 +2360,20 @@ DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, y, width, height) * Processes configurations for menu entries. * * Results: - * Returns standard TCL result. If TCL_ERROR is returned, then - * the interp's result contains an error message. + * Returns standard TCL result. If TCL_ERROR is returned, then the + * interp's result contains an error message. * * Side effects: - * Configuration information get set for mePtr; old resources - * get freed, if any need it. + * Configuration information get set for mePtr; old resources get freed, + * if any need it. * *---------------------------------------------------------------------- */ int TkpConfigureMenuEntry(mePtr) - register TkMenuEntry *mePtr; /* Information about menu entry; may - * or may not already have values for - * some fields. */ + register TkMenuEntry *mePtr;/* Information about menu entry; may or may + * not already have values for some fields. */ { TkMenu *menuPtr = mePtr->menuPtr; @@ -2425,8 +2389,8 @@ TkpConfigureMenuEntry(mePtr) * * TkpDrawMenuEntry -- * - * Draws the given menu entry at the given coordinates with the - * given attributes. + * Draws the given menu entry at the given coordinates with the given + * attributes. * * Results: * None. @@ -2438,21 +2402,21 @@ TkpConfigureMenuEntry(mePtr) */ void -TkpDrawMenuEntry(mePtr, d, tkfont, menuMetricsPtr, x, y, width, height, +TkpDrawMenuEntry(mePtr, d, tkfont, menuMetricsPtr, x, y, width, height, strictMotif, drawArrow) - TkMenuEntry *mePtr; /* The entry to draw */ - Drawable d; /* What to draw into */ - Tk_Font tkfont; /* Precalculated font for menu */ + TkMenuEntry *mePtr; /* The entry to draw */ + Drawable d; /* What to draw into */ + Tk_Font tkfont; /* Precalculated font for menu */ CONST Tk_FontMetrics *menuMetricsPtr; - /* Precalculated metrics for menu */ - int x; /* X-coordinate of topleft of entry */ - int y; /* Y-coordinate of topleft of entry */ - int width; /* Width of the entry rectangle */ - int height; /* Height of the current rectangle */ - int strictMotif; /* Boolean flag */ - int drawArrow; /* Whether or not to draw the cascade - * arrow for cascade items. Only applies - * to Windows. */ + /* Precalculated metrics for menu */ + int x; /* X-coordinate of topleft of entry */ + int y; /* Y-coordinate of topleft of entry */ + int width; /* Width of the entry rectangle */ + int height; /* Height of the current rectangle */ + int strictMotif; /* Boolean flag */ + int drawArrow; /* Whether or not to draw the cascade arrow + * for cascade items. Only applies to + * Windows. */ { GC gc, indicatorGC; TkMenu *menuPtr = mePtr->menuPtr; @@ -2476,11 +2440,11 @@ TkpDrawMenuEntry(mePtr, d, tkfont, menuMetricsPtr, x, y, width, height, TkMenuEntry *cascadeEntryPtr; int parentDisabled = 0; char *name; - + for (cascadeEntryPtr = menuPtr->menuRefPtr->parentEntryPtr; cascadeEntryPtr != NULL; cascadeEntryPtr = cascadeEntryPtr->nextCascadePtr) { - name = Tcl_GetStringFromObj(cascadeEntryPtr->namePtr, NULL); + name = Tcl_GetString(cascadeEntryPtr->namePtr); if (strcmp(name, Tk_PathName(menuPtr->tkwin)) == 0) { if (mePtr->state == ENTRY_DISABLED) { parentDisabled = 1; @@ -2527,16 +2491,16 @@ TkpDrawMenuEntry(mePtr, d, tkfont, menuMetricsPtr, x, y, width, height, } /* - * Need to draw the entire background, including padding. On Unix, - * for menubars, we have to draw the rest of the entry taking - * into account the padding. + * Need to draw the entire background, including padding. On Unix, for + * menubars, we have to draw the rest of the entry taking into account the + * padding. */ - - DrawMenuEntryBackground(menuPtr, mePtr, d, activeBorder, + + DrawMenuEntryBackground(menuPtr, mePtr, d, activeBorder, bgBorder, x, y, width, height); - + if (mePtr->type == SEPARATOR_ENTRY) { - DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont, + DrawMenuSeparator(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY, width, adjustedHeight); } else if (mePtr->type == TEAROFF_ENTRY) { DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY, @@ -2574,17 +2538,16 @@ TkpDrawMenuEntry(mePtr, d, tkfont, menuMetricsPtr, x, y, width, height, static void GetMenuLabelGeometry(mePtr, tkfont, fmPtr, widthPtr, heightPtr) - TkMenuEntry *mePtr; /* The entry we are computing */ - Tk_Font tkfont; /* The precalculated font */ - CONST Tk_FontMetrics *fmPtr; /* The precalculated metrics */ - int *widthPtr; /* The resulting width of the label - * portion */ - int *heightPtr; /* The resulting height of the label - * portion */ + TkMenuEntry *mePtr; /* The entry we are computing */ + Tk_Font tkfont; /* The precalculated font */ + CONST Tk_FontMetrics *fmPtr;/* The precalculated metrics */ + int *widthPtr; /* The resulting width of the label portion */ + int *heightPtr; /* The resulting height of the label + * portion */ { TkMenu *menuPtr = mePtr->menuPtr; int haveImage = 0, haveText = 0; - + if (mePtr->image != NULL) { Tk_SizeOfImage(mePtr->image, widthPtr, heightPtr); haveImage = 1; @@ -2596,54 +2559,72 @@ GetMenuLabelGeometry(mePtr, tkfont, fmPtr, widthPtr, heightPtr) *heightPtr = 0; *widthPtr = 0; } - + if (haveImage && (mePtr->compound == COMPOUND_NONE)) { - /* We don't care about the text in this case */ + /* + * We don't care about the text in this case. + */ } else { - /* Either it is compound or we don't have an image */ + /* + * Either it is compound or we don't have an image, + */ + if (mePtr->labelPtr != NULL) { int textWidth; - char *label = Tcl_GetStringFromObj(mePtr->labelPtr, NULL); + char *label = Tcl_GetString(mePtr->labelPtr); + textWidth = Tk_TextWidth(tkfont, label, mePtr->labelLength); if ((mePtr->compound != COMPOUND_NONE) && haveImage) { switch ((enum compound) mePtr->compound) { - case COMPOUND_TOP: - case COMPOUND_BOTTOM: { - if (textWidth > *widthPtr) { - *widthPtr = textWidth; - } - /* Add text and padding */ - *heightPtr += fmPtr->linespace + 2; - break; + case COMPOUND_TOP: + case COMPOUND_BOTTOM: + if (textWidth > *widthPtr) { + *widthPtr = textWidth; } - case COMPOUND_LEFT: - case COMPOUND_RIGHT: { - if (fmPtr->linespace > *heightPtr) { - *heightPtr = fmPtr->linespace; - } - /* Add text and padding */ - *widthPtr += textWidth + 2; - break; + + /* + * Add text and padding. + */ + + *heightPtr += fmPtr->linespace + 2; + break; + case COMPOUND_LEFT: + case COMPOUND_RIGHT: + if (fmPtr->linespace > *heightPtr) { + *heightPtr = fmPtr->linespace; } - case COMPOUND_CENTER: { - if (fmPtr->linespace > *heightPtr) { - *heightPtr = fmPtr->linespace; - } - if (textWidth > *widthPtr) { - *widthPtr = textWidth; - } - break; + + /* + * Add text and padding. + */ + + *widthPtr += textWidth + 2; + break; + case COMPOUND_CENTER: + if (fmPtr->linespace > *heightPtr) { + *heightPtr = fmPtr->linespace; + } + if (textWidth > *widthPtr) { + *widthPtr = textWidth; } - case COMPOUND_NONE: {break;} + break; + case COMPOUND_NONE: + break; } - } else { - /* We don't have an image or we're not compound */ + } else { + /* + * We don't have an image or we're not compound. + */ + *heightPtr = fmPtr->linespace; *widthPtr = textWidth; } } else { - /* An empty entry still has this height */ + /* + * An empty entry still has this height. + */ + *heightPtr = fmPtr->linespace; } } @@ -2655,36 +2636,35 @@ GetMenuLabelGeometry(mePtr, tkfont, fmPtr, widthPtr, heightPtr) * * DrawMenuEntryBackground -- * - * This procedure draws the background part of a menu. + * This function draws the background part of a menu. * * Results: * None. * * Side effects: - * Commands are output to X to display the menu in its - * current mode. + * Commands are output to X to display the menu in its current mode. * *---------------------------------------------------------------------- */ static void DrawMenuEntryBackground( - TkMenu *menuPtr, /* The menu we are drawing. */ - TkMenuEntry *mePtr, /* The entry we are drawing. */ - Drawable d, /* What we are drawing into */ - Tk_3DBorder activeBorder, /* Border for active items */ - Tk_3DBorder bgBorder, /* Border for the background */ - int x, /* left edge */ - int y, /* top edge */ - int width, /* width of rectangle to draw */ - int height) /* height of rectangle to draw */ + TkMenu *menuPtr, /* The menu we are drawing. */ + TkMenuEntry *mePtr, /* The entry we are drawing. */ + Drawable d, /* What we are drawing into */ + Tk_3DBorder activeBorder, /* Border for active items */ + Tk_3DBorder bgBorder, /* Border for the background */ + int x, /* left edge */ + int y, /* top edge */ + int width, /* width of rectangle to draw */ + int height) /* height of rectangle to draw */ { - if (mePtr->state == ENTRY_ACTIVE + if (mePtr->state == ENTRY_ACTIVE || (mePtr->entryFlags & ENTRY_PLATFORM_FLAG1)!=0 ) { bgBorder = activeBorder; } - Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, - x, y, width, height, 0, TK_RELIEF_FLAT); + Tk_Fill3DRectangle(menuPtr->tkwin, d, bgBorder, x, y, width, height, 0, + TK_RELIEF_FLAT); } /* @@ -2692,16 +2672,15 @@ DrawMenuEntryBackground( * * TkpComputeStandardMenuGeometry -- * - * This procedure is invoked to recompute the size and - * layout of a menu that is not a menubar clone. + * This function is invoked to recompute the size and layout of a menu + * that is not a menubar clone. * * Results: * None. * * Side effects: - * Fields of menu entries are changed to reflect their - * current positions, and the size of the menu window - * itself may be changed. + * Fields of menu entries are changed to reflect their current positions, + * and the size of the menu window itself may be changed. * *-------------------------------------------------------------- */ @@ -2716,26 +2695,25 @@ TkpComputeStandardMenuGeometry( int windowWidth, windowHeight, accelSpace; int i, j, lastColumnBreak = 0; int activeBorderWidth, borderWidth; - + if (menuPtr->tkwin == NULL) { return; } - Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin, + Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin, menuPtr->borderWidthPtr, &borderWidth); x = y = borderWidth; indicatorSpace = labelWidth = accelWidth = 0; windowHeight = 0; /* - * On the Mac especially, getting font metrics can be quite slow, - * so we want to do it intelligently. We are going to precalculate - * them and pass them down to all of the measuring and drawing - * routines. We will measure the font metrics of the menu once. - * If an entry does not have its own font set, then we give - * the geometry/drawing routines the menu's font and metrics. - * If an entry has its own font, we will measure that font and - * give all of the geometry/drawing the entry's font and metrics. + * On the Mac especially, getting font metrics can be quite slow, so we + * want to do it intelligently. We are going to precalculate them and pass + * them down to all of the measuring and drawing routines. We will measure + * the font metrics of the menu once. If an entry does not have its own + * font set, then we give the geometry/drawing routines the menu's font + * and metrics. If an entry has its own font, we will measure that font + * and give all of the geometry/drawing the entry's font and metrics. */ menuFont = Tk_GetFontFromObj(menuPtr->tkwin, menuPtr->fontPtr); @@ -2778,28 +2756,27 @@ TkpComputeStandardMenuGeometry( fmPtr, &width, &height); menuPtr->entries[i]->height = height; } else if (menuPtr->entries[i]->type == TEAROFF_ENTRY) { - GetTearoffEntryGeometry(menuPtr, menuPtr->entries[i], tkfont, + GetTearoffEntryGeometry(menuPtr, menuPtr->entries[i], tkfont, fmPtr, &width, &height); menuPtr->entries[i]->height = height; + } else { - /* - * For each entry, compute the height required by that - * particular entry, plus three widths: the width of the - * label, the width to allow for an indicator to be displayed - * to the left of the label (if any), and the width of the - * accelerator to be displayed to the right of the label - * (if any). These sizes depend, of course, on the type - * of the entry. + * For each entry, compute the height required by that particular + * entry, plus three widths: the width of the label, the width to + * allow for an indicator to be displayed to the left of the label + * (if any), and the width of the accelerator to be displayed to + * the right of the label (if any). These sizes depend, of course, + * on the type of the entry. */ - + GetMenuLabelGeometry(menuPtr->entries[i], tkfont, fmPtr, &width, &height); menuPtr->entries[i]->height = height; if (width > labelWidth) { labelWidth = width; } - + GetMenuAccelGeometry(menuPtr, menuPtr->entries[i], tkfont, fmPtr, &width, &height); if (height > menuPtr->entries[i]->height) { @@ -2809,7 +2786,7 @@ TkpComputeStandardMenuGeometry( accelWidth = width; } - GetMenuIndicatorGeometry(menuPtr, menuPtr->entries[i], tkfont, + GetMenuIndicatorGeometry(menuPtr, menuPtr->entries[i], tkfont, fmPtr, &width, &height); if (height > menuPtr->entries[i]->height) { menuPtr->entries[i]->height = height; @@ -2820,7 +2797,7 @@ TkpComputeStandardMenuGeometry( menuPtr->entries[i]->height += 2 * activeBorderWidth + 1; } - menuPtr->entries[i]->y = y; + menuPtr->entries[i]->y = y; y += menuPtr->entries[i]->height; if (y > windowHeight) { windowHeight = y; @@ -2843,10 +2820,10 @@ TkpComputeStandardMenuGeometry( windowHeight += borderWidth; - + /* - * The X server doesn't like zero dimensions, so round up to at least - * 1 (a zero-sized menu should never really occur, anyway). + * The X server doesn't like zero dimensions, so round up to at least 1 (a + * zero-sized menu should never really occur, anyway). */ if (windowWidth <= 0) { @@ -2864,8 +2841,8 @@ TkpComputeStandardMenuGeometry( * * MenuSelectEvent -- * - * Generates a "MenuSelect" virtual event. This can be used to - * do context-sensitive menu help. + * Generates a "MenuSelect" virtual event. This can be used to do + * context-sensitive menu help. * * Results: * None. @@ -2883,7 +2860,7 @@ MenuSelectEvent( XVirtualEvent event; POINTS rootPoint; DWORD msgPos; - + event.type = VirtualEvent; event.serial = menuPtr->display->request; event.send_event = 0; @@ -2893,7 +2870,7 @@ MenuSelectEvent( event.root = XRootWindow(menuPtr->display, 0); event.subwindow = None; event.time = TkpGetMS(); - + msgPos = GetMessagePos(); rootPoint = MAKEPOINTS(msgPos); event.x_root = rootPoint.x; @@ -2911,8 +2888,8 @@ MenuSelectEvent( * TkpMenuNotifyToplevelCreate -- * * This routine reconfigures the menu and the clones indicated by - * menuName becuase a toplevel has been created and any system - * menus need to be created. + * menuName becuase a toplevel has been created and any system menus need + * to be created. * * Results: * None. @@ -2925,9 +2902,8 @@ MenuSelectEvent( void TkpMenuNotifyToplevelCreate( - Tcl_Interp *interp, /* The interp the menu lives in. */ - char *menuName) /* The name of the menu to - * reconfigure. */ + Tcl_Interp *interp, /* The interp the menu lives in. */ + char *menuName) /* The name of the menu to reconfigure. */ { TkMenuReferences *menuRefPtr; TkMenu *menuPtr; @@ -2937,10 +2913,10 @@ TkpMenuNotifyToplevelCreate( if ((menuRefPtr != NULL) && (menuRefPtr->menuPtr != NULL)) { for (menuPtr = menuRefPtr->menuPtr->masterMenuPtr; menuPtr != NULL; menuPtr = menuPtr->nextInstancePtr) { - if ((menuPtr->menuType == MENUBAR) + if ((menuPtr->menuType == MENUBAR) && !(menuPtr->menuFlags & MENU_RECONFIGURE_PENDING)) { menuPtr->menuFlags |= MENU_RECONFIGURE_PENDING; - Tcl_DoWhenIdle(ReconfigureWindowsMenu, + Tcl_DoWhenIdle(ReconfigureWindowsMenu, (ClientData) menuPtr); } } @@ -2953,8 +2929,8 @@ TkpMenuNotifyToplevelCreate( * * MenuExitHandler -- * - * Throws away the utility window needed for menus and unregisters - * the class. + * Throws away the utility window needed for menus and unregisters the + * class. * * Results: * None. @@ -2969,8 +2945,8 @@ static void MenuExitHandler( ClientData clientData) /* Not used */ { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); DestroyWindow(tsdPtr->menuHWND); UnregisterClass(MENU_CLASS_NAME, Tk_GetHINSTANCE()); @@ -2988,9 +2964,9 @@ MenuExitHandler( * database name. * * Results: - * Returns a Tcl_Obj * with the default value. If there is no - * Windows-specific default for this attribute, returns NULL. - * This object has a ref count of 0. + * Returns a Tcl_Obj* with the default value. If there is no + * Windows-specific default for this attribute, returns NULL. This object + * has a ref count of 0. * * Side effects: * Storage is allocated. @@ -3010,8 +2986,7 @@ TkWinGetMenuSystemDefault( (strcmp(dbName, "borderWidth") == 0)) { valuePtr = Tcl_NewIntObj(defaultBorderWidth); } else if (strcmp(dbName, "font") == 0) { - valuePtr = Tcl_NewStringObj(Tcl_DStringValue(&menuFontDString), - -1); + valuePtr = Tcl_NewStringObj(Tcl_DStringValue(&menuFontDString), -1); } return valuePtr; @@ -3036,14 +3011,14 @@ TkWinGetMenuSystemDefault( void SetDefaults( - int firstTime) /* Is this the first time this - * has been called? */ + int firstTime) /* Is this the first time this has been + * called? */ { char sizeString[TCL_INTEGER_SPACE]; char faceName[LF_FACESIZE]; HDC scratchDC; Tcl_DString boldItalicDString; - int bold = 0; + int bold = 0; int italic = 0; TEXTMETRIC tm; int pointSize; @@ -3051,8 +3026,8 @@ SetDefaults( NONCLIENTMETRICS ncMetrics; /* - * Set all of the default options. The loop will terminate when we run - * out of options via a break statement. + * Set all of the default options. The loop will terminate when we run out + * of options via a break statement. */ defaultBorderWidth = GetSystemMetrics(SM_CXBORDER); @@ -3086,7 +3061,7 @@ SetDefaults( DeleteDC(scratchDC); DeleteObject(menuFont); - + Tcl_DStringAppendElement(&menuFontDString, faceName); sprintf(sizeString, "%d", pointSize); Tcl_DStringAppendElement(&menuFontDString, sizeString); @@ -3099,31 +3074,30 @@ SetDefaults( if (italic == 1) { Tcl_DStringAppendElement(&boldItalicDString, "italic"); } - Tcl_DStringAppendElement(&menuFontDString, + Tcl_DStringAppendElement(&menuFontDString, Tcl_DStringValue(&boldItalicDString)); } /* * Now we go ahead and get the dimensions of the check mark and the - * appropriate margins. Since this is fairly hairy, we do it here - * to save time when traversing large sets of menu items. + * appropriate margins. Since this is fairly hairy, we do it here to save + * time when traversing large sets of menu items. * - * The code below was given to me by Microsoft over the phone. It - * is the only way to insure menu items lining up, and is not - * documented. + * The code below was given to me by Microsoft over the phone. It is the + * only way to ensure menu items line up, and is not documented. */ if (TkWinGetPlatformId() >= VER_PLATFORM_WIN32_WINDOWS) { indicatorDimensions[0] = GetSystemMetrics(SM_CYMENUCHECK); indicatorDimensions[1] = ((GetSystemMetrics(SM_CXFIXEDFRAME) + - GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXBORDER) + GetSystemMetrics(SM_CXMENUCHECK) + 7) & 0xFFF8) - GetSystemMetrics(SM_CXFIXEDFRAME); } else { DWORD dimensions = GetMenuCheckMarkDimensions(); indicatorDimensions[0] = HIWORD(dimensions); indicatorDimensions[1] = LOWORD(dimensions); - } + } } /* @@ -3146,8 +3120,8 @@ void TkpMenuInit() { WNDCLASS wndClass; - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); wndClass.style = CS_OWNDC; wndClass.lpfnWndProc = TkWinMenuProc; @@ -3159,28 +3133,29 @@ TkpMenuInit() wndClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wndClass.lpszMenuName = NULL; wndClass.lpszClassName = MENU_CLASS_NAME; - if(!RegisterClass(&wndClass)) { - panic("Failed to register menu window class."); + if (!RegisterClass(&wndClass)) { + Tcl_Panic("Failed to register menu window class."); } tsdPtr->menuHWND = CreateWindow(MENU_CLASS_NAME, "MenuWindow", WS_POPUP, - 0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL); + 0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL); - if(!tsdPtr->menuHWND) { - panic("Failed to create the menu window."); + if (!tsdPtr->menuHWND) { + Tcl_Panic("Failed to create the menu window."); } wndClass.lpfnWndProc = TkWinEmbeddedMenuProc; wndClass.lpszClassName = EMBEDDED_MENU_CLASS_NAME; - if(!RegisterClass(&wndClass)) { - panic ("Failed to register embedded menu window class."); + if (!RegisterClass(&wndClass)) { + Tcl_Panic("Failed to register embedded menu window class."); } - tsdPtr->embeddedMenuHWND = CreateWindow(EMBEDDED_MENU_CLASS_NAME, "EmbeddedMenuWindow", WS_POPUP, - 0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL); + tsdPtr->embeddedMenuHWND = + CreateWindow(EMBEDDED_MENU_CLASS_NAME, "EmbeddedMenuWindow", + WS_POPUP, 0, 0, 10, 10, NULL, NULL, Tk_GetHINSTANCE(), NULL); - if(!tsdPtr->embeddedMenuHWND) { - panic("Failed to create the embedded menu window."); + if (!tsdPtr->embeddedMenuHWND) { + Tcl_Panic("Failed to create the embedded menu window."); } TkCreateExitHandler(MenuExitHandler, (ClientData) NULL); @@ -3192,11 +3167,10 @@ TkpMenuInit() * * Tk_GetMenuHWND -- * - * This function returns the HWND of a hidden menu Window that - * processes messages of a popup menu. This hidden menu window - * is used to handle either a dynamic popup menu in the same - * process or a pull-down menu of an embedded window in a - * different process. + * This function returns the HWND of a hidden menu Window that processes + * messages of a popup menu. This hidden menu window is used to handle + * either a dynamic popup menu in the same process or a pull-down menu of + * an embedded window in a different process. * * Results: * Returns the HWND of the hidden menu Window. @@ -3211,8 +3185,8 @@ HWND Tk_GetMenuHWND(tkwin) Tk_Window tkwin; { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); TkMenuInit(); return tsdPtr->embeddedMenuHWND; } @@ -3236,9 +3210,17 @@ Tk_GetMenuHWND(tkwin) void TkpMenuThreadInit() { - ThreadSpecificData *tsdPtr = (ThreadSpecificData *) - Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); + ThreadSpecificData *tsdPtr = (ThreadSpecificData *) + Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); Tcl_InitHashTable(&tsdPtr->winMenuTable, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(&tsdPtr->commandTable, TCL_ONE_WORD_KEYS); } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ |