OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tix/] [generic/] [tixTList.c] - Blame information for rev 1778

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tixTList.c --
3
 *
4
 *      This module implements "TList" widgets.
5
 *
6
 *
7
 * Copyright (c) 1996, Expert Interface Technologies
8
 *
9
 * See the file "license.terms" for information on usage and redistribution
10
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11
 */
12
 
13
#include <tixPort.h>
14
#include <tixInt.h>
15
#include <tixDef.h>
16
#include <tixTList.h>
17
 
18
#define TIX_UP          1
19
#define TIX_DOWN        2
20
#define TIX_LEFT        3
21
#define TIX_RIGHT       4
22
 
23
/*
24
 * Information used for argv parsing.
25
 */
26
static Tk_ConfigSpec configSpecs[] = {
27
    {TK_CONFIG_COLOR, "-background", "background", "Background",
28
       DEF_TLIST_BG_COLOR, Tk_Offset(WidgetRecord, normalBg),
29
       TK_CONFIG_COLOR_ONLY},
30
 
31
    {TK_CONFIG_COLOR, "-background", "background", "Background",
32
       DEF_TLIST_BG_MONO, Tk_Offset(WidgetRecord, normalBg),
33
       TK_CONFIG_MONO_ONLY},
34
 
35
    {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
36
       (char *) NULL, 0, 0},
37
 
38
    {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
39
       (char *) NULL, 0, 0},
40
 
41
    {TK_CONFIG_BORDER, "-highlightbackground", "highlightBackground",
42
       "HighlightBackground",
43
       DEF_TLIST_BG_COLOR, Tk_Offset(WidgetRecord, border),
44
       TK_CONFIG_COLOR_ONLY},
45
 
46
    {TK_CONFIG_BORDER, "-highlightbackground", "highlightBackground",
47
       "HighlightBackground",
48
       DEF_TLIST_BG_MONO, Tk_Offset(WidgetRecord, border),
49
       TK_CONFIG_MONO_ONLY},
50
 
51
    {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
52
       DEF_TLIST_BORDER_WIDTH, Tk_Offset(WidgetRecord, borderWidth), 0},
53
 
54
    {TK_CONFIG_STRING, "-browsecmd", "browseCmd", "BrowseCmd",
55
        DEF_TLIST_BROWSE_COMMAND, Tk_Offset(WidgetRecord, browseCmd),
56
        TK_CONFIG_NULL_OK},
57
 
58
    {TK_CONFIG_STRING, "-command", "command", "Command",
59
       DEF_TLIST_COMMAND, Tk_Offset(WidgetRecord, command),
60
       TK_CONFIG_NULL_OK},
61
 
62
    {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
63
       DEF_TLIST_CURSOR, Tk_Offset(WidgetRecord, cursor),
64
       TK_CONFIG_NULL_OK},
65
 
66
    {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL,
67
       (char *) NULL, 0, 0},
68
 
69
    {TK_CONFIG_FONT, "-font", "font", "Font",
70
       DEF_TLIST_FONT, Tk_Offset(WidgetRecord, font), 0},
71
 
72
    {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
73
       DEF_TLIST_FG_COLOR, Tk_Offset(WidgetRecord, normalFg),
74
       TK_CONFIG_COLOR_ONLY},
75
 
76
    {TK_CONFIG_COLOR, "-foreground", "foreground", "Foreground",
77
       DEF_TLIST_FG_MONO, Tk_Offset(WidgetRecord, normalFg),
78
       TK_CONFIG_MONO_ONLY},
79
 
80
    {TK_CONFIG_INT, "-height", "height", "Height",
81
       DEF_TLIST_HEIGHT, Tk_Offset(WidgetRecord, height), 0},
82
 
83
    {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
84
       DEF_TLIST_HIGHLIGHT_COLOR, Tk_Offset(WidgetRecord, highlightColorPtr),
85
       TK_CONFIG_COLOR_ONLY},
86
 
87
    {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
88
       DEF_TLIST_HIGHLIGHT_MONO, Tk_Offset(WidgetRecord, highlightColorPtr),
89
       TK_CONFIG_MONO_ONLY},
90
 
91
    {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
92
       "HighlightThickness",
93
       DEF_TLIST_HIGHLIGHT_WIDTH, Tk_Offset(WidgetRecord, highlightWidth), 0},
94
 
95
    {TK_CONFIG_CUSTOM, "-itemtype", "itemType", "ItemType",
96
       DEF_TLIST_ITEM_TYPE, Tk_Offset(WidgetRecord, diTypePtr),
97
       0, &tixConfigItemType},
98
 
99
    {TK_CONFIG_UID, "-orient", "orient", "Orient",
100
        DEF_TLIST_ORIENT, Tk_Offset(WidgetRecord, orientUid), 0},
101
 
102
    {TK_CONFIG_PIXELS, "-padx", "padX", "Pad",
103
        DEF_TLIST_PADX, Tk_Offset(WidgetRecord, padX), 0},
104
 
105
    {TK_CONFIG_PIXELS, "-pady", "padY", "Pad",
106
        DEF_TLIST_PADY, Tk_Offset(WidgetRecord, padY), 0},
107
 
108
    {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
109
       DEF_TLIST_RELIEF, Tk_Offset(WidgetRecord, relief), 0},
110
 
111
    {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
112
        DEF_TLIST_SELECT_BG_COLOR, Tk_Offset(WidgetRecord, selectBorder),
113
        TK_CONFIG_COLOR_ONLY},
114
 
115
    {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
116
        DEF_TLIST_SELECT_BG_MONO, Tk_Offset(WidgetRecord, selectBorder),
117
        TK_CONFIG_MONO_ONLY},
118
 
119
    {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth","BorderWidth",
120
       DEF_TLIST_SELECT_BORDERWIDTH,Tk_Offset(WidgetRecord, selBorderWidth),0},
121
 
122
    {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
123
       DEF_TLIST_SELECT_FG_COLOR, Tk_Offset(WidgetRecord, selectFg),
124
       TK_CONFIG_COLOR_ONLY},
125
 
126
    {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
127
       DEF_TLIST_SELECT_FG_MONO, Tk_Offset(WidgetRecord, selectFg),
128
       TK_CONFIG_MONO_ONLY},
129
 
130
    {TK_CONFIG_UID, "-selectmode", "selectMode", "SelectMode",
131
        DEF_TLIST_SELECT_MODE, Tk_Offset(WidgetRecord, selectMode), 0},
132
 
133
    {TK_CONFIG_UID, "-state", (char*)NULL, (char*)NULL,
134
       DEF_TLIST_STATE, Tk_Offset(WidgetRecord, state), 0},
135
 
136
    {TK_CONFIG_STRING, "-sizecmd", "sizeCmd", "SizeCmd",
137
       DEF_TLIST_SIZE_COMMAND, Tk_Offset(WidgetRecord, sizeCmd),
138
       TK_CONFIG_NULL_OK},
139
 
140
    {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
141
        DEF_TLIST_TAKE_FOCUS, Tk_Offset(WidgetRecord, takeFocus),
142
        TK_CONFIG_NULL_OK},
143
 
144
    {TK_CONFIG_INT, "-width", "width", "Width",
145
        DEF_TLIST_WIDTH, Tk_Offset(WidgetRecord, width), 0},
146
 
147
    {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
148
       DEF_TLIST_X_SCROLL_COMMAND,
149
       Tk_Offset(WidgetRecord, scrollInfo[0].command),
150
       TK_CONFIG_NULL_OK},
151
 
152
    {TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
153
       DEF_TLIST_Y_SCROLL_COMMAND,
154
       Tk_Offset(WidgetRecord, scrollInfo[1].command),
155
       TK_CONFIG_NULL_OK},
156
 
157
    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
158
       (char *) NULL, 0, 0}
159
};
160
 
161
#define DEF_TLISTENTRY_STATE     "normal"
162
 
163
static Tk_ConfigSpec entryConfigSpecs[] = {
164
 
165
    {TK_CONFIG_UID, "-state", (char*)NULL, (char*)NULL,
166
       DEF_TLISTENTRY_STATE, Tk_Offset(ListEntry, state), 0},
167
 
168
    {TK_CONFIG_END, (char *) NULL, (char *) NULL, (char *) NULL,
169
       (char *) NULL, 0, 0}
170
};
171
 
172
static Tix_ListInfo entListInfo = {
173
    Tk_Offset(ListEntry, next),
174
    TIX_UNDEFINED,
175
};
176
 
177
 
178
/*
179
 * Forward declarations for procedures defined later in this file:
180
 */
181
 
182
        /* These are standard procedures for TK widgets
183
         * implemeted in C
184
         */
185
 
186
static void             WidgetCmdDeletedProc _ANSI_ARGS_((
187
                            ClientData clientData));
188
static int              WidgetConfigure _ANSI_ARGS_((Tcl_Interp *interp,
189
                            WidgetPtr wPtr, int argc, char **argv,
190
                            int flags));
191
static void             WidgetDestroy _ANSI_ARGS_((ClientData clientData));
192
static void             WidgetEventProc _ANSI_ARGS_((ClientData clientData,
193
                            XEvent *eventPtr));
194
static int              WidgetCommand _ANSI_ARGS_((ClientData clientData,
195
                            Tcl_Interp *, int argc, char **argv));
196
static void             WidgetDisplay _ANSI_ARGS_((ClientData clientData));
197
static void             WidgetComputeGeometry _ANSI_ARGS_((
198
                            ClientData clientData));
199
 
200
        /* Extra procedures for this widget
201
         */
202
static void             CancelRedrawWhenIdle _ANSI_ARGS_((WidgetPtr wPtr));
203
static void             CancelResizeWhenIdle _ANSI_ARGS_((WidgetPtr wPtr));
204
static int              ConfigElement _ANSI_ARGS_((WidgetPtr wPtr,
205
                            ListEntry *chPtr, int argc, char ** argv,
206
                            int flags, int forced));
207
static void             RedrawRows _ANSI_ARGS_((
208
                            WidgetPtr wPtr, Drawable pixmap));
209
static void             RedrawWhenIdle _ANSI_ARGS_((WidgetPtr wPtr));
210
static void             ResizeRows _ANSI_ARGS_((
211
                            WidgetPtr wPtr, int winW, int winH));
212
static void             ResizeWhenIdle _ANSI_ARGS_((WidgetPtr wPtr));
213
static void             ResizeNow _ANSI_ARGS_((WidgetPtr wPtr));
214
static void             UpdateScrollBars _ANSI_ARGS_((WidgetPtr wPtr,
215
                            int sizeChanged));
216
static int              Tix_TLGetFromTo _ANSI_ARGS_((
217
                            Tcl_Interp *interp, WidgetPtr wPtr,
218
                            int argc, char **argv,
219
                            ListEntry ** fromPtr_ret, ListEntry ** toPtr_ret));
220
static void             Tix_TLDItemSizeChanged _ANSI_ARGS_((
221
                            Tix_DItem *iPtr));
222
static void             MakeGeomRequest _ANSI_ARGS_((
223
                            WidgetPtr wPtr));
224
static int              Tix_TLGetNearest _ANSI_ARGS_((
225
                            WidgetPtr wPtr, int posn[2]));
226
static int              Tix_TLGetAt _ANSI_ARGS_((WidgetPtr wPtr,
227
                            Tcl_Interp *interp, char * spec, int *at));
228
static int              Tix_TLGetNeighbor _ANSI_ARGS_((
229
                            WidgetPtr wPtr, Tcl_Interp *interp,
230
                            int type, int argc, char **argv));
231
static int              Tix_TranslateIndex _ANSI_ARGS_((
232
                            WidgetPtr wPtr, Tcl_Interp *interp, char * string,
233
                            int * index, int isInsert));
234
static int              Tix_TLDeleteRange _ANSI_ARGS_((
235
                            WidgetPtr wPtr, ListEntry * fromPtr,
236
                            ListEntry *toPtr));
237
static ListEntry *      AllocEntry _ANSI_ARGS_((WidgetPtr wPtr));
238
static int              AddElement _ANSI_ARGS_((WidgetPtr wPtr,
239
                            ListEntry * chPtr, int at));
240
static void             FreeEntry _ANSI_ARGS_((WidgetPtr wPtr,
241
                            ListEntry * chPtr));
242
static int              Tix_TLSpecialEntryInfo _ANSI_ARGS_((
243
                            WidgetPtr wPtr, Tcl_Interp *interp,
244
                            ListEntry * chPtr));
245
static void             Realloc _ANSI_ARGS_((WidgetPtr wPtr,int new_size));
246
 
