1 /*
2  *  This file is part of the XForms library package.
3  *
4  *  XForms is free software; you can redistribute it and/or modify it
5  *  under the terms of the GNU Lesser General Public License as
6  *  published by the Free Software Foundation; either version 2.1, or
7  *  (at your option) any later version.
8  *
9  *  XForms is distributed in the hope that it will be useful, but
10  *  WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  *  Lesser General Public License for more details.
13  *
14  *  You should have received a copy of the GNU Lesser General Public License
15  *  along with XForms.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 
19 /**
20  * \file browser.c
21  *
22  *  This file is part of the XForms library package.
23  *  Copyright (c) 1996-2002  T.C. Zhao and Mark Overmars
24  *  All rights reserved.
25  *
26  *   Browser composite.
27  *   scrollbar redrawing can be further optimized.
28  */
29 
30 
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34 
35 #include "include/forms.h"
36 #include "flinternal.h"
37 #include "private/pbrowser.h"
38 #include "private/flvasprintf.h"
39 
40 
41 /***************************************
42  * Some attribue of the object changed, we better recalculate how
43  * it should oook like
44  ***************************************/
45 
46 static void
attrib_change(FL_OBJECT * ob)47 attrib_change( FL_OBJECT * ob )
48 {
49     FLI_BROWSER_SPEC *sp = ob->spec;
50 
51     /* Text box stuff */
52 
53     sp->tb->x = ob->x;
54     sp->tb->y = ob->y;
55 
56     fli_set_object_visibility( sp->tb, FL_VISIBLE );
57     sp->tb->input = ob->input;
58 
59     sp->tb->type    = ob->type;
60     sp->tb->boxtype = ob->boxtype;
61     sp->tb->lcol    = ob->lcol;
62     sp->tb->col1    = ob->col1;
63     sp->tb->col2    = ob->col2;
64     sp->tb->bw      = ob->bw;
65     fli_notify_object( sp->tb, FL_RESIZED );
66 
67     /* Scrollbars */
68 
69     if (    ob->boxtype == FL_DOWN_BOX
70          && sp->hsl->type == FL_HOR_NICE_SCROLLBAR )
71     {
72         sp->hsl->boxtype = FL_FRAME_BOX;
73         sp->vsl->boxtype = FL_FRAME_BOX;
74     }
75     else if (    ob->boxtype == FL_DOWN_BOX
76               && sp->hsl->type == FL_HOR_SCROLLBAR )
77     {
78         sp->hsl->boxtype = FL_UP_BOX;
79         sp->vsl->boxtype = FL_UP_BOX;
80     }
81     else
82     {
83         sp->hsl->boxtype = ob->boxtype;
84         sp->vsl->boxtype = ob->boxtype;
85     }
86 
87     sp->hsl->bw = sp->vsl->bw = ob->bw;
88 
89     if ( ! sp->user_set && ob->boxtype != FL_DOWN_BOX )
90         sp->vw = sp->vw_def = sp->hh = sp->hh_def =
91                                           fli_get_default_scrollbarsize( ob );
92 }
93 
94 
95 /***************************************
96  ***************************************/
97 
98 static void
get_geometry(FL_OBJECT * obj)99 get_geometry( FL_OBJECT * obj )
100 {
101     FLI_BROWSER_SPEC *comp = obj->spec;
102     FL_OBJECT *tb = comp->tb;
103     FLI_TBOX_SPEC *sp = comp->tb->spec;
104     int h_on = comp->h_on,
105         v_on = comp->v_on;
106     double old_xrel = fli_tbox_get_rel_xoffset( tb );
107     double old_yrel = fli_tbox_get_rel_yoffset( tb );
108 
109     comp->hh = comp->vw = 0;
110     comp->h_on = comp->v_on = 0;
111 
112     tb->w = obj->w;
113     tb->h = obj->h;
114     fli_tbox_recalc_area( tb );
115 
116     /* Check if we need a vertical slider */
117 
118     if (    ( sp->max_height > sp->h && comp->v_pref != FL_OFF )
119          || comp->v_pref == FL_ON )
120     {
121         comp->v_on  = 1;
122         comp->vw    = comp->vw_def;
123 
124         tb->w      -= comp->vw;
125         fli_tbox_recalc_area( tb );
126     }
127 
128     /* Check if we need a horizontal slider */
129 
130     if (    ( sp->max_width > sp->w && comp->h_pref != FL_OFF )
131          || comp->h_pref == FL_ON )
132     {
133         comp->h_on  = 1;
134         comp->hh    = comp->hh_def;
135 
136         tb->h      -= comp->hh;
137         fli_tbox_recalc_area( tb );
138     }
139 
140     /* Due to the addition of a horizontal slider also a vertical slider
141        may now be needed, so recheck for this possibility */
142 
143     if ( ! comp->v_on && sp->max_height > sp->h && comp->v_pref != FL_OFF )
144     {
145         comp->v_on  = 1;
146         comp->vw    = comp->vw_def;
147 
148         tb->w      -= comp->vw;
149         fli_tbox_recalc_area( tb );
150     }
151 
152     if ( comp->v_on )
153     {
154         comp->vsl->x = obj->x + obj->w - comp->vw;
155         comp->vsl->y = obj->y;
156         comp->vsl->w = comp->vw;
157         comp->vsl->h = obj->h - comp->hh;
158         fli_notify_object( comp->vsl, FL_RESIZED );
159 
160         comp->vval  = old_yrel;
161         comp->vsize = comp->vinc1 = ( double ) sp->h / sp->max_height;
162         comp->vinc2 = ( double ) sp->def_height / sp->max_height;
163     }
164     else
165     {
166         comp->vsize = 1.0;
167         comp->vval  = 0.0;
168     }
169 
170     if ( comp->h_on )
171     {
172         comp->hsl->x = obj->x;
173         comp->hsl->y = obj->y + obj->h - comp->hh;
174         comp->hsl->w = obj->w - comp->vw;
175         comp->hsl->h = comp->hh;
176         fli_notify_object( comp->hsl, FL_RESIZED );
177 
178         comp->hval  = old_xrel;
179         comp->hsize = ( double ) sp->w / sp->max_width;
180         comp->hinc1 = ( 8.0 * sp->def_height ) / sp->max_width;
181         comp->hinc2 = ( sp->def_height - 2.0 ) / sp->max_width;
182     }
183     else
184     {
185         comp->hsize = 1.0;
186         comp->hval  = 1.0;
187     }
188 
189     comp->dead_area = comp->h_on && comp->v_on;
190     fli_set_object_visibility( comp->hsl, comp->h_on );
191     fli_set_object_visibility( comp->vsl, comp->v_on );
192 
193     comp->attrib = 1;
194 
195     sp->no_redraw = 1;
196 
197     if ( comp->v_on )
198     {
199         comp->vval = fli_tbox_set_rel_yoffset( tb, comp->vval );
200         fl_set_scrollbar_value( comp->vsl, comp->vval );
201         fl_set_scrollbar_size( comp->vsl, comp->vsize );
202     }
203 
204     if ( comp->h_on )
205     {
206         comp->hval = fli_tbox_set_rel_xoffset( tb, comp->hval );
207         fl_set_scrollbar_value( comp->hsl, comp->hval );
208         fl_set_scrollbar_size( comp->hsl, comp->hsize );
209     }
210 
211     sp->no_redraw = 0;
212 
213     if ( h_on != comp->h_on || v_on != comp->v_on )
214         fli_notify_object( tb, FL_RESIZED );
215 }
216 
217 
218 /***************************************
219  * The "dead area" is the small square in the lower right hand corner
220  * of the browser (beside the horizontal slider and below the vertical
221  * one) that shows up when both sliders are displayed.
222  ***************************************/
223 
224 static void
draw_dead_area(FL_OBJECT * obj)225 draw_dead_area( FL_OBJECT * obj )
226 {
227     FLI_BROWSER_SPEC *sp = obj->spec;
228 
229     if ( FL_ObjWin( sp->tb ) )
230     {
231         fl_winset( FL_ObjWin( sp->tb ) );
232         fl_draw_box( FL_FLAT_BOX, obj->x + obj->w - sp->vw,
233                      obj->y + obj->h - sp->hh, sp->vw, sp->hh,
234                      sp->vsl->col1, 1 );
235     }
236 }
237 
238 
239 /***************************************
240  * Called for events concerning the browser
241  ***************************************/
242 
243 static int
handle_browser(FL_OBJECT * obj,int event,FL_Coord mx FL_UNUSED_ARG,FL_Coord my FL_UNUSED_ARG,int key FL_UNUSED_ARG,void * ev FL_UNUSED_ARG)244 handle_browser( FL_OBJECT * obj,
245                 int         event,
246                 FL_Coord    mx   FL_UNUSED_ARG,
247                 FL_Coord    my   FL_UNUSED_ARG,
248                 int         key  FL_UNUSED_ARG,
249                 void      * ev   FL_UNUSED_ARG )
250 {
251     FLI_BROWSER_SPEC *sp = obj->spec;
252 
253     switch ( event )
254     {
255         case FL_RESIZED :
256         case FL_ATTRIB :
257             sp->attrib = 1;
258             break;
259 
260         case FL_DRAW:
261             if ( sp->attrib )
262             {
263                 attrib_change( obj );
264                 get_geometry( obj );
265                 sp->attrib = 0;
266             }
267 
268             draw_dead_area( obj );
269             /* fall through */
270 
271         case FL_DRAWLABEL:
272             fl_draw_object_label( obj );
273             break;
274 
275         case FL_FREEMEM:
276             fl_free( sp );
277             break;
278     }
279 
280     return FL_RETURN_NONE;
281 }
282 
283 
284 /***************************************
285  ***************************************/
286 
287 static void
redraw_scrollbar(FL_OBJECT * ob)288 redraw_scrollbar( FL_OBJECT * ob )
289 {
290     FLI_BROWSER_SPEC *comp = ob->spec;
291 
292     attrib_change( ob );
293     get_geometry( ob );
294 
295     fl_freeze_form( ob->form );
296 
297     if ( comp->v_on )
298     {
299         fl_set_scrollbar_size( comp->vsl, comp->vsize );
300         fl_set_scrollbar_value( comp->vsl, comp->vval );
301 
302         if ( comp->vsize != 1.0 )
303             fl_set_scrollbar_increment( comp->vsl, comp->vinc1, comp->vinc2 );
304     }
305 
306     if ( comp->h_on )
307     {
308         fl_set_scrollbar_size( comp->hsl, comp->hsize );
309         fl_set_scrollbar_value( comp->hsl, comp->hval );
310 
311         if ( comp->hsize != 1.0 )
312             fl_set_scrollbar_increment( comp->hsl, comp->hinc1, comp->hinc2 );
313     }
314 
315     if ( comp->attrib )
316     {
317         if ( comp->v_on )
318             fl_redraw_object( comp->vsl );
319         if ( comp->h_on )
320             fl_redraw_object( comp->hsl );
321         fl_redraw_object( comp->tb );
322 
323         comp->attrib = 0;
324     }
325 
326     draw_dead_area( ob );
327     fl_unfreeze_form( ob->form );
328 }
329 
330 
331 /***************************************
332  ***************************************/
333 
334 static void
hcb(FL_OBJECT * obj,long data FL_UNUSED_ARG)335 hcb( FL_OBJECT * obj,
336      long        data  FL_UNUSED_ARG )
337 {
338     FLI_BROWSER_SPEC *comp = obj->parent->spec;
339     double hp = fli_tbox_set_rel_xoffset( comp->tb,
340                                           fl_get_scrollbar_value( comp->hsl ) );
341 
342     if ( obj->returned & FL_RETURN_END )
343         obj->parent->returned |= FL_RETURN_END;
344 
345     if ( hp != comp->old_hp )
346         obj->parent->returned |= FL_RETURN_CHANGED;
347 
348     if (    obj->parent->how_return & FL_RETURN_END_CHANGED
349          && ! (    obj->parent->returned & FL_RETURN_CHANGED
350                 && obj->parent->returned & FL_RETURN_END ) )
351             obj->parent->returned = FL_RETURN_NONE;
352 
353     if ( obj->parent->returned & FL_RETURN_END )
354         comp->old_hp = hp;
355 
356     if ( obj->returned & FL_RETURN_CHANGED && comp->hcb )
357         comp->hcb( obj->parent, fli_tbox_get_topline( comp->tb ) + 1,
358                    comp->hcb_data );
359 }
360 
361 
362 /***************************************
363  ***************************************/
364 
365 static void
vcb(FL_OBJECT * obj,long data FL_UNUSED_ARG)366 vcb( FL_OBJECT * obj,
367      long        data  FL_UNUSED_ARG )
368 {
369     FLI_BROWSER_SPEC *comp = obj->parent->spec;
370     double vp = fli_tbox_set_rel_yoffset( comp->tb,
371                                           fl_get_scrollbar_value( comp->vsl ) );
372 
373     if ( obj->returned & FL_RETURN_END )
374         obj->parent->returned |= FL_RETURN_END;
375 
376     if ( vp != comp->old_vp )
377         obj->parent->returned |= FL_RETURN_CHANGED;
378 
379     if (    obj->parent->how_return & FL_RETURN_END_CHANGED
380          && ! (    obj->parent->returned & FL_RETURN_CHANGED
381                 && obj->parent->returned & FL_RETURN_END ) )
382             obj->parent->returned = FL_RETURN_NONE;
383 
384     if ( obj->parent->returned & FL_RETURN_END )
385         comp->old_vp = vp;
386 
387     if ( obj->returned & FL_RETURN_CHANGED && comp->vcb )
388         comp->vcb( obj->parent, fli_tbox_get_topline( comp->tb ) + 1,
389                    comp->vcb_data );
390 }
391 
392 
393 /***************************************
394  * Textbox callback routine, we simply pass the return value of the
395  * textbox on as the parents new return value after a readjustment of
396  * the scollbars.
397  ***************************************/
398 
399 static void
tbcb(FL_OBJECT * obj,long data FL_UNUSED_ARG)400 tbcb( FL_OBJECT * obj,
401       long        data  FL_UNUSED_ARG )
402 {
403     FLI_BROWSER_SPEC *psp = obj->parent->spec;
404     double vp = fli_tbox_get_rel_yoffset( obj );
405     double hp = fli_tbox_get_rel_xoffset( obj );
406 
407     if ( obj->returned & FL_RETURN_CHANGED )
408     {
409         if ( hp != psp->old_hp )
410         {
411             fl_set_scrollbar_value( psp->hsl, psp->old_hp = hp );
412             if ( psp->hcb )
413                 psp->hcb( obj->parent, fli_tbox_get_topline( psp->tb ) + 1,
414                           psp->hcb_data );
415         }
416 
417         if ( vp != psp->old_vp )
418         {
419             fl_set_scrollbar_value( psp->vsl, psp->old_vp = vp );
420             if ( psp->vcb )
421                 psp->vcb( obj->parent, fli_tbox_get_topline( psp->tb ) + 1,
422                           psp->vcb_data );
423         }
424     }
425 
426     obj->parent->returned = obj->returned;
427 }
428 
429 
430 /***************************************
431  * Textbox dblclick callback
432  ***************************************/
433 
434 static void
tb_dblcallback(FL_OBJECT * ob,long data FL_UNUSED_ARG)435 tb_dblcallback( FL_OBJECT * ob,
436                 long        data  FL_UNUSED_ARG )
437 {
438     FLI_BROWSER_SPEC *sp = ob->parent->spec;
439 
440     if ( sp->callback )
441         sp->callback( ob->parent, sp->callback_data );
442 }
443 
444 
445 /***************************************
446  ***************************************/
447 
448 static int
tbpost(FL_OBJECT * ob,int ev,FL_Coord mx,FL_Coord my,int key,void * xev)449 tbpost( FL_OBJECT * ob,
450         int         ev,
451         FL_Coord    mx,
452         FL_Coord    my,
453        int          key,
454         void      * xev )
455 {
456     FL_OBJECT *br = ob->parent;
457 
458     return br->posthandle ? br->posthandle( br, ev, mx, my, key, xev ) : 0;
459 }
460 
461 
462 /***************************************
463  ***************************************/
464 
465 static int
tbpre(FL_OBJECT * ob,int ev,FL_Coord mx,FL_Coord my,int key,void * xev)466 tbpre( FL_OBJECT * ob,
467        int         ev,
468        FL_Coord    mx,
469        FL_Coord    my,
470       int          key,
471        void      * xev )
472 {
473 
474     FL_OBJECT *br = ob->parent;
475 
476     return br->prehandle ? br->prehandle( br, ev, mx, my, key, xev ) : 0;
477 }
478 
479 
480 /***************************************
481  ***************************************/
482 
483 int
fli_get_default_scrollbarsize(FL_OBJECT * ob)484 fli_get_default_scrollbarsize( FL_OBJECT * ob )
485 {
486     int delta = ( FL_abs( ob->bw ) + 3 * ( ob->bw > 0 ) );
487     int flat = IS_FLATBOX( ob->boxtype ) ? 2 : 0;
488 
489     if ( ob->w > 250 && ob->h > 250 )
490         return 15 + delta - flat;
491     else if ( ob->w < 150 || ob->h < 150 )
492         return 13 + delta - flat;
493     else
494         return 14 + delta - flat;
495 }
496 
497 
498 /***************************************
499  * Creates a new browser object to be added to a form
500  ***************************************/
501 
502 FL_OBJECT *
fl_create_browser(int type,FL_Coord x,FL_Coord y,FL_Coord w,FL_Coord h,const char * label)503 fl_create_browser( int          type,
504                    FL_Coord     x,
505                    FL_Coord     y,
506                    FL_Coord     w,
507                    FL_Coord     h,
508                    const char * label )
509 {
510     FL_OBJECT *ob;
511     FLI_BROWSER_SPEC *sp;
512     int D;
513 
514     ob = fl_make_object( FL_BROWSER, type, x, y, w, h, label,
515                          handle_browser );
516 
517     sp = ob->spec = fl_calloc( 1, sizeof *sp );
518     sp->tb = fli_create_tbox( type, x, y, w, h, NULL );
519 
520     sp->callback  = NULL;
521     sp->hsize     = sp->vsize = sp->hval = sp->vval =
522     sp->hinc1     = sp->hinc2 = sp->vinc1 = sp->vinc2 = 0.0;
523     sp->hcb       = sp->vcb = NULL;
524     sp->hcb_data  = sp->vcb_data = NULL;
525     sp->old_hp    = sp->old_vp = 0.0;
526     sp->attrib    = 1;
527 
528     /* Copy browser attributes from textbox */
529 
530     ob->boxtype  = sp->tb->boxtype;
531     ob->lcol     = sp->tb->lcol;
532     ob->col1     = sp->tb->col1;
533     ob->col2     = sp->tb->col2;
534     ob->align    = sp->tb->align;
535 
536     /* Textbox handlers */
537 
538     fl_set_object_callback( sp->tb, tbcb, 0 );
539     fli_tbox_set_dblclick_callback( sp->tb, tb_dblcallback, 0 );
540     fl_set_object_posthandler( sp->tb, tbpost );
541     fl_set_object_prehandler( sp->tb, tbpre );
542 
543     /* Scrollbars */
544 
545     D = sp->vw_def = sp->hh_def = fli_get_default_scrollbarsize( ob );
546     sp->v_pref = sp->h_pref = FL_AUTO;
547 
548     sp->hsl = fl_create_scrollbar( fli_context->hscb, x, y + h - D,
549                                    w - D, D, NULL );
550     fli_set_object_visibility( sp->hsl, sp->h_pref == FL_ON );
551     fl_set_object_callback( sp->hsl, hcb, 0 );
552     fl_set_scrollbar_value( sp->hsl, 0.0 );
553     fl_set_scrollbar_bounds( sp->hsl, 0.0, 1.0 );
554     sp->hsl->resize = FL_RESIZE_NONE;
555 
556     sp->vsl = fl_create_scrollbar( fli_context->vscb, x + w - D, y,
557                                    D, h - D, NULL );
558     fli_set_object_visibility( sp->vsl, sp->v_pref == FL_ON );
559     fl_set_object_callback( sp->vsl, vcb, 0 );
560     fl_set_scrollbar_value( sp->vsl, 0.0 );
561     fl_set_scrollbar_bounds( sp->hsl, 0.0, 1.0 );
562     sp->vsl->resize = FL_RESIZE_NONE;
563 
564     fl_add_child( ob, sp->tb  );
565     fl_add_child( ob, sp->hsl );
566     fl_add_child( ob, sp->vsl );
567 
568     /* In older versions scrollbars and browsers weren't returned to e.g.
569        fl_do_forms() but still a callback associated with the object
570        got called. To emulate the old behaviour we have to set the
571        return policy to default to FL_RETURN_NONE and only change that
572        to FL_RETURN_CHANGED when a callback is installed (which is done
573        in fl_set_object_callback()) */
574 
575 #if ! USE_BWC_BS_HACK
576     fl_set_object_return( ob, FL_RETURN_SELECTION | FL_RETURN_DESELECTION );
577 #else
578     fl_set_object_return( ob, FL_RETURN_NONE );
579 #endif
580 
581     fl_set_object_return( sp->hsl, FL_RETURN_ALWAYS );
582     fl_set_object_return( sp->vsl, FL_RETURN_ALWAYS );
583     fl_set_object_return( sp->tb,  FL_RETURN_ALWAYS );
584 
585     return ob;
586 }
587 
588 
589 /***************************************
590  * Adds a new browser object to the current form
591  ***************************************/
592 
593 FL_OBJECT *
fl_add_browser(int type,FL_Coord x,FL_Coord y,FL_Coord w,FL_Coord h,const char * label)594 fl_add_browser( int          type,
595                 FL_Coord     x,
596                 FL_Coord     y,
597                 FL_Coord     w,
598                 FL_Coord     h,
599                 const char * label )
600 {
601     FL_OBJECT *ob = fl_create_browser( type, x, y, w, h, label );
602 
603     fl_add_object( fl_current_form, ob );
604 
605     return ob;
606 }
607 
608 
609 /***************************************
610  * Switches the vertical scrollbar of the browser on or off
611  ***************************************/
612 
613 void
fl_set_browser_vscrollbar(FL_OBJECT * obj,int on_off)614 fl_set_browser_vscrollbar( FL_OBJECT * obj,
615                            int         on_off )
616 {
617     FLI_BROWSER_SPEC *comp = obj->spec;
618 
619     if ( comp->v_pref == on_off )
620         return;
621 
622     comp->v_pref = on_off;
623     redraw_scrollbar( obj );
624     fli_tbox_react_to_vert( comp->tb, on_off );
625     get_geometry( obj );
626     fl_redraw_object( obj );
627 }
628 
629 
630 /***************************************
631  * Switches the horizontal scrollbar of the browser on or off
632  ***************************************/
633 
634 void
fl_set_browser_hscrollbar(FL_OBJECT * obj,int on_off)635 fl_set_browser_hscrollbar( FL_OBJECT * obj,
636                            int         on_off )
637 {
638     FLI_BROWSER_SPEC *comp = obj->spec;
639 
640     if ( comp->h_pref == on_off )
641         return;
642 
643     comp->h_pref = on_off;
644     redraw_scrollbar( obj );
645     fli_tbox_react_to_hori( comp->tb, on_off );
646     get_geometry( obj );
647     fl_redraw_object( obj );
648 }
649 
650 
651 /***************************************
652  * Sets the callback for the horizontal scrollbar of the browser
653  ***************************************/
654 
655 void
fl_set_browser_hscroll_callback(FL_OBJECT * ob,FL_BROWSER_SCROLL_CALLBACK cb,void * data)656 fl_set_browser_hscroll_callback( FL_OBJECT                  * ob,
657                                  FL_BROWSER_SCROLL_CALLBACK   cb,
658                                  void                       * data )
659 {
660       FLI_BROWSER_SPEC *comp = ob->spec;
661 
662       comp->hcb = cb;
663       comp->hcb_data = data;
664 }
665 
666 
667 /***************************************
668  * Returns the callback for the horizontal scrollbar of the browser
669  ***************************************/
670 
671 FL_BROWSER_SCROLL_CALLBACK
fl_get_browser_hscroll_callback(FL_OBJECT * ob)672 fl_get_browser_hscroll_callback( FL_OBJECT * ob )
673 {
674       return ( ( FLI_BROWSER_SPEC * ) ob->spec )->hcb;
675 }
676 
677 
678 /***************************************
679  * Sets the callback for the vertical scrollbar of the browser
680  ***************************************/
681 
682 void
fl_set_browser_vscroll_callback(FL_OBJECT * ob,FL_BROWSER_SCROLL_CALLBACK cb,void * data)683 fl_set_browser_vscroll_callback( FL_OBJECT                  * ob,
684                                  FL_BROWSER_SCROLL_CALLBACK   cb,
685                                  void                       * data )
686 {
687       FLI_BROWSER_SPEC *comp = ob->spec;
688 
689       comp->vcb = cb;
690       comp->vcb_data = data;
691 }
692 
693 
694 /***************************************
695  * Returns the callback for the vertical scrollbar of the browser
696  ***************************************/
697 
698 FL_BROWSER_SCROLL_CALLBACK
fl_get_browser_vscroll_callback(FL_OBJECT * ob)699 fl_get_browser_vscroll_callback( FL_OBJECT * ob )
700 {
701       return ( ( FLI_BROWSER_SPEC * ) ob->spec )->vcb;
702 }
703 
704 
705 /***************************************
706  * Meant for the textbox to handle scroll callback properly
707  ***************************************/
708 
709 void
fli_adjust_browser_scrollbar(FL_OBJECT * ob)710 fli_adjust_browser_scrollbar( FL_OBJECT * ob )
711 {
712       FLI_BROWSER_SPEC *comp = ob->spec;
713 
714       fl_call_object_callback( comp->hsl );
715       fl_call_object_callback( comp->vsl );
716 }
717 
718 
719 /***************************************
720  * Removes all text from the browser
721  ***************************************/
722 
723 void
fl_clear_browser(FL_OBJECT * ob)724 fl_clear_browser( FL_OBJECT * ob )
725 {
726     FLI_BROWSER_SPEC *comp = ob->spec;
727 
728     fl_freeze_form( ob->form );
729     fli_tbox_clear( comp->tb );
730     fl_set_scrollbar_value( comp->hsl, 0.0 );
731     fl_set_scrollbar_size( comp->hsl, 1.0 );
732     fl_set_scrollbar_value( comp->vsl, 0.0 );
733     fl_set_scrollbar_size( comp->vsl, 1.0 );
734     redraw_scrollbar( ob );
735     fl_unfreeze_form( ob->form );
736 }
737 
738 
739 /***************************************
740  * Returns the x-offset of the text shown in the browser as
741  * the number of pixels
742  ***************************************/
743 
744 FL_Coord
fl_get_browser_xoffset(FL_OBJECT * obj)745 fl_get_browser_xoffset( FL_OBJECT * obj )
746 {
747     FLI_BROWSER_SPEC *sp = obj->spec;
748 
749     return fli_tbox_get_xoffset( sp->tb );
750 }
751 
752 
753 /***************************************
754  * Returns the x-offset of the text shown in the browser as a
755  * number between 0 (starts of lines are shown) and 1 (end of
756  * longest line is shown)
757  ***************************************/
758 
759 double
fl_get_browser_rel_xoffset(FL_OBJECT * obj)760 fl_get_browser_rel_xoffset( FL_OBJECT * obj )
761 {
762     FLI_BROWSER_SPEC *sp = obj->spec;
763 
764     return fli_tbox_get_rel_xoffset( sp->tb );
765 }
766 
767 
768 /***************************************
769  * Sets the x-offset of the text shown in the browser as given
770  * by the number of pixels
771  ***************************************/
772 
773 void
fl_set_browser_xoffset(FL_OBJECT * ob,FL_Coord npixels)774 fl_set_browser_xoffset( FL_OBJECT * ob,
775                         FL_Coord    npixels )
776 {
777     FLI_BROWSER_SPEC *sp = ob->spec;
778 
779     fli_tbox_set_xoffset( sp->tb, npixels );
780     redraw_scrollbar( ob );
781 }
782 
783 
784 /***************************************
785  * Sets the x-offset of the text shown in the browser as given
786  * by a value between 0 (show start of lines) and 1 (show end
787  * of longest line)
788  ***************************************/
789 
790 void
fl_set_browser_rel_xoffset(FL_OBJECT * ob,double val)791 fl_set_browser_rel_xoffset( FL_OBJECT * ob,
792                             double      val )
793 {
794     FLI_BROWSER_SPEC *sp = ob->spec;
795 
796     fli_tbox_set_rel_xoffset( sp->tb, val );
797     redraw_scrollbar( ob );
798 }
799 
800 
801 /***************************************
802  * Returns the y-offset of the text shown in the browser as
803  * the number of pixels
804  ***************************************/
805 
806 FL_Coord
fl_get_browser_yoffset(FL_OBJECT * obj)807 fl_get_browser_yoffset( FL_OBJECT * obj )
808 {
809     FLI_BROWSER_SPEC *sp = obj->spec;
810 
811     return fli_tbox_get_yoffset( sp->tb );
812 }
813 
814 
815 /***************************************
816  * Returns the y-offset of the text shown in the browser as a
817  * number between 0 (start of text is shown) and 1 (end of
818  * text is shown)
819  ***************************************/
820 
821 double
fl_get_browser_rel_yoffset(FL_OBJECT * obj)822 fl_get_browser_rel_yoffset( FL_OBJECT * obj )
823 {
824     FLI_BROWSER_SPEC *sp = obj->spec;
825 
826     return fli_tbox_get_rel_yoffset( sp->tb );
827 }
828 
829 
830 /***************************************
831  * Sets the y-offset of the text shown in the browser as given
832  * by the number of pixels
833  ***************************************/
834 
835 void
fl_set_browser_yoffset(FL_OBJECT * ob,FL_Coord npixels)836 fl_set_browser_yoffset( FL_OBJECT * ob,
837                         FL_Coord    npixels )
838 {
839     FLI_BROWSER_SPEC *sp = ob->spec;
840 
841     fli_tbox_set_yoffset( sp->tb, npixels );
842     redraw_scrollbar( ob );
843 }
844 
845 
846 /***************************************
847  * Sets the y-offset of the text shown in the browser as given
848  * by a value between 0 (show start of text) and 1 (show end of
849  * text)
850  ***************************************/
851 
852 void
fl_set_browser_rel_yoffset(FL_OBJECT * ob,double val)853 fl_set_browser_rel_yoffset( FL_OBJECT * ob,
854                             double      val )
855 {
856     FLI_BROWSER_SPEC *sp = ob->spec;
857 
858     fli_tbox_set_rel_yoffset( sp->tb, val );
859     redraw_scrollbar( ob );
860 }
861 
862 
863 /***************************************
864  * Returns the y-offset for a line (or -1 if the line does not exist).
865  ***************************************/
866 
867 int
fl_get_browser_line_yoffset(FL_OBJECT * obj,int line)868 fl_get_browser_line_yoffset( FL_OBJECT * obj,
869                              int         line )
870 {
871     FLI_BROWSER_SPEC *sp = obj->spec;
872 
873     return fli_tbox_get_line_yoffset( sp->tb, line + 1 );
874 }
875 
876 
877 /***************************************
878  * Move a line to the top of the browser
879  ***************************************/
880 
881 void
fl_set_browser_topline(FL_OBJECT * ob,int line)882 fl_set_browser_topline( FL_OBJECT * ob,
883                         int         line )
884 {
885     FLI_BROWSER_SPEC *sp = ob->spec;
886 
887     fli_tbox_set_topline( sp->tb, line - 1 );
888     redraw_scrollbar( ob );
889 }
890 
891 
892 /***************************************
893  * Move a line to the bottom of the browser
894  ***************************************/
895 
896 void
fl_set_browser_bottomline(FL_OBJECT * ob,int line)897 fl_set_browser_bottomline( FL_OBJECT * ob,
898                            int         line )
899 {
900     FLI_BROWSER_SPEC *sp = ob->spec;
901 
902     fli_tbox_set_bottomline( sp->tb, line - 1 );
903     redraw_scrollbar( ob );
904 }
905 
906 
907 /***************************************
908  * Marks a line of the browser as selected
909  ***************************************/
910 
911 void
fl_select_browser_line(FL_OBJECT * ob,int line)912 fl_select_browser_line( FL_OBJECT * ob,
913                         int         line )
914 {
915     fli_tbox_select_line( ( ( FLI_BROWSER_SPEC * ) ob->spec )->tb, line - 1 );
916 }
917 
918 
919 /***************************************
920  * Adds a line (given by a forma string and the appropriate number of
921  * argumens) to the (end of the) browser and shifts the displayed
922  * area so that the line is visible
923  ***************************************/
924 
925 void
fl_addto_browser(FL_OBJECT * obj,const char * text)926 fl_addto_browser( FL_OBJECT  * obj,
927                   const char * text )
928 {
929     fli_tbox_add_line( ( ( FLI_BROWSER_SPEC * ) obj->spec )->tb, text, 1 );
930     redraw_scrollbar( obj );
931 }
932 
933 
934 /***************************************
935  * Adds a line (specified using a format string and an unspecified number
936  * of further arguments) to the (end of the) browser and shifts the
937  * displayed area so that the line is visible
938  ***************************************/
939 
940 void
fl_addto_browser_f(FL_OBJECT * obj,const char * fmt,...)941 fl_addto_browser_f( FL_OBJECT  * obj,
942                     const char * fmt,
943                     ...)
944 {
945     char *buf;
946 
947     EXPAND_FORMAT_STRING( buf, fmt );
948     fl_addto_browser( obj, buf );
949     fl_free( buf );
950 }
951 
952 
953 /***************************************
954  * Inserts a line into the browser before the line currently
955  * having the number 'linenumb'
956  ***************************************/
957 
958 void
fl_insert_browser_line(FL_OBJECT * ob,int linenumb,const char * newtext)959 fl_insert_browser_line( FL_OBJECT  * ob,
960                         int          linenumb,
961                         const char * newtext )
962 {
963     FLI_BROWSER_SPEC *sp = ob->spec;
964     FLI_TBOX_SPEC *tbsp = sp->tb->spec;
965 
966     /* When inserting into an empty browser or appending at the end
967        it's treated exactly the same way as for fl_add_browser_line()
968        (including interpretation of newline characters). */
969 
970     if ( tbsp->num_lines == 0 || linenumb > tbsp->num_lines )
971         fli_tbox_insert_lines( sp->tb, linenumb - 1, newtext );
972     else
973         fli_tbox_insert_line( sp->tb, linenumb - 1, newtext );
974 
975     redraw_scrollbar( ob );
976 }
977 
978 
979 /***************************************
980  * Inserts a line (given by a format string and the aprropriate number
981  * of arguments) into the browser before the line currently having the
982  * number 'linenumb'
983  ***************************************/
984 
985 void
fl_insert_browser_line_f(FL_OBJECT * ob,int linenumb,const char * fmt,...)986 fl_insert_browser_line_f( FL_OBJECT  * ob,
987                           int          linenumb,
988                           const char * fmt,
989                           ... )
990 {
991     char *buf;
992 
993     EXPAND_FORMAT_STRING( buf, fmt );
994     fl_insert_browser_line( ob, linenumb, buf );
995     fl_free( buf );
996 }
997 
998 
999 /***************************************
1000  * Deletes the line at line number 'linenumb' from the browser
1001  ***************************************/
1002 
1003 void
fl_delete_browser_line(FL_OBJECT * ob,int linenumb)1004 fl_delete_browser_line( FL_OBJECT * ob,
1005                         int         linenumb )
1006 {
1007     fli_tbox_delete_line( ( ( FLI_BROWSER_SPEC * ) ob->spec )->tb,
1008                           linenumb - 1 );
1009     redraw_scrollbar( ob );
1010 }
1011 
1012 
1013 /***************************************
1014  * Replaces the browser line at line number 'linenumb' with a new one
1015  ***************************************/
1016 
1017 void
fl_replace_browser_line(FL_OBJECT * ob,int linenumb,const char * newtext)1018 fl_replace_browser_line( FL_OBJECT  * ob,
1019                          int          linenumb,
1020                          const char * newtext )
1021 {
1022     fli_tbox_replace_line( ( ( FLI_BROWSER_SPEC * ) ob->spec )->tb,
1023                            linenumb - 1, newtext );
1024     redraw_scrollbar( ob );
1025 }
1026 
1027 
1028 /***************************************
1029  * Replaces the browser line at line number 'linenumb' with a new one
1030  * derived from the format string and the following arguments.
1031  ***************************************/
1032 
1033 void
fl_replace_browser_line_f(FL_OBJECT * ob,int linenumb,const char * fmt,...)1034 fl_replace_browser_line_f( FL_OBJECT  * ob,
1035                            int          linenumb,
1036                            const char * fmt,
1037                            ... )
1038 {
1039     char *buf;
1040 
1041     EXPAND_FORMAT_STRING( buf, fmt );
1042     fl_replace_browser_line( ob, linenumb, buf );
1043     fl_free( buf );
1044 }
1045 
1046 
1047 /***************************************
1048  * Returns the text of the browser's line at line number 'linenum'.
1049  * Returned text may not be modified (and not free'ed!)
1050  ***************************************/
1051 
1052 const char *
fl_get_browser_line(FL_OBJECT * ob,int linenumb)1053 fl_get_browser_line( FL_OBJECT * ob,
1054                      int         linenumb )
1055 {
1056     return fli_tbox_get_line( ( ( FLI_BROWSER_SPEC * ) ob->spec )->tb,
1057                               linenumb - 1 );
1058 }
1059 
1060 
1061 /***************************************
1062  * Returns the number of the last line of the browser
1063  ***************************************/
1064 
1065 int
fl_get_browser_maxline(FL_OBJECT * obj)1066 fl_get_browser_maxline( FL_OBJECT * obj )
1067 {
1068     FLI_BROWSER_SPEC *sp = obj->spec;
1069 
1070     return fli_tbox_get_num_lines( sp->tb );
1071 }
1072 
1073 
1074 /***************************************
1075  * Unselects a line in the browser
1076  ***************************************/
1077 
1078 void
fl_deselect_browser_line(FL_OBJECT * ob,int line)1079 fl_deselect_browser_line( FL_OBJECT * ob,
1080                           int         line )
1081 {
1082     fli_tbox_deselect_line( ( ( FLI_BROWSER_SPEC * ) ob->spec )->tb, line - 1 );
1083 }
1084 
1085 
1086 /***************************************
1087  * De-selects all lines of the browser
1088  ***************************************/
1089 
1090 void
fl_deselect_browser(FL_OBJECT * ob)1091 fl_deselect_browser( FL_OBJECT * ob )
1092 {
1093     fli_tbox_deselect( ( ( FLI_BROWSER_SPEC * ) ob->spec )->tb );
1094 }
1095 
1096 
1097 /***************************************
1098  * Tests if a certain line of the browser is selected
1099  ***************************************/
1100 
1101 int
fl_isselected_browser_line(FL_OBJECT * ob,int line)1102 fl_isselected_browser_line( FL_OBJECT * ob,
1103                             int         line )
1104 {
1105     FLI_BROWSER_SPEC *sp = ob->spec;
1106 
1107     return fli_tbox_is_line_selected( sp->tb, line - 1 );
1108 }
1109 
1110 
1111 /***************************************
1112  * Returns the line last selected (or deselected) by the user
1113  ***************************************/
1114 
1115 int
fl_get_browser(FL_OBJECT * ob)1116 fl_get_browser( FL_OBJECT * ob )
1117 {
1118     FLI_BROWSER_SPEC *sp = ob->spec;
1119 
1120     return fli_tbox_get_selection( sp->tb );
1121 }
1122 
1123 
1124 /***************************************
1125  * Sets the font size to be used per default
1126  ***************************************/
1127 
1128 void
fl_set_browser_fontsize(FL_OBJECT * ob,int size)1129 fl_set_browser_fontsize( FL_OBJECT * ob,
1130                          int         size )
1131 {
1132     FLI_BROWSER_SPEC *sp = ob->spec;
1133 
1134     fli_tbox_set_fontsize( sp->tb, size );
1135     redraw_scrollbar( ob );
1136     fl_redraw_object( ob );
1137 }
1138 
1139 
1140 /***************************************
1141  * Sets the font style to be used per default
1142  ***************************************/
1143 
1144 void
fl_set_browser_fontstyle(FL_OBJECT * ob,int style)1145 fl_set_browser_fontstyle( FL_OBJECT * ob,
1146                           int         style )
1147 {
1148     FLI_BROWSER_SPEC *sp = ob->spec;
1149 
1150     fli_tbox_set_fontstyle( sp->tb, style );
1151     redraw_scrollbar( ob );
1152     fl_redraw_object( ob );
1153 }
1154 
1155 
1156 /***************************************
1157  * Returns the number of the topmost line that is completely visible,
1158  * may return 0 if there are no lines in the browser
1159  ***************************************/
1160 
1161 int
fl_get_browser_topline(FL_OBJECT * obj)1162 fl_get_browser_topline( FL_OBJECT * obj )
1163 {
1164     FLI_BROWSER_SPEC *sp = obj->spec;
1165 
1166     return fli_tbox_get_topline( sp->tb ) + 1;
1167 }
1168 
1169 
1170 /***************************************
1171  * Loads a browser with text from a file
1172  ***************************************/
1173 
1174 int
fl_load_browser(FL_OBJECT * obj,const char * f)1175 fl_load_browser( FL_OBJECT  * obj,
1176                  const char * f )
1177 {
1178     FLI_BROWSER_SPEC *sp = obj->spec;
1179     int status;
1180 
1181     fl_clear_browser( obj );
1182     status = fli_tbox_load( sp->tb, f );
1183     redraw_scrollbar( obj );
1184     return status;
1185 }
1186 
1187 
1188 /***************************************
1189  * Adds a line to the (end of the) browser (does not make the line
1190  * visible)
1191  ***************************************/
1192 
1193 void
fl_add_browser_line(FL_OBJECT * ob,const char * newtext)1194 fl_add_browser_line( FL_OBJECT  * ob,
1195                      const char * newtext )
1196 {
1197     FLI_BROWSER_SPEC *sp = ob->spec;
1198 
1199     fli_tbox_add_line( sp->tb, newtext, 0 );
1200     redraw_scrollbar( ob );
1201 }
1202 
1203 
1204 /***************************************
1205  * Adds a line to the (end of the) browser (does not make the line
1206  * visible)
1207  ***************************************/
1208 
1209 void
fl_add_browser_line_f(FL_OBJECT * ob,const char * fmt,...)1210 fl_add_browser_line_f( FL_OBJECT  * ob,
1211                        const char * fmt,
1212                        ... )
1213 {
1214     char *buf;
1215 
1216     EXPAND_FORMAT_STRING( buf, fmt );
1217     fl_add_browser_line( ob,buf );
1218     fl_free( buf );
1219 }
1220 
1221 
1222 /***************************************
1223  * Sets a callback for double clicks in the browser
1224  ***************************************/
1225 
1226 void
fl_set_browser_dblclick_callback(FL_OBJECT * ob,FL_CALLBACKPTR cb,long a)1227 fl_set_browser_dblclick_callback( FL_OBJECT      * ob,
1228                                   FL_CALLBACKPTR   cb,
1229                                   long             a )
1230 {
1231     FLI_BROWSER_SPEC *comp = ob->spec;
1232 
1233     comp->callback = cb;
1234     comp->callback_data = a;
1235 }
1236 
1237 
1238 /***************************************
1239  * Sets the height of the vertical and the width of the horzontal
1240  * scrollbar
1241  ***************************************/
1242 
1243 void
fl_set_browser_scrollbarsize(FL_OBJECT * ob,int hh,int vw)1244 fl_set_browser_scrollbarsize( FL_OBJECT * ob,
1245                               int         hh,
1246                               int         vw )
1247 {
1248     FLI_BROWSER_SPEC *comp = ob->spec;
1249     int redraw = 0;
1250 
1251     if ( hh > 0 && hh != comp->hsl->h )
1252     {
1253         comp->hsl->h = comp->hh_def = hh;
1254         redraw = 1;
1255     }
1256 
1257     if ( vw > 0 && vw != comp->vsl->w )
1258     {
1259         comp->vsl->w = comp->vw_def = vw;
1260         redraw = 1;
1261     }
1262 
1263     if ( redraw )
1264     {
1265         comp->user_set = 1;
1266         fl_redraw_object( ob );
1267         fl_redraw_object( comp->tb );
1268         fl_redraw_object( comp->hsl );
1269         fl_redraw_object( comp->vsl );
1270     }
1271 }
1272 
1273 
1274 /***************************************
1275  * Returns the position and width and height of the browsers text area
1276  ***************************************/
1277 
1278 void
fl_get_browser_dimension(FL_OBJECT * obj,FL_Coord * x,FL_Coord * y,FL_Coord * w,FL_Coord * h)1279 fl_get_browser_dimension( FL_OBJECT * obj,
1280                           FL_Coord  * x,
1281                           FL_Coord  * y,
1282                           FL_Coord  * w,
1283                           FL_Coord  * h )
1284 {
1285     FLI_TBOX_SPEC *sp = ( ( FLI_BROWSER_SPEC * ) obj->spec )->tb->spec;
1286 
1287     *x = obj->x + sp->x;
1288     *y = obj->y + sp->y;
1289     *w = sp->w;
1290     *h = sp->h;
1291 }
1292 
1293 
1294 /***************************************
1295  * Makes a browser line selectable or unselectable
1296  ***************************************/
1297 
1298 void
fl_set_browser_line_selectable(FL_OBJECT * ob,int line,int flag)1299 fl_set_browser_line_selectable( FL_OBJECT * ob,
1300                                 int         line,
1301                                 int         flag )
1302 {
1303     fli_tbox_make_line_selectable( ob, line - 1, flag );
1304 }
1305 
1306 
1307 /***************************************
1308  * Appends characters to the end of the last line in the browser
1309  ***************************************/
1310 
1311 void
fl_addto_browser_chars(FL_OBJECT * ob,const char * str)1312 fl_addto_browser_chars( FL_OBJECT  * ob,
1313                         const char * str )
1314 {
1315     FLI_BROWSER_SPEC *sp = ob->spec;
1316 
1317     fli_tbox_add_chars( sp->tb, str );
1318     redraw_scrollbar( ob );
1319 }
1320 
1321 
1322 /***************************************
1323  * Appends characters to the end of the last line in the browser
1324  ***************************************/
1325 
1326 void
fl_addto_browser_chars_f(FL_OBJECT * ob,const char * fmt,...)1327 fl_addto_browser_chars_f( FL_OBJECT  * ob,
1328                           const char * fmt,
1329                           ... )
1330 {
1331     char *buf;
1332 
1333     EXPAND_FORMAT_STRING( buf, fmt );
1334     fl_addto_browser_chars_f( ob, buf );
1335     fl_free( buf );
1336 }
1337 
1338 
1339 /***************************************
1340  * Returns an approximation of the number of lines shown in the browser
1341  ***************************************/
1342 
1343 int
fl_get_browser_screenlines(FL_OBJECT * ob)1344 fl_get_browser_screenlines( FL_OBJECT * ob )
1345 {
1346     FLI_BROWSER_SPEC *sp = ob->spec;
1347 
1348     int t = fli_tbox_get_topline( sp->tb );
1349     int b = fli_tbox_get_bottomline( sp->tb );
1350 
1351     if ( t < 0 || b < 0 )
1352         return 0;
1353     return b - t + 1;
1354 }
1355 
1356 
1357 /***************************************
1358  * Sets the escape key used in the text
1359  ***************************************/
1360 
1361 void
fl_set_browser_specialkey(FL_OBJECT * ob,int specialkey)1362 fl_set_browser_specialkey( FL_OBJECT * ob,
1363                            int         specialkey )
1364 {
1365     FLI_TBOX_SPEC *sp = ( ( FLI_BROWSER_SPEC * ) ob->spec )->tb->spec;
1366 
1367     sp->specialkey = specialkey;
1368 }
1369 
1370 
1371 /***************************************
1372  * Brings a line into view
1373  ***************************************/
1374 
1375 void
fl_show_browser_line(FL_OBJECT * ob,int line)1376 fl_show_browser_line( FL_OBJECT * ob,
1377                       int         line )
1378 {
1379     fli_tbox_set_centerline( ( ( FLI_BROWSER_SPEC * ) ob->spec )->tb, line );
1380     redraw_scrollbar( ob );
1381 }
1382 
1383 
1384 /***************************************
1385  * Deprecated function, only left in for backward compatibility
1386  ***************************************/
1387 
1388 int
fl_set_default_browser_maxlinelength(int n FL_UNUSED_ARG)1389 fl_set_default_browser_maxlinelength( int n  FL_UNUSED_ARG )
1390 {
1391     return 0;
1392 }
1393 
1394 
1395 /***************************************
1396  ***************************************/
1397 
1398 int
fl_get_browser_scrollbar_repeat(FL_OBJECT * ob)1399 fl_get_browser_scrollbar_repeat( FL_OBJECT * ob )
1400 {
1401     return fl_get_slider_repeat( ( ( FLI_BROWSER_SPEC * ) ob->spec )->vsl );
1402 }
1403 
1404 
1405 /***************************************
1406  ***************************************/
1407 
1408 void
fl_set_browser_scrollbar_repeat(FL_OBJECT * ob,int millisec)1409 fl_set_browser_scrollbar_repeat( FL_OBJECT * ob,
1410                                  int         millisec )
1411 {
1412     if ( millisec > 0 )
1413     {
1414         fl_set_slider_repeat( ( ( FLI_BROWSER_SPEC * ) ob->spec )->vsl,
1415                               millisec );
1416         fl_set_slider_repeat( ( ( FLI_BROWSER_SPEC * ) ob->spec )->hsl,
1417                               millisec );
1418     }
1419 }
1420 
1421 
1422 /*
1423  * Local variables:
1424  * tab-width: 4
1425  * indent-tabs-mode: nil
1426  * End:
1427  */
1428