247
static TIX_DECLARE_SUBCMD(Tix_TLInsert);
248
static TIX_DECLARE_SUBCMD(Tix_TLCGet);
249
static TIX_DECLARE_SUBCMD(Tix_TLConfig);
250
static TIX_DECLARE_SUBCMD(Tix_TLDelete);
251
static TIX_DECLARE_SUBCMD(Tix_TLEntryCget);
252
static TIX_DECLARE_SUBCMD(Tix_TLEntryConfig);
253
static TIX_DECLARE_SUBCMD(Tix_TLGeometryInfo);
254
static TIX_DECLARE_SUBCMD(Tix_TLIndex);
255
static TIX_DECLARE_SUBCMD(Tix_TLInfo);
256
static TIX_DECLARE_SUBCMD(Tix_TLNearest);
257
static TIX_DECLARE_SUBCMD(Tix_TLSee);
258
static TIX_DECLARE_SUBCMD(Tix_TLSelection);
259
static TIX_DECLARE_SUBCMD(Tix_TLSetSite);
260
static TIX_DECLARE_SUBCMD(Tix_TLView);
261
 
262
/*
263
 *--------------------------------------------------------------
264
 *
265
 * Tix_TListCmd --
266
 *
267
 *      This procedure is invoked to process the "tixTList" Tcl
268
 *      command.  It creates a new "TixTList" widget.
269
 *
270
 * Results:
271
 *      A standard Tcl result.
272
 *
273
 * Side effects:
274
 *      A new widget is created and configured.
275
 *
276
 *--------------------------------------------------------------
277
 */
278
int
279
Tix_TListCmd(clientData, interp, argc, argv)
280
    ClientData clientData;
281
    Tcl_Interp *interp;         /* Current interpreter. */
282
    int argc;                   /* Number of arguments. */
283
    char **argv;                /* Argument strings. */
284
{
285
    Tk_Window main = (Tk_Window) clientData;
286
    WidgetPtr wPtr;
287
    Tk_Window tkwin;
288
 
289
    if (argc < 2) {
290
        Tcl_AppendResult(interp, "wrong # args:  should be \"",
291
                argv[0], " pathName ?options?\"", (char *) NULL);
292
        return TCL_ERROR;
293
    }
294
 
295
    tkwin = Tk_CreateWindowFromPath(interp, main, argv[1], (char *) NULL);
296
    if (tkwin == NULL) {
297
        return TCL_ERROR;
298
    }
299
 
300
    Tk_SetClass(tkwin, "TixTList");
301
 
302
    /*
303
     * Allocate and initialize the widget record.
304
     */
305
    wPtr = (WidgetPtr) ckalloc(sizeof(WidgetRecord));
306
 
307
    wPtr->dispData.tkwin        = tkwin;
308
    wPtr->dispData.display      = Tk_Display(tkwin);
309
    wPtr->dispData.interp       = interp;
310
    wPtr->dispData.sizeChangedProc = Tix_TLDItemSizeChanged;
311
    wPtr->font          = NULL;
312
    wPtr->normalBg              = NULL;
313
    wPtr->normalFg              = NULL;
314
    wPtr->command               = NULL;
315
    wPtr->border                = NULL;
316
    wPtr->borderWidth           = 0;
317
    wPtr->selectBorder          = NULL;
318
    wPtr->selBorderWidth        = 0;
319
    wPtr->selectFg              = NULL;
320
    wPtr->backgroundGC          = None;
321
    wPtr->selectGC              = None;
322
    wPtr->anchorGC              = None;
323
    wPtr->highlightWidth        = 0;
324
    wPtr->highlightColorPtr     = NULL;
325
    wPtr->highlightGC           = None;
326
    wPtr->relief                = TK_RELIEF_FLAT;
327
    wPtr->cursor                = None;
328
    wPtr->redrawing             = 0;
329
    wPtr->resizing              = 0;
330
    wPtr->hasFocus              = 0;
331
    wPtr->selectMode            = NULL;
332
    wPtr->seeElemPtr            = NULL;
333
    wPtr->anchor                = NULL;
334
    wPtr->active                = NULL;
335
    wPtr->dropSite              = NULL;
336
    wPtr->dragSite              = NULL;
337
    wPtr->sizeCmd               = NULL;
338
    wPtr->browseCmd             = NULL;
339
    wPtr->takeFocus             = NULL;
340
    wPtr->orientUid             = NULL;
341
    wPtr->serial                = 0;
342
    wPtr->state                 = tixNormalUid;
343
    wPtr->rows                  = (ListRow*)ckalloc(sizeof(ListRow) *1);
344
    wPtr->numRow                = 1;
345
    wPtr->numRowAllocd          = 1;
346
    wPtr->width                 = 0;
347
    wPtr->height                = 0;
348
 
349
    Tix_LinkListInit(&wPtr->entList);
350
    Tix_InitScrollInfo((Tix_ScrollInfo*)&wPtr->scrollInfo[0], TIX_SCROLL_INT);
351
    Tix_InitScrollInfo((Tix_ScrollInfo*)&wPtr->scrollInfo[1], TIX_SCROLL_INT);
352
 
353
    Tk_CreateEventHandler(wPtr->dispData.tkwin,
354
        ExposureMask|StructureNotifyMask|FocusChangeMask,
355
        WidgetEventProc, (ClientData) wPtr);
356
    wPtr->widgetCmd = Tcl_CreateCommand(interp,
357
        Tk_PathName(wPtr->dispData.tkwin), WidgetCommand, (ClientData) wPtr,
358
        WidgetCmdDeletedProc);
359
 
360
    if (WidgetConfigure(interp, wPtr, argc-2, argv+2, 0) != TCL_OK) {
361
        Tk_DestroyWindow(wPtr->dispData.tkwin);
362
        return TCL_ERROR;
363
    }
364
 
365
    interp->result = Tk_PathName(wPtr->dispData.tkwin);
366
    return TCL_OK;
367
}
368
 
369
/*
370
 *----------------------------------------------------------------------
371
 *
372
 * WidgetConfigure --
373
 *
374
 *      This procedure is called to process an argv/argc list in
375
 *      conjunction with the Tk option database to configure (or
376
 *      reconfigure) a List widget.
377
 *
378
 * Results:
379
 *      The return value is a standard Tcl result.  If TCL_ERROR is
380
 *      returned, then interp->result contains an error message.
381
 *
382
 * Side effects:
383
 *      Configuration information, such as colors, border width,
384
 *      etc. get set for wPtr;  old resources get freed,
385
 *      if there were any.
386
 *
387
 *----------------------------------------------------------------------
388
 */
389
static int
390
WidgetConfigure(interp, wPtr, argc, argv, flags)
391
    Tcl_Interp *interp;                 /* Used for error reporting. */
392
    WidgetPtr wPtr;                     /* Information about widget. */
393
    int argc;                           /* Number of valid entries in argv. */
394
    char **argv;                        /* Arguments. */
395
    int flags;                          /* Flags to pass to
396
                                         * Tk_ConfigureWidget. */
397
{
398
    XGCValues gcValues;
399
    GC newGC;
400
    TixFont oldfont;
401
    size_t length;
402
    Tix_StyleTemplate stTmpl;
403
 
404
    oldfont = wPtr->font;
405
 
406
    if (Tk_ConfigureWidget(interp, wPtr->dispData.tkwin, configSpecs,
407
            argc, argv, (char *) wPtr, flags) != TCL_OK) {
408
        return TCL_ERROR;
409
    }
410
 
411
    length = strlen(wPtr->orientUid);
412
    if (strncmp(wPtr->orientUid, "vertical", length) == 0) {
413
        wPtr->isVertical = 1;
414
    } else if (strncmp(wPtr->orientUid, "horizontal", length) == 0) {
415
        wPtr->isVertical = 0;
416
    } else {
417
        Tcl_AppendResult(interp, "bad orientation \"", wPtr->orientUid,
418
            "\": must be vertical or horizontal", (char *) NULL);
419
        wPtr->orientUid = Tk_GetUid("vertical");
420
        wPtr->isVertical = 1;
421
        return TCL_ERROR;
422
    }
423
 
424
    if ((wPtr->state != tixNormalUid) && (wPtr->state != tixDisabledUid)) {
425
        Tcl_AppendResult(interp, "bad state value \"", wPtr->state,
426
            "\":  must be normal or disabled", (char *) NULL);
427
        wPtr->state = tixNormalUid;
428
        return TCL_ERROR;
429
    }
430
 
431
 
432
    if (oldfont != wPtr->font) {
433
        /* Font has been changed (initialized) */
434
        TixComputeTextGeometry(wPtr->font, "0", 1,
435
            0, &wPtr->scrollInfo[0].unit, &wPtr->scrollInfo[1].unit);
436
    }
437
 
438
    /*
439
     * A few options need special processing, such as setting the
440
     * background from a 3-D border, or filling in complicated
441
     * defaults that couldn't be specified to Tk_ConfigureWidget.
442
     */
443
 
444
    Tk_SetBackgroundFromBorder(wPtr->dispData.tkwin, wPtr->border);
445
 
446
    /*
447
     * Note: GraphicsExpose events are disabled in normalGC because it's
448
     * used to copy stuff from an off-screen pixmap onto the screen (we know
449
     * that there's no problem with obscured areas).
450
     */
451
 
452
    /* The background GC */
453
    gcValues.foreground         = wPtr->normalBg->pixel;
454
    gcValues.graphics_exposures = False;
455
 
456
    newGC = Tk_GetGC(wPtr->dispData.tkwin,
457
        GCForeground|GCGraphicsExposures, &gcValues);
458
    if (wPtr->backgroundGC != None) {
459
        Tk_FreeGC(wPtr->dispData.display, wPtr->backgroundGC);
460
    }
461
    wPtr->backgroundGC = newGC;
462
 
463
    /* The selected text GC */
464
    gcValues.font               = TixFontId(wPtr->font);
465
    gcValues.foreground         = wPtr->selectFg->pixel;
466
    gcValues.background         = Tk_3DBorderColor(wPtr->selectBorder)->pixel;
467
    gcValues.graphics_exposures = False;
468
 
469
    newGC = Tk_GetGC(wPtr->dispData.tkwin,
470
        GCForeground|GCBackground|GCFont|GCGraphicsExposures, &gcValues);
471
    if (wPtr->selectGC != None) {
472
        Tk_FreeGC(wPtr->dispData.display, wPtr->selectGC);
473
    }
474
    wPtr->selectGC = newGC;
475
 
476
    /* The dotted anchor lines */
477
    gcValues.foreground         = wPtr->normalFg->pixel;
478
    gcValues.background         = wPtr->normalBg->pixel;
479
    gcValues.graphics_exposures = False;
480
    gcValues.line_style         = LineDoubleDash;
481
    gcValues.dashes             = 2;
482
    gcValues.subwindow_mode     = IncludeInferiors;
483
 
484
    newGC = Tk_GetGC(wPtr->dispData.tkwin,
485
        GCForeground|GCBackground|GCGraphicsExposures|GCLineStyle|GCDashList|
486
        GCSubwindowMode, &gcValues);
487
    if (wPtr->anchorGC != None) {
488
        Tk_FreeGC(wPtr->dispData.display, wPtr->anchorGC);
489
    }
490
    wPtr->anchorGC = newGC;
491
 
492
    /* The highlight border */
493
    gcValues.background         = wPtr->selectFg->pixel;
494
    gcValues.foreground         = wPtr->highlightColorPtr->pixel;
495
    gcValues.graphics_exposures = False;
496
 
497
    newGC = Tk_GetGC(wPtr->dispData.tkwin,
498
        GCForeground|GCBackground|GCGraphicsExposures, &gcValues);
499
    if (wPtr->highlightGC != None) {
500
        Tk_FreeGC(wPtr->dispData.display, wPtr->highlightGC);
501
    }
502
    wPtr->highlightGC = newGC;
503
 
504
    /* We must set the options of the default styles so that
505
     * -- the default styles will change according to what is in
506
     *    stTmpl
507
     */
508
    stTmpl.font                         = wPtr->font;
509
    stTmpl.pad[0]                        = wPtr->padX;
510
    stTmpl.pad[1]                       = wPtr->padY;
511
    stTmpl.colors[TIX_DITEM_NORMAL].fg  = wPtr->normalFg;
512
    stTmpl.colors[TIX_DITEM_NORMAL].bg  = wPtr->normalBg;
513
    stTmpl.colors[TIX_DITEM_SELECTED].fg= wPtr->selectFg;
514
    stTmpl.colors[TIX_DITEM_SELECTED].bg= Tk_3DBorderColor(wPtr->selectBorder);
515
    stTmpl.flags = TIX_DITEM_FONT|TIX_DITEM_NORMAL_BG|
516
        TIX_DITEM_SELECTED_BG|TIX_DITEM_NORMAL_FG|TIX_DITEM_SELECTED_FG |
517
        TIX_DITEM_PADX|TIX_DITEM_PADY;
518
 
519
    Tix_SetDefaultStyleTemplate(wPtr->dispData.tkwin, &stTmpl);
520
 
521
    /*
522
     * Probably the -font or -width or -height options have changed. Let's
523
     * make geometry request
524
     */
525
    MakeGeomRequest(wPtr);
526
 
527
    ResizeWhenIdle(wPtr);
528
 
529
    return TCL_OK;
530
}
531
 
532
/*
533
 *--------------------------------------------------------------
534
 *
535
 * WidgetCommand --
536
 *
537
 *      This procedure is invoked to process the Tcl command
538
 *      that corresponds to a widget managed by this module.
539
 *      See the user documentation for details on what it does.
540
 *
541
 * Results:
542
 *      A standard Tcl result.
543
 *
544
 * Side effects:
545
 *      See the user documentation.
546
 *
547
 *--------------------------------------------------------------
548
 */
549
 
550
static int
551
WidgetCommand(clientData, interp, argc, argv)
552
    ClientData clientData;              /* Information about the widget. */
553
    Tcl_Interp *interp;                 /* Current interpreter. */
554
    int argc;                           /* Number of arguments. */
555
    char **argv;                        /* Argument strings. */
556
{
557
    int code;
558
 
559
    static Tix_SubCmdInfo subCmdInfo[] = {
560
        {TIX_DEFAULT_LEN, "active", 1, 2, Tix_TLSetSite,
561
           "option ?index?"},
562
        {TIX_DEFAULT_LEN, "anchor", 1, 2, Tix_TLSetSite,
563
           "option ?index?"},
564
        {TIX_DEFAULT_LEN, "cget", 1, 1, Tix_TLCGet,
565
           "option"},
566
        {TIX_DEFAULT_LEN, "configure", 0, TIX_VAR_ARGS, Tix_TLConfig,
567
           "?option? ?value? ?option value ... ?"},
568
        {TIX_DEFAULT_LEN, "delete", 1, 2, Tix_TLDelete,
569
           "from ?to?"},
570
        {TIX_DEFAULT_LEN, "dragsite", 1, 2, Tix_TLSetSite,
571
           "option ?entryPath?"},
572
        {TIX_DEFAULT_LEN, "dropsite", 1, 2, Tix_TLSetSite,
573
           "option ?entryPath?"},
574
        {TIX_DEFAULT_LEN, "entrycget", 2, 2, Tix_TLEntryCget,
575
           "entryPath option"},
576
        {TIX_DEFAULT_LEN, "entryconfigure", 1, TIX_VAR_ARGS, Tix_TLEntryConfig,
577
           "index ?option? ?value? ?option value ... ?"},
578
        {TIX_DEFAULT_LEN, "geometryinfo", 0, 2, Tix_TLGeometryInfo,
579
           "?width height?"},
580
        {TIX_DEFAULT_LEN, "index", 1, 1, Tix_TLIndex,
581
           "index"},
582
        {TIX_DEFAULT_LEN, "info", 1, TIX_VAR_ARGS, Tix_TLInfo,
583
           "option ?args ...?"},
584
        {TIX_DEFAULT_LEN, "insert", 1, TIX_VAR_ARGS, Tix_TLInsert,
585
           "where ?option value ..."},
586
        {TIX_DEFAULT_LEN, "nearest", 2, 2, Tix_TLNearest,
587
           "x y"},
588
        {TIX_DEFAULT_LEN, "see", 1, 1, Tix_TLSee,
589
           "entryPath"},
590
        {TIX_DEFAULT_LEN, "selection", 1, 3, Tix_TLSelection,
591
           "option arg ?arg ...?"},
592
        {TIX_DEFAULT_LEN, "xview", 0, 3, Tix_TLView,
593
           "args"},
594
        {TIX_DEFAULT_LEN, "yview", 0, 3, Tix_TLView,
595
           "args"},
596
    };
597
 
598
    static Tix_CmdInfo cmdInfo = {
599
        Tix_ArraySize(subCmdInfo), 1, TIX_VAR_ARGS, "?option? arg ?arg ...?",
600
    };
601
 
602
    Tk_Preserve(clientData);
603
    code = Tix_HandleSubCmds(&cmdInfo, subCmdInfo, clientData,
604
        interp, argc, argv);
605
    Tk_Release(clientData);
606
 
607
    return code;
608
}
609
 
610
/*
611
 *--------------------------------------------------------------
612
 *
613
 * WidgetEventProc --
614
 *
615
 *      This procedure is invoked by the Tk dispatcher for various
616
 *      events on Lists.
617
 *
618
 * Results:
619
 *      None.
620
 *
621
 * Side effects:
622
 *      When the window gets deleted, internal structures get
623
 *      cleaned up.  When it gets exposed, it is redisplayed.
624
 *
625
 *--------------------------------------------------------------
626
 */
627
static void
628
WidgetEventProc(clientData, eventPtr)
629
    ClientData clientData;      /* Information about window. */
630
    XEvent *eventPtr;           /* Information about event. */
631
{
632
    WidgetPtr wPtr = (WidgetPtr) clientData;
633
 
634
    switch (eventPtr->type) {
635
      case DestroyNotify:
636
        if (wPtr->dispData.tkwin != NULL) {
637
            wPtr->dispData.tkwin = NULL;
638
            Tcl_DeleteCommand(wPtr->dispData.interp,
639
                Tcl_GetCommandName(wPtr->dispData.interp, wPtr->widgetCmd));
640
        }
641
        CancelResizeWhenIdle(wPtr);
642
        CancelRedrawWhenIdle(wPtr);
643
        Tk_EventuallyFree((ClientData) wPtr, (Tix_FreeProc*)WidgetDestroy);
644
        break;
645
 
646
      case ConfigureNotify:
647
        ResizeWhenIdle(wPtr);
648
        break;
649
 
650
      case Expose:
651
        RedrawWhenIdle(wPtr);
652
        break;
653
 
654
      case FocusIn:
655
        wPtr->hasFocus = 1;
656
        RedrawWhenIdle(wPtr);
657
        break;
658
 
659
      case FocusOut:
660
        wPtr->hasFocus = 0;
661
        RedrawWhenIdle(wPtr);
662
        break;
663
    }
664
}
665
 
666
/*
667
 *----------------------------------------------------------------------
668
 *
669
 * WidgetDestroy --
670
 *
671
 *      This procedure is invoked by Tk_EventuallyFree or Tk_Release
672
 *      to clean up the internal structure of a List at a safe time
673
 *      (when no-one is using it anymore).
674
 *
675
 * Results:
676
 *      None.
677
 *
678
 * Side effects:
679
 *      Everything associated with the List is freed up.
680
 *
681
 *----------------------------------------------------------------------
682
 */
683
 
684
static void
685
WidgetDestroy(clientData)
686
    ClientData clientData;      /* Info about my widget. */
687
{
688
    WidgetPtr wPtr = (WidgetPtr) clientData;
689
 
690
 
691
    if (wPtr->backgroundGC != None) {
692
        Tk_FreeGC(wPtr->dispData.display, wPtr->backgroundGC);
693
    }
694
    if (wPtr->selectGC != None) {
695
        Tk_FreeGC(wPtr->dispData.display, wPtr->selectGC);
696
    }
697
    if (wPtr->anchorGC != None) {
698
        Tk_FreeGC(wPtr->dispData.display, wPtr->anchorGC);
699
    }
700
    if (wPtr->highlightGC != None) {
701
        Tk_FreeGC(wPtr->dispData.display, wPtr->highlightGC);
702
    }
703
 
704
    if (wPtr->entList.numItems > 0) {
705
        ListEntry * fromPtr=NULL, *toPtr=NULL;
706
        char * argv[2];
707
        argv[0] = "0";
708
        argv[1] = "end";
709
 
710
        Tix_TLGetFromTo(wPtr->dispData.interp, wPtr, 2, argv, &fromPtr,&toPtr);
711
        Tcl_ResetResult(wPtr->dispData.interp);
712
 
713
        if (fromPtr && toPtr) {
714
            Tix_TLDeleteRange(wPtr, fromPtr, toPtr);
715
        }
716
    }
717
 
718
    if (wPtr->rows) {
719
        ckfree((char*)wPtr->rows);
720
    }
721
 
722
    Tk_FreeOptions(configSpecs, (char *) wPtr, wPtr->dispData.display, 0);
723
    ckfree((char *) wPtr);
724
}
725
 
726
/*
727
 *----------------------------------------------------------------------
728
 *
729
 * WidgetCmdDeletedProc --
730
 *
731
 *      This procedure is invoked when a widget command is deleted.  If
732
 *      the widget isn't already in the process of being destroyed,
733
 *      this command destroys it.
734
 *
735
 * Results:
736
 *      None.
737
 *
738
 * Side effects:
739
 *      The widget is destroyed.
740
 *
741
 *----------------------------------------------------------------------
742
 */
743
static void
744
WidgetCmdDeletedProc(clientData)
745
    ClientData clientData;      /* Pointer to widget record for widget. */
746
{
747
    WidgetPtr wPtr = (WidgetPtr) clientData;
748
 
749
    /*
750
     * This procedure could be invoked either because the window was
751
     * destroyed and the command was then deleted (in which case tkwin
752
     * is NULL) or because the command was deleted, and then this procedure
753
     * destroys the widget.
754
     */
755
    if (wPtr->dispData.tkwin != NULL) {
756
        Tk_Window tkwin = wPtr->dispData.tkwin;
757
        wPtr->dispData.tkwin = NULL;
758
        Tk_DestroyWindow(tkwin);
759
    }
760
}
761
 
762
/*
763
 *--------------------------------------------------------------
764
 *
765
 * WidgetComputeGeometry --
766
 *
767
 *      This procedure is invoked to process the Tcl command
768
 *      that corresponds to a widget managed by this module.
769
 *      See the user documentation for details on what it does.
770
 *
771
 * Results:
772
 *      A standard Tcl result.
773
 *
774
 * Side effects:
775
 *      none
776
 *
777
 *--------------------------------------------------------------
778
 */
779
static void
780
WidgetComputeGeometry(clientData)
781
    ClientData clientData;
782
{
783
    WidgetPtr wPtr = (WidgetPtr)clientData;
784
    int winW, winH;
785
    Tk_Window tkwin = wPtr->dispData.tkwin;
786
 
787
    wPtr->resizing = 0;
788
 
789
    winW = Tk_Width(tkwin)  - 2*wPtr->highlightWidth - 2*wPtr->borderWidth;
790
    winH = Tk_Height(tkwin) - 2*wPtr->highlightWidth - 2*wPtr->borderWidth;
791
 
792
    ResizeRows(wPtr, winW, winH);
793
    /* Update scrollbars */
794
    UpdateScrollBars(wPtr, 1);
795
 
796
    RedrawWhenIdle(wPtr);
797
}
798
 
799
static void
800
MakeGeomRequest(wPtr)
801
    WidgetPtr wPtr;
802
{
803
    int reqW, reqH;
804
 
805
    reqW = wPtr->width  * wPtr->scrollInfo[0].unit;
806
    reqH = wPtr->height * wPtr->scrollInfo[1].unit;
807
 
808
    Tk_GeometryRequest(wPtr->dispData.tkwin, reqW, reqH);
809
}
810
 
811
 
812
 
813
/*----------------------------------------------------------------------
814
 * DItemSizeChanged --
815
 *
816
 *      This is called whenever the size of one of the HList's items
817
 *      changes its size.
818
 *----------------------------------------------------------------------
819
 */
820
static void
821
Tix_TLDItemSizeChanged(iPtr)
822
    Tix_DItem *iPtr;
823
{
824
    WidgetPtr wPtr = (WidgetPtr)iPtr->base.clientData;
825
 
826
    if (wPtr) {
827
        /* double-check: perhaps we haven't set the clientData yet! */
828
        ResizeWhenIdle(wPtr);
829
    }
830
}
831
 
832
/*
833
 *----------------------------------------------------------------------
834
 * ResizeWhenIdle --
835
 *----------------------------------------------------------------------
836
 */
837
static void
838
ResizeWhenIdle(wPtr)
839
    WidgetPtr wPtr;
840
{
841
    if (wPtr->redrawing) {
842
        CancelRedrawWhenIdle(wPtr);
843
    }
844
    if (!wPtr->resizing) {
845
        wPtr->resizing = 1;
846
        Tk_DoWhenIdle(WidgetComputeGeometry, (ClientData)wPtr);
847
    }
848
}
849
 
850
/*
851
 *----------------------------------------------------------------------
852
 * ResizeWhenIdle --
853
 *----------------------------------------------------------------------
854
 */
855
static void
856
ResizeNow(wPtr)
857
    WidgetPtr wPtr;
858
{
859
    if (wPtr->resizing) {
860
        Tk_CancelIdleCall(WidgetComputeGeometry, (ClientData)wPtr);
861
 
862
        WidgetComputeGeometry((ClientData)wPtr);
863
        wPtr->resizing = 0;
864
    }
865
}
866
 
867
/*
868
 *----------------------------------------------------------------------
869
 * CancelResizeWhenIdle --
870
 *----------------------------------------------------------------------
871
 */
872
static void
873
CancelResizeWhenIdle(wPtr)
874
    WidgetPtr wPtr;
875
{
876
    if (wPtr->resizing) {
877
        wPtr->resizing = 0;
878
        Tk_CancelIdleCall(WidgetComputeGeometry, (ClientData)wPtr);
879
    }
880
}
881
 
882
/*
883
 *----------------------------------------------------------------------
884
 * RedrawWhenIdle --
885
 *----------------------------------------------------------------------
886
 */
887
static void
888
RedrawWhenIdle(wPtr)
889
    WidgetPtr wPtr;
890
{
891
    if (wPtr->resizing) {
892
        /*
893
         * Resize will eventually call redraw.
894
         */
895
        return;
896
    }
897
    if (!wPtr->redrawing && Tk_IsMapped(wPtr->dispData.tkwin)) {
898
        wPtr->redrawing = 1;
899
        Tk_DoWhenIdle(WidgetDisplay, (ClientData)wPtr);
900
    }
901
}
902
 
903
/*
904
 *----------------------------------------------------------------------
905
 * CancelRedrawWhenIdle --
906
 *----------------------------------------------------------------------
907
 */
908
static void
909
CancelRedrawWhenIdle(wPtr)
910
    WidgetPtr wPtr;
911
{
912
    if (wPtr->redrawing) {
913
        wPtr->redrawing = 0;
914
        Tk_CancelIdleCall(WidgetDisplay, (ClientData)wPtr);
915
    }
916
}
917
 
918
/*
919
 *----------------------------------------------------------------------
920
 *
921
 * WidgetDisplay --
922
 *
923
 *      Draw the widget to the screen.
924
 *
925
 * Results:
926
 *      None.
927
 *
928
 * Side effects:
929
 *
930
 *----------------------------------------------------------------------
931
 */
932
static void
933
WidgetDisplay(clientData)
934
    ClientData clientData;      /* Info about my widget. */
935
{
936
    WidgetPtr wPtr = (WidgetPtr) clientData;
937
    Pixmap pixmap;
938
    Tk_Window tkwin = wPtr->dispData.tkwin;
939
    int winH, winW;
940
 
941
    wPtr->redrawing = 0;         /* clear the redraw flag */
942
    wPtr->serial ++;
943
 
944
    pixmap = Tk_GetPixmap(wPtr->dispData.display, Tk_WindowId(tkwin),
945
        Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
946
 
947
    /* Fill the background */
948
    XFillRectangle(wPtr->dispData.display, pixmap, wPtr->backgroundGC,
949
        0, 0, Tk_Width(tkwin), Tk_Height(tkwin));
950
 
951
    winW = Tk_Width(tkwin)  - 2*wPtr->highlightWidth - 2*wPtr->borderWidth;
952
    winH = Tk_Height(tkwin) - 2*wPtr->highlightWidth - 2*wPtr->borderWidth;
953
 
954
    if (winW > 0 && winH > 0) {
955
        RedrawRows(wPtr, pixmap);
956
    }
957
 
958
    /* Draw the border */
959
    Tk_Draw3DRectangle(wPtr->dispData.tkwin, pixmap, wPtr->border,
960
        wPtr->highlightWidth, wPtr->highlightWidth,
961
        Tk_Width(tkwin)  - 2*wPtr->highlightWidth,
962
        Tk_Height(tkwin) - 2*wPtr->highlightWidth, wPtr->borderWidth,
963
        wPtr->relief);
964
 
965
    /* Draw the highlight */
966
    if (wPtr->highlightWidth > 0) {
967
        GC gc;
968
 
969
        if (wPtr->hasFocus) {
970
            gc = wPtr->highlightGC;
971
        } else {
972
            gc = Tk_3DBorderGC(wPtr->dispData.tkwin, wPtr->border,
973
                TK_3D_FLAT_GC);
974
        }
975
        Tk_DrawFocusHighlight(tkwin, gc, wPtr->highlightWidth, pixmap);
976
    }
977
 
978
    /*
979
     * Copy the information from the off-screen pixmap onto the screen,
980
     * then delete the pixmap.
981
     */
982
    XCopyArea(wPtr->dispData.display, pixmap, Tk_WindowId(tkwin),
983
        wPtr->backgroundGC, 0, 0, Tk_Width(tkwin), Tk_Height(tkwin), 0, 0);
984
    Tk_FreePixmap(wPtr->dispData.display, pixmap);
985
 
986
}
987
 
988
/*----------------------------------------------------------------------
989
 *  AddElement  --
990
 *
991
 *      Add the element at the position indicated by "at".
992
 *----------------------------------------------------------------------
993
 */
994
static int
995
AddElement(wPtr, chPtr, at)
996
    WidgetPtr wPtr;
997
    ListEntry * chPtr;
998
    int at;
999
{
1000
    if (at >= wPtr->entList.numItems) {
1001
        /* The "end" position */
1002
        Tix_LinkListAppend(&entListInfo, &wPtr->entList, (char*)chPtr, 0);
1003
    }
1004
    else {
1005
        Tix_ListIterator li;
1006
        Tix_LinkListIteratorInit(&li);
1007
 
1008
        for (Tix_LinkListStart(&entListInfo, &wPtr->entList, &li);
1009
             !Tix_LinkListDone(&li);
1010
             Tix_LinkListNext (&entListInfo, &wPtr->entList, &li)) {
1011
 
1012
            if (at == 0) {
1013
                Tix_LinkListInsert(&entListInfo, &wPtr->entList,
1014
                    (char*)chPtr, &li);
1015
                break;
1016
            } else {
1017
                -- at;
1018
            }
1019
        }
1020
    }
1021
 
1022
    return TCL_OK;
1023
}
1024
 
1025
/*----------------------------------------------------------------------
1026
 *  AllocEntry  --
1027
 *
1028
 *      Allocates memory for a new entry and initializes it to a
1029
 *      proper state.
1030
 *----------------------------------------------------------------------
1031
 */
1032
static ListEntry *
1033
AllocEntry(wPtr)
1034
    WidgetPtr wPtr;
1035
{
1036
    ListEntry * chPtr;
1037
 
1038
    chPtr = (ListEntry *)ckalloc(sizeof(ListEntry));
1039
    chPtr->state        = NULL;
1040
    chPtr->selected     = 0;
1041
    chPtr->iPtr         = NULL;
1042
 
1043
    return chPtr;
1044
}
1045
 
1046
/*----------------------------------------------------------------------
1047
 *  FreeEntry  --
1048
 *
1049
 *      Free the entry and all resources allocated to this entry.
1050
 *      This entry must already be deleted from the list.
1051
 *----------------------------------------------------------------------
1052
 */
1053
static void
1054
FreeEntry(wPtr, chPtr)
1055
    WidgetPtr wPtr;
1056
    ListEntry * chPtr;
1057
{
1058
 
1059
    if (wPtr->seeElemPtr == chPtr) {
1060
        /*
1061
         * This is the element that should be visible the next time
1062
         * we draw the window. Adjust the "to see element" to an element
1063
         * that is close to it.
1064
         */
1065
        if (chPtr->next != NULL) {
1066
            wPtr->seeElemPtr = chPtr->next;
1067
        } else {
1068
            ListEntry *p;
1069
 
1070
            wPtr->seeElemPtr = NULL;
1071
            for (p=(ListEntry*)wPtr->entList.head; p; p=p->next) {
1072
                if (p->next == chPtr) {
1073
                    wPtr->seeElemPtr = p;
1074
                    break;
1075
                }
1076
            }
1077
        }
1078
    }
1079
 
1080
    if (wPtr->anchor == chPtr) {
1081
        wPtr->anchor = NULL;
1082
    }
1083
    if (wPtr->active == chPtr) {
1084
        wPtr->active = NULL;
1085
    }
1086
    if (wPtr->dragSite == chPtr) {
1087
        wPtr->dragSite = NULL;
1088
    }
1089
    if (wPtr->dropSite == chPtr) {
1090
        wPtr->dropSite = NULL;
1091
    }
1092
 
1093
    if (chPtr->iPtr != NULL) {
1094
        if (Tix_DItemType(chPtr->iPtr) == TIX_DITEM_WINDOW) {
1095
#if 0
1096
            Tix_WindowItemListRemove(&wPtr->mappedWindows,
1097
                chPtr->iPtr);
1098
#endif
1099
        }
1100
        Tix_DItemFree(chPtr->iPtr);
1101
    }
1102
 
1103
    Tk_FreeOptions(entryConfigSpecs, (char *)chPtr,wPtr->dispData.display, 0);
1104
    ckfree((char*)chPtr);
1105
}
1106
 
1107
/*----------------------------------------------------------------------
1108
 * "insert" sub command --
1109
 *
1110
 *      Insert a new item into the list
1111
 *----------------------------------------------------------------------
1112
 */
1113
static int
1114
Tix_TLInsert(clientData, interp, argc, argv)
1115
    ClientData clientData;
1116
    Tcl_Interp *interp;         /* Current interpreter. */
1117
    int argc;                   /* Number of arguments. */
1118
    char **argv;                /* Argument strings. */
1119
{
1120
    WidgetPtr wPtr = (WidgetPtr) clientData;
1121
    ListEntry * chPtr = NULL;
1122
    char buff[40];
1123
    char * ditemType;
1124
    int at;
1125
    int added = 0;
1126
    int code = TCL_OK;
1127
 
1128
    /*------------------------------------------------------------
1129
     * (1) We need to determine the options:
1130
     *     -itemtype and -at.
1131
     *------------------------------------------------------------
1132
     */
1133
 
1134
    /* (1.1) Find out where */
1135
    if (Tix_TranslateIndex(wPtr, interp, argv[0], &at, 1) != TCL_OK) {
1136
        code = TCL_ERROR; goto done;
1137
    }
1138
 
1139
    /* (1.2) Find out the -itemtype, if specified */
1140
    ditemType = wPtr->diTypePtr->name;                   /* default value */
1141
    if (argc > 1) {
1142
        size_t len;
1143
        int i;
1144
        if (argc %2 != 1) {
1145
            Tcl_AppendResult(interp, "value for \"", argv[argc-1],
1146
                "\" missing", NULL);
1147
            code = TCL_ERROR; goto done;
1148
        }
1149
        for (i=1; i<argc; i+=2) {
1150
            len = strlen(argv[i]);
1151
            if (strncmp(argv[i], "-itemtype", len) == 0) {
1152
                ditemType = argv[i+1];
1153
            }
1154
        }
1155
    }
1156
 
1157
    if (Tix_GetDItemType(interp, ditemType) == NULL) {
1158
        code = TCL_ERROR; goto done;
1159
    }
1160
 
1161
    /*
1162
     * (2) Allocate a new entry
1163
     */
1164
    chPtr = AllocEntry(wPtr);
1165
 
1166
    /* (2.1) The Display item data */
1167
    if ((chPtr->iPtr = Tix_DItemCreate(&wPtr->dispData, ditemType)) == NULL) {
1168
        code = TCL_ERROR; goto done;
1169
    }
1170
    chPtr->iPtr->base.clientData = (ClientData)wPtr;
1171
    chPtr->size[0] = chPtr->iPtr->base.size[0];
1172
    chPtr->size[1] = chPtr->iPtr->base.size[1];
1173
 
1174
    /*
1175
     * (3) Add the entry into the list
1176
     */
1177
    if (AddElement(wPtr, chPtr, at) != TCL_OK) {
1178
        code = TCL_ERROR; goto done;
1179
    } else {
1180
        added = 1;
1181
    }
1182
 
1183
    if (ConfigElement(wPtr, chPtr, argc-1, argv+1, 0, 1) != TCL_OK) {
1184
        code = TCL_ERROR; goto done;
1185
    }
1186
 
1187
    ResizeWhenIdle(wPtr);
1188
 
1189
  done:
1190
    if (code == TCL_ERROR) {
1191
        if (chPtr != NULL) {
1192
            if (added) {
1193
                Tix_LinkListFindAndDelete(&entListInfo, &wPtr->entList,
1194
                    (char*)chPtr, NULL);
1195
            }
1196
            FreeEntry(wPtr, chPtr);
1197
        }
1198
    } else {
1199
        sprintf(buff, "%d", at);
1200
        Tcl_AppendResult(interp, buff, NULL);
1201
    }
1202
 
1203
    return code;
1204
}
1205
 
1206
static int
1207
Tix_TLSpecialEntryInfo(wPtr, interp, chPtr)
1208
    WidgetPtr wPtr;
1209
    Tcl_Interp *interp;
1210
    ListEntry * chPtr;
1211
{
1212
    char buff[100];
1213
 
1214
    if (chPtr) {
1215
        int i;
1216
        Tix_ListIterator li;
1217
 
1218
        Tix_LinkListIteratorInit(&li);
1219
 
1220
        for (i=0,Tix_LinkListStart(&entListInfo, &wPtr->entList, &li);
1221
             !Tix_LinkListDone(&li);
1222
             Tix_LinkListNext(&entListInfo, &wPtr->entList, &li),i++) {
1223
            if (li.curr == (char*)chPtr) {
1224
                break;
1225
            }
1226
        }
1227
        if (li.curr != NULL) {
1228
            sprintf(buff, "%d", i);
1229
            Tcl_AppendResult(interp, buff, NULL);
1230
        } else {
1231
            panic("TList list entry is invalid");
1232
        }
1233
    } else {
1234
        Tcl_ResetResult(interp);
1235
    }
1236
    return TCL_OK;
1237
}
1238
 
1239
/*----------------------------------------------------------------------
1240
 * "index" sub command
1241
 *----------------------------------------------------------------------
1242
 */
1243
static int
1244
Tix_TLIndex(clientData, interp, argc, argv)
1245
    ClientData clientData;      /* TList widget record. */
1246
    Tcl_Interp *interp;         /* Current interpreter. */
1247
    int argc;                   /* Number of arguments. */
1248
    char **argv;                /* Argument strings. */
1249
{
1250
    WidgetPtr wPtr = (WidgetPtr) clientData;
1251
    int index;
1252
    char buff[100];
1253
 
1254
    if (Tix_TranslateIndex(wPtr, interp, argv[0], &index, 0) != TCL_OK) {
1255
        return TCL_ERROR;
1256
    }
1257
 
1258
    sprintf(buff, "%d", index);
1259
    Tcl_AppendResult(interp, buff, NULL);
1260
    return TCL_OK;
1261
}
1262
 
1263
/*----------------------------------------------------------------------
1264
 * "info" sub command
1265
 *----------------------------------------------------------------------
1266
 */
1267
static int
1268
Tix_TLInfo(clientData, interp, argc, argv)
1269
    ClientData clientData;
1270
    Tcl_Interp *interp;         /* Current interpreter. */
1271
    int argc;                   /* Number of arguments. */
1272
    char **argv;                /* Argument strings. */
1273
{
1274
    WidgetPtr wPtr = (WidgetPtr) clientData;
1275
    size_t len = strlen(argv[0]);
1276
 
1277
    if (strncmp(argv[0], "anchor", len)==0) {
1278
        return Tix_TLSpecialEntryInfo(wPtr, interp, wPtr->anchor);
1279
    }
1280
    else if (strncmp(argv[0], "active", len)==0) {
1281
        return Tix_TLSpecialEntryInfo(wPtr, interp, wPtr->active);
1282
    }
1283
    else if (strncmp(argv[0], "down", len)==0) {
1284
        return Tix_TLGetNeighbor(wPtr, interp, TIX_DOWN,  argc-1, argv+1);
1285
    }
1286
    else if (strncmp(argv[0], "left", len)==0) {
1287
        return Tix_TLGetNeighbor(wPtr, interp, TIX_LEFT,  argc-1, argv+1);
1288
    }
1289
    else if (strncmp(argv[0], "right", len)==0) {
1290
        return Tix_TLGetNeighbor(wPtr, interp, TIX_RIGHT, argc-1, argv+1);
1291
    }
1292
    else if (strncmp(argv[0], "selection", len)==0) {
1293
        ListEntry *chPtr;
1294
        int i;
1295
        char buffer[32];
1296
 
1297
        for (chPtr=(ListEntry*)wPtr->entList.head, i=0;
1298
             chPtr;
1299
             chPtr=chPtr->next, i++) {
1300
 
1301
            if (chPtr->selected) {
1302
                if (i) {
1303
                    Tcl_AppendResult(interp, " ", (char *) NULL);
1304
                }
1305
                sprintf(buffer, "%d", i);
1306
                Tcl_AppendResult(interp, buffer, (char *) NULL);
1307
            }
1308
        }
1309
        return TCL_OK;
1310
    }
1311
    else if (strncmp(argv[0], "size", len)==0) {
1312
        char buff[100];
1313
 
1314
        sprintf(buff, "%d", wPtr->entList.numItems);
1315
        Tcl_AppendResult(interp, buff, NULL);
1316
 
1317
        return TCL_OK;
1318
    }
1319
    else if (strncmp(argv[0], "up", len)==0) {
1320
        return Tix_TLGetNeighbor(wPtr, interp, TIX_UP,    argc-1, argv+1);
1321
    }
1322
    else {
1323
        Tcl_AppendResult(interp, "unknown option \"", argv[0],
1324
            "\": must be anchor or selection",
1325
            NULL);
1326
        return TCL_ERROR;
1327
    }
1328
}
1329
 
1330
static int
1331
Tix_TranslateIndex(wPtr, interp, string, index, isInsert)
1332
    WidgetPtr wPtr;             /* TList widget record. */
1333
    Tcl_Interp *interp;         /* Current interpreter. */
1334
    char * string;              /* String representation of the index. */
1335
    int * index;                /* Returns the index value(0 = 1st element).*/
1336
    int isInsert;               /* Is this function called by an "insert"
1337
                                 * operation? */
1338
{
1339
    if (strcmp(string, "end") == 0) {
1340
        *index = wPtr->entList.numItems;
1341
    }
1342
    else if (Tix_TLGetAt(wPtr, interp, string, index) != TCL_OK) {
1343
        if (Tcl_GetInt(interp, string, index) != TCL_OK) {
1344
            return TCL_ERROR;
1345
        }
1346
        else if (*index < 0) {
1347
            Tcl_AppendResult(interp,"expected non-negative integer but got \"",
1348
                string, "\"", NULL);
1349
            return TCL_ERROR;
1350
        }
1351
    }
1352
 
1353
 
1354
    /*
1355
     * The meaning of "end" means:
1356
     *     isInsert:wPtr->entList.numItems
1357
     *    !isInsert:wPtr->entList.numItems-1;
1358
     */
1359
 
1360
    if (isInsert) {
1361
        if (*index > wPtr->entList.numItems) {
1362
            /*
1363
             * By default add it to the end, just to follow what TK
1364
             * does for the Listbox widget
1365
             */
1366
            *index = wPtr->entList.numItems;
1367
        }
1368
    } else {
1369
        if (*index >= wPtr->entList.numItems) {
1370
            /*
1371
             * By default add it to the end, just to follow what TK
1372
             * does for the Listbox widget
1373
             */
1374
            *index = wPtr->entList.numItems - 1;
1375
        }
1376
    }
1377
 
1378
    if (*index < 0) {
1379
        *index = 0;
1380
    }
1381
 
1382
    return TCL_OK;
1383
}
1384
 
1385
static int Tix_TLGetNeighbor(wPtr, interp, type, argc, argv)
1386
    WidgetPtr wPtr;
1387
    Tcl_Interp *interp;         /* Current interpreter. */
1388
    int type;
1389
    int argc;                   /* Number of arguments. */
1390
    char **argv;                /* Argument strings. */
1391
{
1392
    int index;
1393
    int dst;
1394
    int xStep, yStep;
1395
    int numPerRow;
1396
    char buff[100];
1397
 
1398
    if (argc != 1) {
1399
        Tix_ArgcError(interp, argc+3, argv-3, 3, "index");
1400
    }
1401
 
1402
    if (Tix_TranslateIndex(wPtr, interp, argv[0], &index, 0) != TCL_OK) {
1403
        return TCL_ERROR;
1404
    }
1405
 
1406
    if (wPtr->entList.numItems == 0) {
1407
        Tcl_ResetResult(interp);
1408
        return TCL_OK;
1409
    }
1410
 
1411
    numPerRow = wPtr->rows[0].numEnt;
1412
 
1413
    if (wPtr->isVertical) {
1414
        xStep = numPerRow;
1415
        yStep = 1;
1416
    } else {
1417
        xStep = 1;
1418
        yStep = numPerRow;
1419
    }
1420
 
1421
    switch (type) {
1422
      case TIX_UP:
1423
        dst = index - yStep;
1424
        break;
1425
      case TIX_DOWN:
1426
        dst = index + yStep;
1427
        break;
1428
      case TIX_LEFT:
1429
        dst = index - xStep;
1430
        break;
1431
      case TIX_RIGHT:
1432
        dst = index + xStep;
1433
        break;
1434
    }
1435
 
1436
    if (dst < 0) {
1437
        dst = index;
1438
    } else if (dst >= wPtr->entList.numItems) {
1439
        dst = index;
1440
    }
1441
 
1442
    sprintf(buff, "%d", dst);
1443
    Tcl_AppendResult(interp, buff, NULL);
1444
 
1445
    return TCL_OK;
1446
}
1447
 
1448
 
1449
 
1450
/*----------------------------------------------------------------------
1451
 * "cget" sub command --
1452
 *----------------------------------------------------------------------
1453
 */
1454
static int
1455
Tix_TLCGet(clientData, interp, argc, argv)
1456
    ClientData clientData;
1457
    Tcl_Interp *interp;         /* Current interpreter. */
1458
    int argc;                   /* Number of arguments. */
1459
    char **argv;                /* Argument strings. */
1460
{
1461
    WidgetPtr wPtr = (WidgetPtr) clientData;
1462
 
1463
    return Tk_ConfigureValue(interp, wPtr->dispData.tkwin, configSpecs,
1464
        (char *)wPtr, argv[0], 0);
1465
}
1466
 
1467
/*----------------------------------------------------------------------
1468
 * "configure" sub command
1469
 *----------------------------------------------------------------------
1470
 */
1471
static int
1472
Tix_TLConfig(clientData, interp, argc, argv)
1473
    ClientData clientData;
1474
    Tcl_Interp *interp;         /* Current interpreter. */
1475
    int argc;                   /* Number of arguments. */
1476
    char **argv;                /* Argument strings. */
1477
{
1478
    WidgetPtr wPtr = (WidgetPtr) clientData;
1479
 
1480
    if (argc == 0) {
1481
        return Tk_ConfigureInfo(interp, wPtr->dispData.tkwin, configSpecs,
1482
            (char *) wPtr, (char *) NULL, 0);
1483
    } else if (argc == 1) {
1484
        return Tk_ConfigureInfo(interp, wPtr->dispData.tkwin, configSpecs,
1485
            (char *) wPtr, argv[0], 0);
1486
    } else {
1487
        return WidgetConfigure(interp, wPtr, argc, argv,
1488
            TK_CONFIG_ARGV_ONLY);
1489
    }
1490
}
1491
 
1492
/*----------------------------------------------------------------------
1493
 * "geometryinfo" sub command
1494
 *----------------------------------------------------------------------
1495
 */
1496
static int
1497
Tix_TLGeometryInfo(clientData, interp, argc, argv)
1498
    ClientData clientData;
1499
    Tcl_Interp *interp;         /* Current interpreter. */
1500
    int argc;                   /* Number of arguments. */
1501
    char **argv;                /* Argument strings. */
1502
{
1503
    WidgetPtr wPtr = (WidgetPtr) clientData;
1504
    int qSize[2];
1505
    double first[2], last[2];
1506
    char string[40];
1507
    int i;
1508
 
1509
    if (argc == 2) {
1510
        if (Tcl_GetInt(interp, argv[0], &qSize[0]) != TCL_OK) {
1511
            return TCL_ERROR;
1512
        }
1513
        if (Tcl_GetInt(interp, argv[1], &qSize[1]) != TCL_OK) {
1514
            return TCL_ERROR;
1515
        }
1516
    } else {
1517
        qSize[0] = Tk_Width (wPtr->dispData.tkwin);
1518
        qSize[1] = Tk_Height(wPtr->dispData.tkwin);
1519
    }
1520
    qSize[0] -= 2*wPtr->borderWidth + 2*wPtr->highlightWidth;
1521
    qSize[1] -= 2*wPtr->borderWidth + 2*wPtr->highlightWidth;
1522
 
1523
    for (i=0; i<2; i++) {
1524
        qSize[i] -= 2*wPtr->borderWidth + 2*wPtr->highlightWidth;
1525
        Tix_GetScrollFractions((Tix_ScrollInfo*)&wPtr->scrollInfo[i],
1526
            &first[i], &last[i]);
1527
    }
1528
 
1529
    sprintf(string, "{%f %f} {%f %f}", first[0], last[0], first[1], last[1]);
1530
    Tcl_AppendResult(interp, string, NULL);
1531
 
1532
    return TCL_OK;
1533
}
1534
 
1535
/*----------------------------------------------------------------------
1536
 * "delete" sub command
1537
 *----------------------------------------------------------------------
1538
 */
1539
static int
1540
Tix_TLDelete(clientData, interp, argc, argv)
1541
    ClientData clientData;
1542
    Tcl_Interp *interp;         /* Current interpreter. */
1543
    int argc;                   /* Number of arguments. */
1544
    char **argv;                /* Argument strings. */
1545
{
1546
    WidgetPtr wPtr = (WidgetPtr) clientData;
1547
    ListEntry * fromPtr, *toPtr;
1548
    int code = TCL_OK;
1549
 
1550
    if (argc < 1 || argc > 2) {
1551
        Tix_ArgcError(interp, argc+2, argv-2, 2, "from ?to?");
1552
        code = TCL_ERROR;
1553
        goto done;
1554
    }
1555
 
1556
    if (Tix_TLGetFromTo(interp, wPtr, argc, argv, &fromPtr, &toPtr)!= TCL_OK) {
1557
        code = TCL_ERROR;
1558
        goto done;
1559
    }
1560
    if (fromPtr == NULL) {
1561
        goto done;
1562
    }
1563
 
1564
    if (Tix_TLDeleteRange(wPtr, fromPtr, toPtr)) {
1565
        ResizeWhenIdle(wPtr);
1566
    }
1567
 
1568
  done:
1569
    return code;
1570
}
1571
 
1572
/* returns true if some element has been deleted */
1573
static int Tix_TLDeleteRange(wPtr, fromPtr, toPtr)
1574
    WidgetPtr wPtr;
1575
    ListEntry * fromPtr;
1576
    ListEntry *toPtr;
1577
{
1578
    int started;
1579
    Tix_ListIterator li;
1580
 
1581
    Tix_LinkListIteratorInit(&li);
1582
    started = 0;
1583
    for (Tix_LinkListStart(&entListInfo, &wPtr->entList, &li);
1584
         !Tix_LinkListDone(&li);
1585
         Tix_LinkListNext (&entListInfo, &wPtr->entList, &li)) {
1586
 
1587
        ListEntry * curr = (ListEntry *)li.curr;
1588
        if (curr == fromPtr) {
1589
            started = 1;
1590
        }
1591
        if (started) {
1592
            Tix_LinkListDelete(&entListInfo, &wPtr->entList, &li);
1593
            FreeEntry(wPtr, curr);
1594
        }
1595
        if (curr == toPtr) {
1596
            break;
1597
        }
1598
    }
1599
 
1600
    return started;
1601
}
1602
 
1603
 
1604
/*----------------------------------------------------------------------
1605
 * "entrycget" sub command
1606
 *----------------------------------------------------------------------
1607
 */
1608
static int
1609
Tix_TLEntryCget(clientData, interp, argc, argv)
1610
    ClientData clientData;
1611
    Tcl_Interp *interp;         /* Current interpreter. */
1612
    int argc;                   /* Number of arguments. */
1613
    char **argv;                /* Argument strings. */
1614
{
1615
    WidgetPtr wPtr = (WidgetPtr) clientData;
1616
    ListEntry * chPtr, * dummy;
1617
 
1618
    if (Tix_TLGetFromTo(interp, wPtr, 1, argv, &chPtr, &dummy)
1619
        != TCL_OK) {
1620
        return TCL_ERROR;
1621
    }
1622
 
1623
    if (chPtr == NULL) {
1624
        Tcl_AppendResult(interp, "list entry \"", argv[0],
1625
            "\" does not exist", NULL);
1626
        return TCL_ERROR;
1627
    }
1628
 
1629
    return Tix_ConfigureValue2(interp, wPtr->dispData.tkwin, (char *)chPtr,
1630
        entryConfigSpecs, chPtr->iPtr, argv[1], 0);
1631
}
1632
 
1633
/*----------------------------------------------------------------------
1634
 * "entryconfigure" sub command
1635
 *----------------------------------------------------------------------
1636
 */
1637
static int
1638
Tix_TLEntryConfig(clientData, interp, argc, argv)
1639
    ClientData clientData;
1640
    Tcl_Interp *interp;         /* Current interpreter. */
1641
    int argc;                   /* Number of arguments. */
1642
    char **argv;                /* Argument strings. */
1643
{
1644
    WidgetPtr wPtr = (WidgetPtr) clientData;
1645
    ListEntry * chPtr, * dummy;
1646
 
1647
    if (Tix_TLGetFromTo(interp, wPtr, 1, argv, &chPtr, &dummy)
1648
        != TCL_OK) {
1649
        return TCL_ERROR;
1650
    }
1651
 
1652
    if (chPtr == NULL) {
1653
        Tcl_AppendResult(interp, "list entry \"", argv[0],
1654
            "\" does not exist", NULL);
1655
        return TCL_ERROR;
1656
    }
1657
 
1658
    if (argc == 1) {
1659
        return Tix_ConfigureInfo2(interp, wPtr->dispData.tkwin,
1660
            (char*)chPtr, entryConfigSpecs, chPtr->iPtr, (char *) NULL, 0);
1661
    } else if (argc == 2) {
1662
        return Tix_ConfigureInfo2(interp, wPtr->dispData.tkwin,
1663
            (char*)chPtr, entryConfigSpecs, chPtr->iPtr, (char *) argv[1], 0);
1664
    } else {
1665
        return ConfigElement(wPtr, chPtr, argc-1, argv+1,
1666
            TK_CONFIG_ARGV_ONLY, 0);
1667
    }
1668
}
1669
 
1670
/*----------------------------------------------------------------------
1671
 * "nearest" sub command
1672
 *----------------------------------------------------------------------
1673
 */
1674
static int
1675
Tix_TLNearest(clientData, interp, argc, argv)
1676
    ClientData clientData;
1677
    Tcl_Interp *interp;         /* Current interpreter. */
1678
    int argc;                   /* Number of arguments. */
1679
    char **argv;                /* Argument strings. */
1680
{
1681
    WidgetPtr wPtr = (WidgetPtr) clientData;
1682
    int posn[2];
1683
    int index;
1684
    char buff[100];
1685
 
1686
    if (Tcl_GetInt(interp, argv[0], &posn[0]) != TCL_OK) {
1687
        return TCL_ERROR;
1688
    }
1689
    if (Tcl_GetInt(interp, argv[1], &posn[1]) != TCL_OK) {
1690
        return TCL_ERROR;
1691
    }
1692
 
1693
    index = Tix_TLGetNearest(wPtr, posn);
1694
    Tcl_ResetResult(interp);
1695
 
1696
    if (index != -1) {
1697
        sprintf(buff, "%d", index);
1698
        Tcl_AppendResult(interp, buff, NULL);
1699
    }
1700
    return TCL_OK;
1701
}
1702
 
1703
static int Tix_TLGetAt(wPtr, interp, spec, at)
1704
    WidgetPtr wPtr;
1705
    Tcl_Interp *interp;
1706
    char * spec;
1707
    int *at;
1708
{
1709
    int posn[2];
1710
    char *p, *end;
1711
 
1712
    if (spec[0] != '@') {
1713
        return TCL_ERROR;
1714
    }
1715
 
1716
    p = spec+1;
1717
    posn[0] = strtol(p, &end, 0);
1718
    if ((end == p) || (*end != ',')) {
1719
        return TCL_ERROR;
1720
    }
1721
    p = end+1;
1722
    posn[1] = strtol(p, &end, 0);
1723
    if ((end == p) || (*end != 0)) {
1724
        return TCL_ERROR;
1725
    }
1726
 
1727
    *at = Tix_TLGetNearest(wPtr, posn);
1728
    return TCL_OK;
1729
}
1730
 
1731
static int Tix_TLGetNearest(wPtr, posn)
1732
    WidgetPtr wPtr;
1733
    int posn[2];
1734
{
1735
    int i, j, index;
1736
    int maxX, maxY;
1737
    int r, c;
1738
 
1739
    if (wPtr->resizing) {
1740
        ResizeNow(wPtr);
1741
    }
1742
 
1743
    if (wPtr->entList.numItems == 0) {
1744
        return -1;
1745
    }
1746
 
1747
    /* clip off the position with the border of the window */
1748
 
1749
    posn[0] -= wPtr->borderWidth + wPtr->highlightWidth;
1750
    posn[1] -= wPtr->borderWidth + wPtr->highlightWidth;
1751
 
1752
    maxX = Tk_Width (wPtr->dispData.tkwin);
1753
    maxY = Tk_Height(wPtr->dispData.tkwin);
1754
 
1755
    maxX -= 2*(wPtr->borderWidth + wPtr->highlightWidth);
1756
    maxY -= 2*(wPtr->borderWidth + wPtr->highlightWidth);
1757
 
1758
    if (posn[0] >= maxX) {
1759
        posn[0] =  maxX -1;
1760
    }
1761
    if (posn[1] >= maxY) {
1762
        posn[1] =  maxY -1;
1763
    }
1764
    if (posn[0] < 0) {
1765
        posn[0] = 0;
1766
    }
1767
    if (posn[1] < 0) {
1768
        posn[1] = 0;
1769
    }
1770
 
1771
    i = (wPtr->isVertical == 0);
1772
    j = (wPtr->isVertical == 1);
1773
 
1774
    posn[0] += wPtr->scrollInfo[0].offset;
1775
    posn[1] += wPtr->scrollInfo[1].offset;
1776
 
1777
    r = posn[i] / wPtr->maxSize[i];
1778
    c = posn[j] / wPtr->maxSize[j];
1779
 
1780
    index = (r * wPtr->rows[0].numEnt) + c;
1781
 
1782
    if (index >= wPtr->entList.numItems) {
1783
        index = wPtr->entList.numItems - 1;
1784
    }
1785
 
1786
    return index;
1787
}
1788
 
1789
/*----------------------------------------------------------------------
1790
 * "selection" sub command
1791
 *      Modify the selection in this HList box
1792
 *----------------------------------------------------------------------
1793
 */
1794
static int
1795
Tix_TLGetFromTo(interp, wPtr, argc, argv, fromPtr_ret, toPtr_ret)
1796
    Tcl_Interp *interp;
1797
    WidgetPtr wPtr;
1798
    int argc;
1799
    char **argv;
1800
    ListEntry ** fromPtr_ret;
1801
    ListEntry ** toPtr_ret;
1802
{
1803
    /*
1804
     * ToDo: make it more efficient by saving the previous from and to
1805
     * pointers and make the list of childrens a doubly-linked list
1806
     */
1807
    ListEntry * fromPtr;
1808
    ListEntry * toPtr;
1809
    int from, to, tmp;
1810
 
1811
    if (Tix_TranslateIndex(wPtr, interp, argv[0], &from, 0) != TCL_OK) {
1812
        return TCL_ERROR;
1813
    }
1814
    if (argc == 2) {
1815
        if (Tix_TranslateIndex(wPtr, interp, argv[1], &to, 0) != TCL_OK) {
1816
            return TCL_ERROR;
1817
        }
1818
    } else {
1819
        to = from;
1820
    }
1821
 
1822
    if (from > to) {
1823
        /* swap from and to */
1824
        tmp = to; to = from; from = tmp;
1825
    }
1826
 
1827
    fromPtr = NULL;
1828
    toPtr   = NULL;
1829
 
1830
    if (from >= wPtr->entList.numItems) {
1831
        fromPtr = (ListEntry *)wPtr->entList.tail;
1832
        toPtr   = (ListEntry *)wPtr->entList.tail;
1833
    }
1834
    if (to >= wPtr->entList.numItems) {
1835
        toPtr   = (ListEntry *)wPtr->entList.tail;
1836
    }
1837
 
1838
    if (fromPtr == NULL) {
1839
        for (fromPtr = (ListEntry*)wPtr->entList.head;
1840
             from > 0;
1841
             fromPtr=fromPtr->next) {
1842
 
1843
            -- from;
1844
            -- to;
1845
        }
1846
    }
1847
    if (toPtr == NULL) {
1848
        for (toPtr = fromPtr; to > 0; toPtr=toPtr->next) {
1849
            -- to;
1850
        }
1851
    }
1852
 
1853
    * fromPtr_ret = fromPtr;
1854
    if (toPtr_ret) {
1855
        * toPtr_ret = toPtr;
1856
    }
1857
    return TCL_OK;
1858
}
1859
 
1860
static int
1861
Tix_TLSelection(clientData, interp, argc, argv)
1862
    ClientData clientData;
1863
    Tcl_Interp *interp;         /* Current interpreter. */
1864
    int argc;                   /* Number of arguments. */
1865
    char **argv;                /* Argument strings. */
1866
{
1867
    WidgetPtr wPtr = (WidgetPtr) clientData;
1868
    size_t len = strlen(argv[0]);
1869
    int code = TCL_OK;
1870
    int changed = 0;
1871
    ListEntry * chPtr, * fromPtr, * toPtr;
1872
 
1873
    if (strncmp(argv[0], "clear", len)==0) {
1874
        if (argc == 1) {
1875
            /*
1876
             * Clear all entries
1877
             */
1878
            for (chPtr=(ListEntry*)wPtr->entList.head;
1879
                 chPtr;
1880
                 chPtr=chPtr->next) {
1881
 
1882
                chPtr->selected = 0;
1883
            }
1884
            changed = 1;
1885
        }
1886
        else {
1887
            if (Tix_TLGetFromTo(interp, wPtr, argc-1, argv+1, &fromPtr, &toPtr)
1888
                    != TCL_OK) {
1889
                code = TCL_ERROR;
1890
                goto done;
1891
            }
1892
            if (fromPtr == NULL) {
1893
                goto done;
1894
            }
1895
            else {
1896
                while (1) {
1897
                    fromPtr->selected = 0;
1898
                    if (fromPtr == toPtr) {
1899
                        break;
1900
                    } else {
1901
                        fromPtr=fromPtr->next;
1902
                    }
1903
                }
1904
                changed = 1;
1905
                goto done;
1906
            }
1907
        }
1908
    }
1909
    else if (strncmp(argv[0], "includes", len)==0) {
1910
        if (argc != 2) {
1911
            Tix_ArgcError(interp, argc+2, argv-2, 3, "index");
1912
            code = TCL_ERROR;
1913
            goto done;
1914
        }
1915
        if (Tix_TLGetFromTo(interp, wPtr, argc-1, argv+1, &fromPtr, &toPtr)
1916
                != TCL_OK) {
1917
            code = TCL_ERROR;
1918
            goto done;
1919
        }
1920
        if (fromPtr->selected) {
1921
            Tcl_AppendResult(interp, "1", NULL);
1922
        } else {
1923
            Tcl_AppendResult(interp, "0", NULL);
1924
        }
1925
    }
1926
    else if (strncmp(argv[0], "set", len)==0) {
1927
        if (argc < 2 || argc > 3) {
1928
            Tix_ArgcError(interp, argc+2, argv-2, 3, "from ?to?");
1929
            code = TCL_ERROR;
1930
            goto done;
1931
        }
1932
 
1933
        if (Tix_TLGetFromTo(interp, wPtr, argc-1, argv+1, &fromPtr, &toPtr)
1934
                != TCL_OK) {
1935
            code = TCL_ERROR;
1936
            goto done;
1937
        }
1938
        if (fromPtr == NULL) {
1939
            goto done;
1940
        }
1941
        else {
1942
            while (1) {
1943
                fromPtr->selected = 1;
1944
                if (fromPtr == toPtr) {
1945
                    break;
1946
                } else {
1947
                    fromPtr=fromPtr->next;
1948
                }
1949
            }
1950
            changed = 1;
1951
            goto done;
1952
        }
1953
    }
1954
    else {
1955
        Tcl_AppendResult(interp, "unknown option \"", argv[0],
1956
            "\": must be anchor, clear, includes or set", NULL);
1957
        code = TCL_ERROR;
1958
    }
1959
 
1960
  done:
1961
    if (changed) {
1962
        RedrawWhenIdle(wPtr);
1963
    }
1964
 
1965
    return code;
1966
}
1967
 
1968
/*----------------------------------------------------------------------
1969
 * "see" command
1970
 *----------------------------------------------------------------------
1971
 */
1972
static int
1973
Tix_TLSee(clientData, interp, argc, argv)
1974
    ClientData clientData;
1975
    Tcl_Interp *interp;         /* Current interpreter. */
1976
    int argc;                   /* Number of arguments. */
1977
    char **argv;                /* Argument strings. */
1978
{
1979
    WidgetPtr wPtr = (WidgetPtr) clientData;
1980
    ListEntry * chPtr, * dummy;
1981
 
1982
    if (argc == 1) {
1983
        if (Tix_TLGetFromTo(interp, wPtr, 1, argv, &chPtr, &dummy) != TCL_OK) {
1984
            return TCL_ERROR;
1985
        }
1986
        if (chPtr != NULL) {
1987
            wPtr->seeElemPtr = chPtr;
1988
            RedrawWhenIdle(wPtr);
1989
        }
1990
    } else {
1991
        Tcl_AppendResult(interp, "wrong # of arguments, must be: ",
1992
                Tk_PathName(wPtr->dispData.tkwin), " ", argv[-1],
1993
                " index", NULL);
1994
    }
1995
 
1996
    return TCL_OK;
1997
}
1998
 
1999
/*----------------------------------------------------------------------
2000
 * "anchor", "dragsite" and "dropsite" sub commands --
2001
 *
2002
 *      Set/remove the anchor element
2003
 *----------------------------------------------------------------------
2004
 */
2005
static int
2006
Tix_TLSetSite(clientData, interp, argc, argv)
2007
    ClientData clientData;
2008
    Tcl_Interp *interp;         /* Current interpreter. */
2009
    int argc;                   /* Number of arguments. */
2010
    char **argv;                /* Argument strings. */
2011
{
2012
    int changed = 0;
2013
    WidgetPtr wPtr = (WidgetPtr) clientData;
2014
    ListEntry * fromPtr;
2015
    ListEntry * toPtr;                  /* unused */
2016
    ListEntry ** changePtr;
2017
    size_t len;
2018
 
2019
    /* Determine which site should be changed (the last else clause
2020
     * doesn't need to check the string because HandleSubCommand
2021
     * already ensures that only the valid options can be specified.
2022
     **/
2023
    len = strlen(argv[-1]);
2024
    if (strncmp(argv[-1], "anchor", len)==0) {
2025
        changePtr = &wPtr->anchor;
2026
    }
2027
    else if (strncmp(argv[-1], "active", len)==0) {
2028
        changePtr = &wPtr->active;
2029
    }
2030
    else if (strncmp(argv[-1], "dragsite", len)==0) {
2031
        changePtr = &wPtr->dragSite;
2032
    }
2033
    else {
2034
        changePtr = &wPtr->dropSite;
2035
    }
2036
 
2037
    len = strlen(argv[0]);
2038
    if (strncmp(argv[0], "set", len)==0) {
2039
        if (argc == 2) {
2040
            if (Tix_TLGetFromTo(interp,wPtr, argc-1, argv+1, &fromPtr, &toPtr)
2041
                    != TCL_OK) {
2042
                return TCL_ERROR;
2043
            }
2044
            if (*changePtr != fromPtr) {
2045
                *changePtr = fromPtr;
2046
                changed = 1;
2047
            }
2048
        } else {
2049
            Tcl_AppendResult(interp, "wrong # of arguments, must be: ",
2050
                Tk_PathName(wPtr->dispData.tkwin), " ", argv[-1],
2051
                " set index", NULL);
2052
            return TCL_ERROR;
2053
        }
2054
    }
2055
    else if (strncmp(argv[0], "clear", len)==0) {
2056
        if (*changePtr != NULL) {
2057
            *changePtr = NULL;
2058
            changed = 1;
2059
        }
2060
    }
2061
    else {
2062
        Tcl_AppendResult(interp, "wrong option \"", argv[0], "\", ",
2063
            "must be clear or set", NULL);
2064
        return TCL_ERROR;
2065
    }
2066
 
2067
    if (changed) {
2068
        RedrawWhenIdle(wPtr);
2069
    }
2070
 
2071
    return TCL_OK;
2072
}
2073
 
2074
/*----------------------------------------------------------------------
2075
 * "xview" and "yview" sub command
2076
 *----------------------------------------------------------------------
2077
 */
2078
static int
2079
Tix_TLView(clientData, interp, argc, argv)
2080
    ClientData clientData;
2081
    Tcl_Interp *interp;         /* Current interpreter. */
2082
    int argc;                   /* Number of arguments. */
2083
    char **argv;                /* Argument strings. */
2084
{
2085
    WidgetPtr wPtr = (WidgetPtr) clientData;
2086
    int axis;
2087
 
2088
    if (argv[-1][0] == 'x') {
2089
        axis = 0;
2090
    } else {
2091
        axis = 1;
2092
    }
2093
 
2094
    if (argc == 0) {
2095
        char string[80];
2096
        double first, last;
2097
 
2098
        Tix_GetScrollFractions((Tix_ScrollInfo*)&wPtr->scrollInfo[axis],
2099
            &first, &last);
2100
 
2101
        sprintf(string, "{%f %f}", first, last);
2102
        Tcl_AppendResult(interp, string, NULL);
2103
        return TCL_OK;
2104
    }
2105
    else if (Tix_SetScrollBarView(interp,
2106
        (Tix_ScrollInfo*)&wPtr->scrollInfo[axis], argc, argv, 0) != TCL_OK) {
2107
 
2108
        return TCL_ERROR;
2109
    }
2110
 
2111
    UpdateScrollBars(wPtr, 0);
2112
    RedrawWhenIdle(wPtr);
2113
    return TCL_OK;
2114
}
2115
/*----------------------------------------------------------------------
2116
 *
2117
 *
2118
 *                      Memory Management Section
2119
 *
2120
 *
2121
 *----------------------------------------------------------------------
2122
 */
2123
static int
2124
ConfigElement(wPtr, chPtr, argc, argv, flags, forced)
2125
    WidgetPtr wPtr;
2126
    ListEntry *chPtr;
2127
    int argc;
2128
    char ** argv;
2129
    int flags;
2130
    int forced;
2131
{
2132
    int sizeChanged;
2133
 
2134
    if (Tix_WidgetConfigure2(wPtr->dispData.interp, wPtr->dispData.tkwin,
2135
        (char*)chPtr, entryConfigSpecs, chPtr->iPtr, argc, argv, flags,
2136
        forced, &sizeChanged) != TCL_OK) {
2137
        return TCL_ERROR;
2138
    }
2139
 
2140
    if (sizeChanged) {
2141
        chPtr->size[0] = chPtr->iPtr->base.size[0];
2142
        chPtr->size[1] = chPtr->iPtr->base.size[1];
2143
        ResizeWhenIdle(wPtr);
2144
    } else {
2145
        RedrawWhenIdle(wPtr);
2146
    }
2147
    return TCL_OK;
2148
}
2149
 
2150
static void
2151
Realloc(wPtr, new_size)
2152
    WidgetPtr wPtr;
2153
    int new_size;
2154
{
2155
    if (new_size < 1) {
2156
        new_size = 1;
2157
    }
2158
    if (new_size == wPtr->numRowAllocd) {
2159
        return;
2160
    }
2161
    wPtr->rows = (ListRow*)ckrealloc(wPtr->rows, sizeof(ListRow)*new_size);
2162
    wPtr->numRowAllocd = new_size;
2163
}
2164
 
2165
static void ResizeRows(wPtr, winW, winH)
2166
    WidgetPtr wPtr;
2167
    int winW;                   /* -1 == current width */
2168
    int winH;                   /* -1 == current height */
2169
{
2170
    ListEntry * chPtr;
2171
    ListEntry * rowHead;
2172
    int n, c, r;
2173
    int maxI;                   /* max of width in the current column */
2174
    int maxJ;                   /* max of height among all elements */
2175
    int curRow;
2176
    int i, j;
2177
    int sizeJ;
2178
    int winSize[2];
2179
 
2180
    if (wPtr->isVertical) {
2181
        i = 0;           /* Column major, 0,0 -> 0,1 -> 0,2 ... -> 1,0 */
2182
        j = 1;
2183
    } else {
2184
        i = 1;          /* Row major, 0,0 -> 1,0 -> 2,0 ... -> 0,1 */
2185
        j = 0;
2186
    }
2187
 
2188
    if (winW == -1) {
2189
        winW = Tk_Width (wPtr->dispData.tkwin);
2190
    }
2191
    if (winH == -1) {
2192
        winH = Tk_Height(wPtr->dispData.tkwin);
2193
    }
2194
 
2195
    winSize[0] = winW;
2196
    winSize[1] = winH;
2197
 
2198
    if (wPtr->entList.numItems == 0) {
2199
        wPtr->rows[0].chPtr = NULL;
2200
        wPtr->rows[0].size[0] = 1;
2201
        wPtr->rows[0].size[1] = 1;
2202
        wPtr->rows[0].numEnt = 0;
2203
 
2204
        wPtr->numRow = 1;
2205
        goto done;
2206
    }
2207
 
2208
    /*      --  The following verbal description follows the "Column Major"
2209
     *          model. Row major are similar, just the i,j incides are swapped
2210
     *
2211
     * (1) (a) Search for the tallest element, use it as the height of all
2212
     *         the elements;
2213
     *     (b) Search for the widest element, use it as the width of all
2214
     *         the elements;
2215
     */
2216
    for (maxJ=1, maxI=1, chPtr = (ListEntry*)wPtr->entList.head;
2217
         chPtr;
2218
         chPtr=chPtr->next) {
2219
 
2220
        if (maxJ < chPtr->iPtr->base.size[j]) {
2221
            maxJ = chPtr->iPtr->base.size[j];
2222
        }
2223
        if (maxI < chPtr->iPtr->base.size[i]) {
2224
            maxI = chPtr->iPtr->base.size[i];
2225
        }
2226
    }
2227
    wPtr->maxSize[i] = maxI;
2228
    wPtr->maxSize[j] = maxJ;
2229
 
2230
    /* (2) Calculate how many elements can be in each column
2231
     *
2232
     */
2233
    n = winSize[j] / maxJ;
2234
    if (n <=0) {
2235
        n = 1;
2236
    }
2237
 
2238
    wPtr->numRow = 0;
2239
    curRow = 0;
2240
    c = 0;
2241
    sizeJ = 0;
2242
    rowHead = (ListEntry*)wPtr->entList.head;
2243
    for(chPtr = (ListEntry*)wPtr->entList.head; chPtr; chPtr=chPtr->next) {
2244
        sizeJ += chPtr->iPtr->base.size[j];
2245
        ++ c;
2246
        if (c == n || chPtr->next == NULL) {
2247
            if (curRow >= wPtr->numRowAllocd) {
2248
                Realloc(wPtr, curRow*2);
2249
            }
2250
            wPtr->rows[curRow].chPtr   = rowHead;
2251
            wPtr->rows[curRow].size[i] = maxI;
2252
            wPtr->rows[curRow].size[j] = sizeJ;
2253
            wPtr->rows[curRow].numEnt  = c;
2254
            ++ curRow;
2255
            ++ wPtr->numRow;
2256
            c = 0;
2257
            rowHead = chPtr->next;
2258
            sizeJ = 0;
2259
        }
2260
    }
2261
 
2262
  done:
2263
    /* calculate the size of the total and visible area */
2264
    wPtr->scrollInfo[i].total = 0;
2265
    wPtr->scrollInfo[j].total = 0;
2266
 
2267
    for (r=0; r<wPtr->numRow; r++) {
2268
        wPtr->scrollInfo[i].total += wPtr->rows[r].size[i];
2269
        if (wPtr->scrollInfo[j].total < wPtr->rows[r].size[j]) {
2270
            wPtr->scrollInfo[j].total = wPtr->rows[r].size[j];
2271
        }
2272
    }
2273
 
2274
    wPtr->scrollInfo[i].window = winSize[i];
2275
    wPtr->scrollInfo[j].window = winSize[j];
2276
 
2277
    if (wPtr->scrollInfo[i].total < 1) {
2278
        wPtr->scrollInfo[i].total = 1;
2279
    }
2280
    if (wPtr->scrollInfo[j].total < 1) {
2281
        wPtr->scrollInfo[j].total = 1;
2282
    }
2283
    if (wPtr->scrollInfo[i].window < 1) {
2284
        wPtr->scrollInfo[i].window = 1;
2285
    }
2286
    if (wPtr->scrollInfo[j].window < 1) {
2287
        wPtr->scrollInfo[j].window = 1;
2288
    }
2289
 
2290
    /* If we have much fewer rows now, adjust the size of the rows list */
2291
    if (wPtr->numRowAllocd > (2*wPtr->numRow)) {
2292
        Realloc(wPtr, 2*wPtr->numRow);
2293
    }
2294
 
2295
    /* Update the scrollbars */
2296
 
2297
    UpdateScrollBars(wPtr, 1);
2298
}
2299
/*----------------------------------------------------------------------
2300
 * RedrawRows --
2301
 *
2302
 *      Redraw the rows, according to the "offset: in both directions
2303
 *----------------------------------------------------------------------
2304
 */
2305
 
2306
static void
2307
RedrawRows(wPtr, pixmap)
2308
    WidgetPtr wPtr;
2309
    Drawable pixmap;
2310
{
2311
    int r, n;
2312
    int p[2];
2313
    ListEntry * chPtr;
2314
    int i, j;
2315
    int total;
2316
    int windowSize;
2317
 
2318
    if (wPtr->entList.numItems == 0) {
2319
        return;
2320
    }
2321
 
2322
    if (wPtr->isVertical) {
2323
        i = 0;           /* Column major, 0,0 -> 0,1 -> 0,2 ... -> 1,0 */
2324
        j = 1;
2325
        windowSize = Tk_Width(wPtr->dispData.tkwin);
2326
    } else {
2327
        i = 1;          /* Row major, 0,0 -> 1,0 -> 2,0 ... -> 0,1 */
2328
        j = 0;
2329
        windowSize = Tk_Height(wPtr->dispData.tkwin);
2330
    }
2331
 
2332
    p[i] = wPtr->highlightWidth + wPtr->borderWidth;
2333
    windowSize -= 2*p[i];
2334
 
2335
    if (windowSize < 1) {
2336
        windowSize = 1;
2337
    }
2338
 
2339
    if (wPtr->seeElemPtr != NULL) {
2340
        /*
2341
         * Adjust the scrolling so that the given entry is visible.
2342
         */
2343
        int start = 0;           /* x1 position of the element to see. */
2344
        int size = 0;            /* width of the element to see. */
2345
        int old = wPtr->scrollInfo[i].offset;
2346
 
2347
        for (r=0, n=0, chPtr=(ListEntry*)wPtr->entList.head; chPtr;
2348
                chPtr=chPtr->next, n++) {
2349
            if (chPtr == wPtr->seeElemPtr) {
2350
                size = wPtr->rows[r].size[i];
2351
                break;
2352
            }
2353
            if (n == wPtr->rows[r].numEnt) {
2354
                n=0;
2355
                r++;
2356
                start += wPtr->rows[r].size[i];
2357
            }
2358
        }
2359
 
2360
        if (wPtr->scrollInfo[i].offset + windowSize > start + size) {
2361
            wPtr->scrollInfo[i].offset = start + size - windowSize;
2362
        }
2363
        if (wPtr->scrollInfo[i].offset < start) {
2364
            wPtr->scrollInfo[i].offset = start;
2365
        }
2366
        if (wPtr->scrollInfo[i].offset != old) {
2367
            UpdateScrollBars(wPtr, 0);
2368
        }
2369
        wPtr->seeElemPtr = NULL;
2370
    }
2371
 
2372
    /* Search for a row that is (possibly partially) visible*/
2373
    total=0; r=0;
2374
    if (wPtr->scrollInfo[i].offset != 0) {
2375
        for (; r<wPtr->numRow; r++) {
2376
            total += wPtr->rows[r].size[i];
2377
 
2378
            if (total > wPtr->scrollInfo[i].offset) {
2379
                p[i] -= wPtr->scrollInfo[i].offset -
2380
                        (total - wPtr->rows[r].size[i]);
2381
                break;
2382
            }
2383
            if (total == wPtr->scrollInfo[i].offset) {
2384
                r++;
2385
                break;
2386
            }
2387
        }
2388
    }
2389
 
2390
    /* Redraw all the visible rows */
2391
    for (; r<wPtr->numRow; r++) {
2392
 
2393
        p[j] = wPtr->highlightWidth + wPtr->borderWidth;
2394
 
2395
        total=0; n=0; chPtr=wPtr->rows[r].chPtr;
2396
        if (wPtr->scrollInfo[j].offset > 0)  {
2397
            /* Search for a column that is (possibly partially) visible*/
2398
            for (;
2399
                 n<wPtr->rows[r].numEnt;
2400
                 n++, chPtr = chPtr->next) {
2401
 
2402
                total += chPtr->iPtr->base.size[j];
2403
                if (total > wPtr->scrollInfo[j].offset) {
2404
                    /* Adjust for the shift due to partially visible elements*/
2405
                    p[j] -= wPtr->scrollInfo[j].offset -
2406
                      (total - chPtr->iPtr->base.size[j]);
2407
                    break;
2408
                }
2409
                if (total == wPtr->scrollInfo[j].offset) {
2410
                    n++; chPtr = chPtr->next;
2411
                    break;
2412
                }
2413
            }
2414
        }
2415
 
2416
        /* Redraw all the visible columns in this row */
2417
        for (; n<wPtr->rows[r].numEnt; n++, chPtr = chPtr->next) {
2418
            int flags = TIX_DITEM_NORMAL_FG;
2419
            int W, H;
2420
 
2421
            if (chPtr->selected) {
2422
                flags |= TIX_DITEM_SELECTED_FG;
2423
                flags |= TIX_DITEM_SELECTED_BG;
2424
            }
2425
 
2426
            if (wPtr->isVertical) {
2427
                W = wPtr->rows[r].size[0];
2428
                H = chPtr->iPtr->base.size[1];
2429
            } else {
2430
                H = wPtr->rows[r].size[1];
2431
                W = chPtr->iPtr->base.size[0];
2432
            }
2433
 
2434
            Tix_DItemDisplay(pixmap, None, chPtr->iPtr, p[0], p[1], W, H,
2435
                flags);
2436
 
2437
            if (chPtr == wPtr->anchor) {
2438
                Tix_DrawAnchorLines(Tk_Display(wPtr->dispData.tkwin), pixmap,
2439
                    wPtr->anchorGC, p[0], p[1], W-1, H-1);
2440
            }
2441
            p[j] += wPtr->maxSize[j];
2442
        }
2443
 
2444
        /* advance to the next row */
2445
        p[i]+= wPtr->rows[r].size[i];
2446
    }
2447
}
2448
 
2449
/*----------------------------------------------------------------------
2450
 *  UpdateScrollBars
2451
 *----------------------------------------------------------------------
2452
 */
2453
static void UpdateScrollBars(wPtr, sizeChanged)
2454
    WidgetPtr wPtr;
2455
    int sizeChanged;
2456
{
2457
    Tix_UpdateScrollBar(wPtr->dispData.interp,
2458
        (Tix_ScrollInfo*)&wPtr->scrollInfo[0]);
2459
    Tix_UpdateScrollBar(wPtr->dispData.interp,
2460
        (Tix_ScrollInfo*)&wPtr->scrollInfo[1]);
2461
 
2462
    if (wPtr->sizeCmd && sizeChanged) {
2463
        if (Tcl_Eval(wPtr->dispData.interp, wPtr->sizeCmd) != TCL_OK) {
2464
            Tcl_AddErrorInfo(wPtr->dispData.interp,
2465
                "\n    (size command executed by tixTList)");
2466
            Tk_BackgroundError(wPtr->dispData.interp);
2467
        }
2468
    }
2469
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.