1 /*
2 * This file is part of XForms.
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 fd_spec.c
21 *
22 * This file is part of XForms package
23 * Copyright (c) 1996-2002 T.C. Zhao and Mark Overmars
24 * All rights reserved.
25 *
26 * Driver for setting object specific info
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include <string.h>
34 #include <ctype.h>
35
36 #include "fd_main.h"
37 #include "fd_spec.h"
38 #include "fd_iconinfo.h"
39
40 #include "sp_slider.h"
41 #include "sp_counter.h"
42 #include "sp_spinner.h"
43 #include "sp_dial.h"
44 #include "sp_positioner.h"
45 #include "sp_twheel.h"
46 #include "sp_button.h"
47 #include "sp_pixmap.h"
48 #include "sp_scrollbar.h"
49 #include "sp_browser.h"
50 #include "sp_choice.h"
51 #include "sp_menu.h"
52 #include "sp_xyplot.h"
53 #include "sp_freeobj.h"
54
55
56 #define MAXOBJCLASS 9
57
58 typedef struct
59 {
60 /* List of object classes this entry is for */
61
62 int objclass[ MAXOBJCLASS ];
63
64 /* Function to be called for changing the objects type */
65
66 void ( * change_type )( FL_OBJECT *, int );
67
68 /* Function for creating the form for editing the specific object
69 attributes */
70
71 FL_FORM * ( * create_spec_form )( void );
72
73 /* Function for adjustments of the form for e.g. the objects type */
74
75 void ( * adjust_spec_form )( FL_OBJECT * );
76
77 /* Function for setting up the form with the objects attributes */
78
79 void ( * fill_in_spec_form )( FL_OBJECT * );
80
81 /* Function for setting up the object attributes according to the forms
82 data */
83
84 void ( * reread_spec_form )( FL_OBJECT * );
85
86 /* Object specific code to be run when object got restored */
87
88 void ( * restore_spec )( FL_OBJECT * );
89
90 /* Function for emitting code for the fd file for the object */
91
92 void ( * emit_spec_fd_code )( FILE *, FL_OBJECT * );
93
94 /* Function for emitting C code for the object */
95
96 void ( * emit_spec_c_code )( FILE *, FL_OBJECT * );
97
98 /* Function for emitting header code for the object */
99
100 void ( * emit_spec_header )( FILE *, FL_OBJECT * );
101
102 /* */
103
104 void ( * emit_spec_global_header )( FILE *, FL_OBJECT * );
105
106 } ObjSPEC;
107
108 static ObjSPEC objspec[ ] =
109 {
110 {
111 { FL_SLIDER,
112 FL_VALSLIDER },
113 NULL,
114 slider_create_spec_form,
115 slider_adjust_spec_form,
116 slider_fill_in_spec_form,
117 slider_reread_spec_form,
118 NULL,
119 slider_emit_spec_fd_code,
120 slider_emit_spec_c_code,
121 NULL,
122 NULL
123 },
124
125 {
126 { FL_COUNTER },
127 NULL,
128 counter_create_spec_form,
129 counter_adjust_spec_form,
130 counter_fill_in_spec_form,
131 counter_reread_spec_form,
132 NULL,
133 counter_emit_spec_fd_code,
134 counter_emit_spec_c_code,
135 NULL,
136 NULL
137 },
138
139 {
140 { FL_SPINNER },
141 spinner_change_type,
142 spinner_create_spec_form,
143 spinner_adjust_spec_form,
144 spinner_fill_in_spec_form,
145 spinner_reread_spec_form,
146 NULL,
147 spinner_emit_spec_fd_code,
148 spinner_emit_spec_c_code,
149 NULL,
150 NULL
151 },
152
153 {
154 { FL_DIAL },
155 NULL,
156 dial_create_spec_form,
157 NULL,
158 dial_fill_in_spec_form,
159 dial_reread_spec_form,
160 NULL,
161 dial_emit_spec_fd_code,
162 dial_emit_spec_c_code,
163 NULL,
164 NULL
165 },
166
167 {
168 { FL_POSITIONER },
169 NULL,
170 positioner_create_spec_form,
171 NULL,
172 positioner_fill_in_spec_form,
173 positioner_reread_spec_form,
174 NULL,
175 positioner_emit_spec_fd_code,
176 positioner_emit_spec_c_code,
177 NULL,
178 NULL
179 },
180
181 {
182 { FL_THUMBWHEEL },
183 NULL,
184 thwheel_create_spec_form,
185 NULL,
186 twheel_fill_in_spec_form,
187 twheel_reread_spec_form,
188 NULL,
189 twheel_emit_spec_fd_code,
190 twheel_emit_spec_c_code,
191 NULL,
192 NULL
193 },
194
195 {
196 { FL_PIXMAPBUTTON,
197 FL_BITMAPBUTTON,
198 FL_BUTTON,
199 FL_CHECKBUTTON,
200 FL_SCROLLBUTTON,
201 FL_ROUNDBUTTON,
202 FL_LIGHTBUTTON,
203 FL_ROUND3DBUTTON,
204 FL_LABELBUTTON },
205 NULL,
206 button_create_spec_form,
207 button_adjust_spec_form,
208 button_fill_in_spec_form,
209 button_reread_spec_form,
210 button_restore_spec,
211 button_emit_spec_fd_code,
212 button_emit_spec_c_code,
213 button_emit_spec_header,
214 NULL
215 },
216
217 {
218 { FL_PIXMAP,
219 FL_BITMAP },
220 NULL,
221 pixmap_create_spec_form,
222 pixmap_adjust_spec_form,
223 pixmap_fill_in_spec_form,
224 pixmap_reread_spec_form,
225 pixmap_restore_spec,
226 pixmap_emit_spec_fd_code,
227 pixmap_emit_spec_c_code,
228 pixmap_emit_spec_header,
229 NULL
230 },
231
232 {
233 { FL_SCROLLBAR },
234 NULL,
235 scrollbar_create_spec_form,
236 scrollbar_adjust_spec_form,
237 scrollbar_fill_in_spec_form,
238 scrollbar_reread_spec_form,
239 NULL,
240 scrollbar_emit_spec_fd_code,
241 scrollbar_emit_spec_c_code,
242 NULL,
243 NULL
244 },
245
246 {
247 { FL_BROWSER },
248 NULL,
249 browser_create_spec_form,
250 NULL,
251 browser_fill_in_spec_form,
252 NULL,
253 NULL,
254 browser_emit_spec_fd_code,
255 browser_emit_spec_c_code,
256 NULL,
257 NULL
258 },
259
260 {
261 { FL_CHOICE },
262 NULL,
263 choice_create_spec_form,
264 NULL,
265 choice_fill_in_spec_form,
266 NULL,
267 NULL,
268 choice_emit_spec_fd_code,
269 choice_emit_spec_c_code,
270 NULL,
271 NULL
272 },
273
274 {
275 { FL_MENU },
276 NULL,
277 menu_create_spec_form,
278 NULL,
279 menu_fill_in_spec_form,
280 NULL,
281 NULL,
282 menu_emit_spec_fd_code,
283 menu_emit_spec_c_code,
284 menu_emit_spec_header,
285 menu_emit_spec_global_header
286 },
287
288 {
289 { FL_XYPLOT },
290 NULL,
291 xyplot_create_spec_form,
292 xyplot_adjust_spec_form,
293 xyplot_fill_in_spec_form,
294 NULL,
295 NULL,
296 xyplot_emit_spec_fd_code,
297 xyplot_emit_spec_c_code,
298 NULL,
299 NULL
300 },
301
302 {
303 { FL_FREE },
304 NULL,
305 freeobj_create_spec_form,
306 freeobj_adjust_spec_form,
307 freeobj_fill_in_spec_form,
308 freeobj_reread_spec_form,
309 freeobj_restore_spec,
310 freeobj_emit_spec_fd_code,
311 NULL,
312 NULL,
313 NULL
314 }
315 };
316
317
318 /***************************************
319 * Find the entry in the list of classes for the objects class
320 ***************************************/
321
322 static ObjSPEC *
find_entry(FL_OBJECT * ob)323 find_entry( FL_OBJECT * ob )
324 {
325 size_t i;
326
327 for ( i = 0; i < sizeof objspec / sizeof *objspec; i++ )
328 {
329 int *cls = objspec[ i ].objclass;
330
331 for ( ; *cls > 0; cls++ )
332 if ( *cls == ob->objclass )
333 return objspec + i;
334 }
335
336 return NULL;
337 }
338
339
340 /***************************************
341 ***************************************/
342
343 /***************************************
344 * Returns the form to be shown for the "Spec" tab folder
345 ***************************************/
346
347 void
spec_change_type(FL_OBJECT * obj,int new_type)348 spec_change_type( FL_OBJECT * obj,
349 int new_type )
350 {
351 ObjSPEC *spec = find_entry( obj );
352 FL_OBJECT * defobj;
353
354 if ( obj->type == new_type )
355 return;
356
357 /* Different types may have different default box types. If the user
358 obviously didn't change the box type (i.e. expects the default) make
359 sure that the box type is the default for the object type we switch
360 to. */
361
362 defobj = find_class_default( obj->objclass, new_type );
363
364 if ( defobj && defobj->boxtype == obj->boxtype )
365 obj->boxtype = defobj->boxtype;
366
367 if ( spec && spec->change_type )
368 spec->change_type( obj, new_type );
369 else
370 obj->type = new_type;
371 }
372
373
374 /***************************************
375 * Returns the form to be shown for the "Spec" tab folder (or NULL If none
376 * exists)
377 ***************************************/
378
379 FL_FORM *
create_spec_form(FL_OBJECT * obj)380 create_spec_form( FL_OBJECT * obj )
381 {
382 ObjSPEC *spec = find_entry( obj );
383
384 return ( spec && spec->create_spec_form ) ?
385 spec->create_spec_form( ) : NULL;
386 }
387
388
389 /***************************************
390 * Prepare the form for the object specific attributes for becoming shown
391 * - the form may need adjustments because e.g. the objects type has been
392 * changed and then the form content also have to be modified. Then fill
393 * in all the objects attributes.
394 ***************************************/
395
396 void
prepare_spec_form(FL_OBJECT * obj)397 prepare_spec_form( FL_OBJECT * obj )
398 {
399 ObjSPEC *spec = find_entry( obj );
400
401 if ( ! spec )
402 return;
403
404 /* The form may need some modification,. e.g because the objects type
405 has been changed */
406
407 if ( spec->adjust_spec_form )
408 spec->adjust_spec_form( obj );
409
410 /* Fill in the current settings of the objects attributes into the form */
411
412 if ( spec->fill_in_spec_form )
413 spec->fill_in_spec_form( obj );
414 }
415
416
417 /***************************************
418 * When switching back to the "Generic" form or on end of editing
419 * an input field may not have been processed yet, thus reread all
420 * input fields in the form for the object specific attributes (and
421 * make sure the object gets shown with the potentially modified
422 * attributes).
423 ***************************************/
424
425 void
reread_spec_form(FL_OBJECT * obj)426 reread_spec_form( FL_OBJECT * obj )
427 {
428 ObjSPEC *spec = find_entry( obj );
429
430 if ( spec && spec->reread_spec_form )
431 {
432 spec->reread_spec_form( obj );
433 redraw_the_form( 0 );
434 }
435 }
436
437
438 /***************************************
439 ***************************************/
440
441 void
restore_spec(FL_OBJECT * obj)442 restore_spec( FL_OBJECT * obj )
443 {
444 ObjSPEC *spec = find_entry( obj );
445
446 if ( spec && spec->restore_spec )
447 {
448 spec->restore_spec( obj );
449 redraw_the_form( 0 );
450 }
451 }
452
453
454 /***************************************
455 * Function called for writing out object class specific
456 * information for an object to an .fd file
457 ***************************************/
458
459 void
save_objclass_spec_info(FILE * fp,FL_OBJECT * obj)460 save_objclass_spec_info( FILE * fp,
461 FL_OBJECT * obj )
462 {
463 ObjSPEC *spec = find_entry( obj );
464
465 if ( spec && spec->emit_spec_fd_code )
466 spec->emit_spec_fd_code( fp, obj );
467 }
468
469
470 /***************************************
471 * Function called for writing out object class specific
472 * information for an object to a .c file
473 ***************************************/
474
475 void
emit_objclass_spec_info(FILE * fp,FL_OBJECT * obj)476 emit_objclass_spec_info( FILE * fp,
477 FL_OBJECT * obj )
478 {
479 ObjSPEC *spec = find_entry( obj );
480
481 if ( spec && spec->emit_spec_c_code )
482 spec->emit_spec_c_code( fp, obj );
483 }
484
485
486 /***************************************
487 * Emit (file scope) variable code
488 ***************************************/
489
490 void
emit_objclass_spec_header(FILE * fp,FL_OBJECT * obj)491 emit_objclass_spec_header( FILE * fp,
492 FL_OBJECT * obj )
493 {
494 ObjSPEC *spec = find_entry( obj );
495
496 if ( spec && spec->emit_spec_header )
497 spec->emit_spec_header( fp, obj );
498 }
499
500
501 /***************************************
502 * Emit global variable declarations
503 ***************************************/
504
505 void
emit_objclass_spec_global(FILE * fp,FL_OBJECT * obj)506 emit_objclass_spec_global( FILE * fp,
507 FL_OBJECT * obj )
508 {
509 ObjSPEC *spec = find_entry( obj );
510
511 if ( spec && spec->emit_spec_global_header )
512 spec->emit_spec_global_header( fp, obj );
513 }
514
515
516 /***************************************
517 ***************************************/
518
519 static int
ff_read_sp_bounds(FL_OBJECT * obj,SuperSPEC * sp)520 ff_read_sp_bounds( FL_OBJECT * obj,
521 SuperSPEC * sp )
522 {
523 int r;
524
525 if ( ( obj->objclass == FL_SPINNER
526 && ( r = ff_read( "%F%F", &sp->dmin, &sp->dmax ) ) < 0 )
527 || ( obj->objclass != FL_SPINNER
528 && ( r = ff_read( "%F%F", &sp->min, &sp->max ) ) < 0 ) )
529 return ff_err( "Can't read expected object bounds" );
530
531 if ( r == 0 )
532 return ff_err( "\"bounds\" key with no or invalid values" );
533 else if ( r == 1 )
534 return ff_err( "\"bounds\" key with only one (valid) value" );
535
536 return 0;
537 }
538
539
540 /***************************************
541 ***************************************/
542
543 static int
ff_read_sp_precision(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)544 ff_read_sp_precision( FL_OBJECT * obj FL_UNUSED_ARG,
545 SuperSPEC * sp )
546 {
547 int r;
548
549 if ( ( r = ff_read( "%d", &sp->prec ) ) < 0 )
550 return ff_err( "Can't read expected object precision" );
551
552 if ( r == 0 )
553 return ff_err( "\"precision\" key with no or invalid value" );
554
555 return 0;
556 }
557
558
559 /***************************************
560 ***************************************/
561
562 static int
ff_read_sp_increment(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)563 ff_read_sp_increment( FL_OBJECT * obj FL_UNUSED_ARG,
564 SuperSPEC * sp )
565 {
566 int r;
567
568 if ( ( r = ff_read( "%F%F", &sp->ldelta, &sp->rdelta) ) < 0 )
569 return ff_err( "Can't read expected object increment values" );
570
571 if ( r == 0 )
572 return ff_err( "\"increment\" key with no or invalid values" );
573 else if ( r == 1 )
574 return ff_err( "\"increment\" key with only one valid value" );
575
576 return 0;
577 }
578
579
580 /***************************************
581 ***************************************/
582
583 static int
ff_read_sp_value(FL_OBJECT * obj,SuperSPEC * sp)584 ff_read_sp_value( FL_OBJECT * obj,
585 SuperSPEC * sp )
586 {
587 int r;
588
589 if ( ISBUTTON( obj->objclass ) || ISCHOICE( obj->objclass ) )
590 {
591 if ( ( r = ff_read( "%d", &sp->int_val ) ) < 0 )
592 return ff_err( "Can't read expected object value" );
593
594 if ( ISBUTTON( obj->objclass ) )
595 fl_set_button( obj, sp->int_val );
596 }
597 else if ( obj->objclass == FL_SPINNER )
598 {
599 if ( ( r = ff_read( "%F", &sp->dval ) ) < 0 )
600 return ff_err( "Can't read expected object value" );
601 }
602 else if ( ( r = ff_read( "%F", &sp->val ) ) < 0 )
603 return ff_err( "Can't read expected object value" );
604
605 if ( r == 0 )
606 return ff_err( "\"value\" key with no or invalid value" );
607
608 return 0;
609 }
610
611
612 /***************************************
613 ***************************************/
614
615 static int
ff_read_sp_slsize(FL_OBJECT * ob FL_UNUSED_ARG,SuperSPEC * sp)616 ff_read_sp_slsize( FL_OBJECT * ob FL_UNUSED_ARG,
617 SuperSPEC * sp )
618 {
619 int r;
620 if ( ( r = ff_read( "%F", &sp->slsize ) ) < 0 )
621 return ff_err( "Can't read expected object slider size" );
622
623 if ( r == 0 )
624 return ff_err( "\"slsize\" key with no or invalid value" );
625
626 return 0;
627 }
628
629
630 /***************************************
631 ***************************************/
632
633 static int
ff_read_sp_step(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)634 ff_read_sp_step( FL_OBJECT * obj FL_UNUSED_ARG,
635 SuperSPEC * sp )
636 {
637 int r;
638
639 if ( ( obj->objclass == FL_SPINNER
640 && ( r = ff_read( "%F", &sp->dstep ) ) < 0 )
641 || ( obj->objclass != FL_SPINNER
642 && ( r = ff_read( "%F", &sp->step ) ) < 0 ) )
643 return ff_err( "Can't read expected object step" );
644
645 if ( r == 0 )
646 return ff_err( "\"step\" key with no or invalid value" );
647
648 return 0;
649 }
650
651
652 /***************************************
653 ***************************************/
654
655 static int
ff_read_sp_h_pref(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)656 ff_read_sp_h_pref( FL_OBJECT * obj FL_UNUSED_ARG,
657 SuperSPEC * sp )
658 {
659 int r;
660 char *p;
661 int i;
662
663 if ( ( r = ff_read( "%v", &p ) ) < 0 )
664 return ff_err( "Can't read expected object h_pref" );
665
666 if ( r == 0 )
667 return ff_err( "\"h_pref\" key with no or invalid value" );
668
669 i = get_scrollbar_pref_value( p );
670
671 fli_safe_free( p );
672
673 if ( i < 0 )
674 return ff_err( "Invalid value for \"h_pref\" key" );
675
676 sp->h_pref = i;
677
678 return 0;
679 }
680
681
682 /***************************************
683 ***************************************/
684
685 static int
ff_read_sp_v_pref(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)686 ff_read_sp_v_pref( FL_OBJECT * obj FL_UNUSED_ARG,
687 SuperSPEC * sp )
688 {
689 int r;
690 char *p;
691 int i;
692
693 if ( ( r = ff_read( "%v", &p ) ) < 0 )
694 return ff_err( "Can't read expected object v_pref" );
695
696 if ( r == 0 )
697 return ff_err( "\"v_pref\" key with no or invalid value" );
698
699 i = get_scrollbar_pref_value( p );
700
701 fli_safe_free( p );
702
703 if ( i < 0 )
704 return ff_err( "Invalid value for \"v_pref\" key" );
705
706 sp->v_pref = i;
707
708 return 0;
709 }
710
711
712 /***************************************
713 ***************************************/
714
715 static int
ff_read_sp_sstep(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)716 ff_read_sp_sstep( FL_OBJECT * obj FL_UNUSED_ARG,
717 SuperSPEC * sp )
718 {
719 int r;
720
721 if ( ( r = ff_read( "%F", &sp->sstep ) ) < 0 )
722 return ff_err( "Can't read expected object small step" );
723
724 if ( r == 0 )
725 return ff_err( "\"sstep\" key with no or invalid value" );
726
727 return 0;
728 }
729
730
731 /***************************************
732 ***************************************/
733
734 static int
ff_read_sp_lstep(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)735 ff_read_sp_lstep( FL_OBJECT * obj FL_UNUSED_ARG,
736 SuperSPEC * sp )
737 {
738 int r;
739
740 if ( ( r = ff_read( "%F", &sp->lstep ) ) < 0 )
741 return ff_err( "Can't read expected object large step" );
742
743 if ( r == 0 )
744 return ff_err( "\"lstep\" key with no or invalid value" );
745
746 return 0;
747 }
748
749
750 /***************************************
751 ***************************************/
752
753 static int
ff_read_sp_xbounds(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)754 ff_read_sp_xbounds( FL_OBJECT * obj FL_UNUSED_ARG,
755 SuperSPEC * sp )
756 {
757 int r;
758
759 if ( ( r = ff_read( "%F%F", &sp->xmin, &sp->xmax ) ) < 0 )
760 return ff_err( "Can't read expected object xbounds" );
761
762 if ( r == 0 )
763 return ff_err( "\"xbounds\" key with no or invalid values" );
764 else if ( r == 1 )
765 return ff_err( "\"xbounds\" key with only one valid value" );
766
767 return 0;
768 }
769
770
771 /***************************************
772 ***************************************/
773
774 static int
ff_read_sp_ybounds(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)775 ff_read_sp_ybounds( FL_OBJECT * obj FL_UNUSED_ARG,
776 SuperSPEC * sp )
777 {
778 int r;
779
780 if ( ( r = ff_read( "%F%F", &sp->ymin, &sp->ymax ) ) < 0 )
781 return ff_err( "Can't read expected object ybounds" );
782
783 if ( r == 0 )
784 return ff_err( "\"ybounds\" key with no or invalid values" );
785 else if ( r == 1 )
786 return ff_err( "\"ybounds\" key with only one valid value" );
787
788 return 0;
789 }
790
791
792 /***************************************
793 ***************************************/
794
795 static int
ff_read_sp_xvalue(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)796 ff_read_sp_xvalue( FL_OBJECT * obj FL_UNUSED_ARG,
797 SuperSPEC * sp )
798 {
799 int r;
800
801 if ( ( r = ff_read( "%F", &sp->xval ) ) < 0 )
802 return ff_err( "Can't read expected object xvalue" );
803
804 if ( r == 0 )
805 return ff_err( "\"xvalue\" key with no or invalid value" );
806
807 return 0;
808 }
809
810
811 /***************************************
812 ***************************************/
813
814 static int
ff_read_sp_yvalue(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)815 ff_read_sp_yvalue( FL_OBJECT * obj FL_UNUSED_ARG,
816 SuperSPEC * sp )
817 {
818 int r;
819
820 if ( ( r = ff_read( "%F", &sp->yval ) ) < 0 )
821 return ff_err( "Can't read expected object yvalue" );
822
823 if ( r == 0 )
824 return ff_err( "\"yvalue\" key with no or invalid value" );
825
826 return 0;
827 }
828
829
830 /***************************************
831 ***************************************/
832
833 static int
ff_read_sp_xstep(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)834 ff_read_sp_xstep( FL_OBJECT * obj FL_UNUSED_ARG,
835 SuperSPEC * sp )
836 {
837 int r;
838
839 if ( ( r = ff_read( "%F", &sp->xstep ) ) < 0 )
840 return ff_err( "Can't read expected object xstep" );
841
842 if ( r == 0 )
843 return ff_err( "\"xstep\" key with no or invalid value" );
844
845 return 0;
846 }
847
848
849 /***************************************
850 ***************************************/
851
852 static int
ff_read_sp_ystep(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)853 ff_read_sp_ystep( FL_OBJECT * obj FL_UNUSED_ARG,
854 SuperSPEC * sp )
855 {
856 int r;
857
858 if ( ( r = ff_read( "%F", &sp->ystep ) ) < 0 )
859 return ff_err( "Can't read expected object ystep" );
860
861 if ( r == 0 )
862 return ff_err( "\"ystep\" key with no or invalid value" );
863
864 return 0;
865 }
866
867
868 /***************************************
869 ***************************************/
870
871 static int
ff_read_sp_angles(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)872 ff_read_sp_angles( FL_OBJECT * obj FL_UNUSED_ARG,
873 SuperSPEC * sp )
874 {
875 int r;
876
877 if ( ( r = ff_read( "%F%F", &sp->thetai, &sp->thetaf ) ) < 0 )
878 return ff_err( "Can't read expected object angles" );
879
880 if ( r == 0 )
881 return ff_err( "\"angles\" key with no or invalid values" );
882 else if ( r == 1 )
883 return ff_err( "\"angles\" key with only one valid value" );
884
885 return 0;
886 }
887
888
889 /***************************************
890 ***************************************/
891
892 static int
ff_read_sp_mbuttons(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)893 ff_read_sp_mbuttons( FL_OBJECT * obj FL_UNUSED_ARG,
894 SuperSPEC * sp )
895 {
896 int r;
897
898 if ( ( r = ff_read( "%d", &sp->mbuttons ) ) < 0 )
899 return ff_err( "Can't read expected object mbuttons setting" );
900
901 if ( r == 0 )
902 return ff_err( "\"mbuttons\" key with no or invalid value" );
903
904 return 0;
905 }
906
907
908 /***************************************
909 ***************************************/
910
911 static int
ff_read_sp_initial_val(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)912 ff_read_sp_initial_val( FL_OBJECT * obj FL_UNUSED_ARG,
913 SuperSPEC * sp )
914 {
915 int r;
916
917 if ( ( r = ff_read( "%F", &sp->val ) ) < 0 )
918 return ff_err( "Can't read expected object initial value" );
919
920 if ( r == 0 )
921 return ff_err( "\"initial_val\" key with no or invalid value" );
922
923 return 0;
924 }
925
926
927 /***************************************
928 ***************************************/
929
930 static int
ff_read_sp_content(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)931 ff_read_sp_content( FL_OBJECT * obj FL_UNUSED_ARG,
932 SuperSPEC * sp )
933 {
934 char *p;
935
936 if ( ff_read( "%S", &p ) < 0 )
937 return ff_err( "Can't read expected object content" );
938
939 ++sp->nlines;
940 sp->content = fl_realloc( sp->content,
941 ( sp->nlines + 1 ) * sizeof *sp->content );
942 sp->shortcut = fl_realloc( sp->shortcut,
943 ( sp->nlines + 1 ) * sizeof *sp->shortcut );
944 sp->callback = fl_realloc( sp->callback,
945 ( sp->nlines + 1 ) * sizeof *sp->callback );
946 sp->mode = fl_realloc( sp->mode,
947 ( sp->nlines + 1 ) * sizeof *sp->mode );
948 sp->mval = fl_realloc( sp->mval,
949 ( sp->nlines + 1 ) * sizeof *sp->mval );
950
951 sp->content[ sp->nlines ] = p;
952 sp->shortcut[ sp->nlines ] = NULL;
953 sp->callback[ sp->nlines ] = NULL;
954 sp->mode[ sp->nlines ] = 0;
955 sp->mval[ sp->nlines ] = sp->nlines;
956
957 return 0;
958 }
959
960
961 /***************************************
962 ***************************************/
963
964 static int
ff_read_sp_mode(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)965 ff_read_sp_mode( FL_OBJECT * obj FL_UNUSED_ARG,
966 SuperSPEC * sp )
967 {
968 int r;
969 char *p;
970 int i;
971
972 if ( ( r = ff_read( "%v", &p ) ) < 0 )
973 return ff_err( "Can't read expected object mode" );
974
975 if ( r == 0 )
976 return ff_err( "\"mode\" key with no or invalid value" );
977
978 i = get_pupmode_value( p );
979
980 fli_safe_free( p );
981
982 if ( i < 0 )
983 return ff_err( "Invalid value for \"mode\" key" );
984
985 sp->mode[ sp->nlines ] = i;
986
987 return 0;
988 }
989
990
991 /***************************************
992 ***************************************/
993
994 static int
ff_read_sp_shortcut(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)995 ff_read_sp_shortcut( FL_OBJECT * obj FL_UNUSED_ARG,
996 SuperSPEC * sp )
997 {
998 char *p;
999
1000 if ( ff_read( "%s", &p) < 0 )
1001 return ff_err( "Can't read expected object shortcut" );
1002
1003 sp->shortcut[ sp->nlines ] = p;
1004
1005 return 0;
1006 }
1007
1008
1009 /***************************************
1010 ***************************************/
1011
1012 static int
ff_read_sp_callback(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)1013 ff_read_sp_callback( FL_OBJECT * obj FL_UNUSED_ARG,
1014 SuperSPEC * sp )
1015 {
1016 char *p;
1017
1018 if ( ff_read( "%v", &p) < 0 )
1019 return ff_err( "Can't read expected object callback" );
1020
1021 sp->callback[ sp->nlines ] = p;
1022
1023 return 0;
1024 }
1025
1026
1027 /***************************************
1028 ***************************************/
1029
1030 static int
ff_read_sp_id(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)1031 ff_read_sp_id( FL_OBJECT * obj FL_UNUSED_ARG,
1032 SuperSPEC * sp )
1033 {
1034 int r;
1035
1036 if ( ( r = ff_read( "%d", sp->mval + sp->nlines ) ) < 0 )
1037 return ff_err( "Can't read expected object id" );
1038
1039 if ( r == 0 )
1040 return ff_err( "\"id\" key with no or invalid value" );
1041
1042 return 0;
1043 }
1044
1045
1046 /***************************************
1047 ***************************************/
1048
1049 static int
ff_read_sp_file(FL_OBJECT * obj,SuperSPEC * sp FL_UNUSED_ARG)1050 ff_read_sp_file( FL_OBJECT * obj,
1051 SuperSPEC * sp FL_UNUSED_ARG )
1052 {
1053 char *p;
1054 IconInfo *info = get_iconinfo( obj );
1055
1056 if ( ! info )
1057 return ff_err( "Invalid \"file\" attribute for object type found" );
1058
1059 if ( ff_read( "%S", &p ) < 0 )
1060 return ff_err( "Can't read expected object \"file\" attribute" );
1061
1062 if ( strlen( p ) >= sizeof info->filename )
1063 return ff_err( "Filename for \"file\" key too long" );
1064
1065 strcpy( info->filename, p );
1066
1067 fli_safe_free( p );
1068
1069 return 0;
1070 }
1071
1072
1073 /***************************************
1074 ***************************************/
1075
1076 static int
ff_read_sp_focus_file(FL_OBJECT * obj,SuperSPEC * sp FL_UNUSED_ARG)1077 ff_read_sp_focus_file( FL_OBJECT * obj,
1078 SuperSPEC * sp FL_UNUSED_ARG )
1079 {
1080 char *p;
1081 IconInfo *info = get_iconinfo( obj );
1082
1083 if ( ! info )
1084 return ff_err( "Invalid \"focus\" attribute for object type found" );
1085
1086 if ( ff_read( "%S", &p ) < 0 )
1087 return ff_err( "Can't read expected object \"focus\" attribute" );
1088
1089 if ( strlen( p ) >= sizeof info->focus_filename )
1090 return ff_err( "Filename for \"focus_file\" key too long" );
1091
1092 strcpy( info->focus_filename, p );
1093
1094 fli_safe_free( p );
1095
1096 return 0;
1097 }
1098
1099
1100 /***************************************
1101 ***************************************/
1102
1103 static int
ff_read_sp_handler(FL_OBJECT * obj,SuperSPEC * sp FL_UNUSED_ARG)1104 ff_read_sp_handler( FL_OBJECT * obj,
1105 SuperSPEC * sp FL_UNUSED_ARG )
1106 {
1107 int r;
1108 char *p;
1109
1110 if ( ( r = ff_read( "%v", &p ) ) < 0 )
1111 return ff_err( "Can't read expected object handler" );
1112
1113 if ( r == 0 )
1114 return ff_err( "\"handler\" key with no or invalid value" );
1115
1116 obj->c_vdata = p;
1117
1118 return 0;
1119 }
1120
1121
1122 /***************************************
1123 ***************************************/
1124
1125 static int
ff_read_sp_data(FL_OBJECT * obj,SuperSPEC * sp FL_UNUSED_ARG)1126 ff_read_sp_data( FL_OBJECT * obj,
1127 SuperSPEC * sp FL_UNUSED_ARG )
1128 {
1129 char *p;
1130 IconInfo *info = get_iconinfo( obj );
1131
1132 if ( ! info )
1133 return ff_err( "Invalid data structrure for object type found" );
1134
1135 if ( ff_read( "%v", &p ) < 0 )
1136 return ff_err( "Can't read expected object data attribute" );
1137
1138 strcpy( info->data, p );
1139
1140 fli_safe_free( p );
1141
1142 if ( *info->data )
1143 info->use_data = 1;
1144
1145 return 0;
1146 }
1147
1148
1149 /***************************************
1150 ***************************************/
1151
1152 static int
ff_read_sp_focus_data(FL_OBJECT * obj,SuperSPEC * sp FL_UNUSED_ARG)1153 ff_read_sp_focus_data( FL_OBJECT * obj,
1154 SuperSPEC * sp FL_UNUSED_ARG )
1155 {
1156 char *p;
1157 IconInfo *info = get_iconinfo( obj );
1158
1159 if ( ! info )
1160 return ff_err( "Invalid \"focus_data\" attribute for object type "
1161 "found" );
1162
1163 if ( ff_read( "%v", &p ) < 0 )
1164 return ff_err( "Can't read expected object \"focus_data\" attribute" );
1165
1166 strcpy( info->focus_data, p );
1167
1168 fli_safe_free( p );
1169
1170 return 0;
1171 }
1172
1173
1174 /***************************************
1175 ***************************************/
1176
1177 static int
ff_read_sp_fullpath(FL_OBJECT * obj,SuperSPEC * sp FL_UNUSED_ARG)1178 ff_read_sp_fullpath( FL_OBJECT * obj,
1179 SuperSPEC * sp FL_UNUSED_ARG )
1180 {
1181 int r;
1182 IconInfo *info = get_iconinfo( obj );
1183
1184 if ( ! info )
1185 return ff_err( "Invalid \"fullpath\" attribute for object type found" );
1186
1187 if ( ( r = ff_read( "%d", &info->fullpath) ) < 0 )
1188 return ff_err( "Can't read expected object \"fullpath\" attribute" );
1189
1190 if ( r == 0 )
1191 return ff_err( "\"fullpath\" key with no or invalid value" );
1192
1193 return 0;
1194 }
1195
1196
1197 /***************************************
1198 ***************************************/
1199
1200 static int
ff_read_sp_width(FL_OBJECT * obj,SuperSPEC * sp FL_UNUSED_ARG)1201 ff_read_sp_width( FL_OBJECT * obj,
1202 SuperSPEC * sp FL_UNUSED_ARG )
1203 {
1204 char *p;
1205 IconInfo *info = get_iconinfo( obj );
1206
1207 if ( ! info )
1208 return ff_err( "Invalid \"width\" attribute for object type found" );
1209
1210 if ( ff_read( "%v", &p ) < 0 )
1211 return ff_err( "Can't read expected object \"width\" attribute" );
1212
1213 strcpy( info->width, p );
1214
1215 fli_safe_free( p );
1216
1217 return 0;
1218 }
1219
1220
1221 /***************************************
1222 ***************************************/
1223
1224 static int
ff_read_sp_height(FL_OBJECT * obj,SuperSPEC * sp FL_UNUSED_ARG)1225 ff_read_sp_height( FL_OBJECT * obj,
1226 SuperSPEC * sp FL_UNUSED_ARG )
1227 {
1228 char *p;
1229 IconInfo *info = get_iconinfo( obj );
1230
1231 if ( ! info )
1232 return ff_err( "Invalid \"height\" attribute for object type found" );
1233
1234 if ( ff_read( "%v", &p ) < 0 )
1235 return ff_err( "Can't read expected object \"height\" attribute" );
1236
1237 strcpy( info->height, p );
1238
1239 fli_safe_free( p );
1240
1241 return 0;
1242 }
1243
1244
1245 /***************************************
1246 ***************************************/
1247
1248 static int
ff_read_sp_align(FL_OBJECT * obj,SuperSPEC * sp)1249 ff_read_sp_align( FL_OBJECT * obj,
1250 SuperSPEC * sp )
1251 {
1252 int r;
1253 IconInfo *info = get_iconinfo( obj );
1254 int align;
1255
1256 if ( ( r = ff_read( "%a", &align ) ) < 0 )
1257 return ff_err( "Can't read expected object align attribute" );
1258
1259 align &= ~FL_ALIGN_INSIDE;
1260
1261 if ( r == 0 )
1262 return ff_err( "Invalid value for \"align\" attribute" );
1263
1264 if ( info )
1265 info->align = align;
1266 else
1267 sp->align = align;
1268
1269 return 0;
1270 }
1271
1272
1273 /***************************************
1274 ***************************************/
1275
1276 static int
ff_read_sp_struct(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)1277 ff_read_sp_struct( FL_OBJECT * obj FL_UNUSED_ARG,
1278 SuperSPEC * sp )
1279 {
1280 int r;
1281
1282 if ( ( r = ff_read( "%d", &sp->new_menuapi ) ) < 0 )
1283 return ff_err( "Can't read expected object struct attribute" );
1284
1285 if ( r == 0 )
1286 return ff_err( "\"struct\" key with no or invalid value" );
1287
1288 return 0;
1289 }
1290
1291
1292 /***************************************
1293 ***************************************/
1294
1295 static int
ff_read_sp_global(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)1296 ff_read_sp_global( FL_OBJECT * obj FL_UNUSED_ARG,
1297 SuperSPEC * sp )
1298 {
1299 int r;
1300
1301 if ( ( r = ff_read( "%d", &sp->global_scope ) ) < 0 )
1302 return ff_err( "Can't read expected object global attribute" );
1303
1304 if ( r == 0 )
1305 return ff_err( "\"global\" key with no or invalid value" );
1306
1307 return 0;
1308 }
1309
1310
1311 /***************************************
1312 ***************************************/
1313
1314 static int
ff_read_sp_focus(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)1315 ff_read_sp_focus( FL_OBJECT * obj FL_UNUSED_ARG,
1316 SuperSPEC * sp )
1317 {
1318 int r;
1319
1320 if ( ( r = ff_read( "%d", &sp->show_focus ) ) < 0 )
1321 return ff_err( "Can't read expected object focus attribute" );
1322
1323 if ( r == 0 )
1324 return ff_err( "\"focus\" key with no or invalid value" );
1325
1326 return 0;
1327 }
1328
1329
1330 /***************************************
1331 ***************************************/
1332
1333 static int
ff_read_sp_xtics(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)1334 ff_read_sp_xtics( FL_OBJECT * obj FL_UNUSED_ARG,
1335 SuperSPEC * sp )
1336 {
1337 int r;
1338
1339 if ( ( r = ff_read( "%d%d", &sp->xmajor, &sp->xminor ) ) < 0 )
1340 return ff_err( "Can't read expected object xtics values" );
1341
1342 if ( r == 0 )
1343 return ff_err( "\"xtics\" key with no or invalid values" );
1344 else if ( r == 1 )
1345 return ff_err( "\"xtics\" key with only one valid value" );
1346
1347 return 0;
1348 }
1349
1350
1351 /***************************************
1352 ***************************************/
1353
1354 static int
ff_read_sp_ytics(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)1355 ff_read_sp_ytics( FL_OBJECT * obj FL_UNUSED_ARG,
1356 SuperSPEC * sp )
1357 {
1358 int r;
1359
1360 if ( ( r = ff_read( "%d%d", &sp->ymajor, &sp->yminor ) ) < 0 )
1361 return ff_err( "Can't read expected object ytics values" );
1362
1363 if ( r == 0 )
1364 return ff_err( "\"ytics\" key with no or invalid values" );
1365 else if ( r == 1 )
1366 return ff_err( "\"ytics\" key with only one valid value" );
1367
1368 return 0;
1369 }
1370
1371
1372 /***************************************
1373 ***************************************/
1374
1375 static int
ff_read_sp_xscale(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)1376 ff_read_sp_xscale( FL_OBJECT * obj FL_UNUSED_ARG,
1377 SuperSPEC * sp )
1378 {
1379 int r;
1380 char *p;
1381 int xscale;
1382
1383 if ( ( r = ff_read( "%h%f", &p, &sp->xbase ) ) < 0 )
1384 return ff_err( "Can't read expected object xscale values" );
1385
1386 if ( r == 0 )
1387 return ff_err( "\"xscale\" key with no or invalid values" );
1388
1389 xscale = get_scale_value( p );
1390
1391 fli_safe_free( p );
1392
1393 if ( xscale < 0 )
1394 return ff_err( "Invalid value for first value for \"xscale\" key" );
1395
1396 sp->xscale = xscale;
1397
1398 if ( r == 1 )
1399 return ff_err( "\"xscale\" key with only one valid value" );
1400
1401 return 0;
1402 }
1403
1404
1405 /***************************************
1406 ***************************************/
1407
1408 static int
ff_read_sp_yscale(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)1409 ff_read_sp_yscale( FL_OBJECT * obj FL_UNUSED_ARG,
1410 SuperSPEC * sp )
1411 {
1412 int r;
1413 char *p;
1414 int yscale;
1415
1416 if ( ( r = ff_read( "%h%f", &p, &sp->ybase ) ) < 0 )
1417 return ff_err( "Can't read expected object yscale values" );
1418
1419 if ( r == 0 )
1420 return ff_err( "\"yscale\" key with no or invalid values" );
1421
1422 yscale = get_scale_value( p );
1423
1424 fli_safe_free( p );
1425
1426 if ( yscale < 0 )
1427 return ff_err( "Invalid value for first value for \"yscale\" key" );
1428
1429 sp->yscale = yscale;
1430
1431 if ( r == 1 )
1432 return ff_err( "\"yscale\" key with only one valid value" );
1433
1434 return 0;
1435 }
1436
1437
1438 /***************************************
1439 ***************************************/
1440
1441 static int
ff_read_sp_grid(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)1442 ff_read_sp_grid( FL_OBJECT * obj FL_UNUSED_ARG,
1443 SuperSPEC * sp )
1444 {
1445 int r;
1446 char *p1, *p2;
1447 int g;
1448
1449 if ( ( r = ff_read( "%v%v", &p1, &p2) ) < 0 )
1450 return ff_err( "Can't read expected object grid attribute" );
1451
1452 if ( r == 0 )
1453 return ff_err( "\"grid\" key with no or invalid values" );
1454
1455 g = get_grid_value( p1 );
1456
1457 fli_safe_free( p1 );
1458
1459 if ( g < 0 )
1460 return ff_err( "Invalid first value for \"grid\" key" );
1461
1462 sp->xgrid = g;
1463
1464 if ( r != 2 )
1465 return ff_err( "\"grid\" key with only one valid value" );
1466
1467 g = get_grid_value( p2 );
1468
1469 fli_safe_free( p2 );
1470
1471 if ( g < 0 )
1472 return ff_err( "Invalid second value for \"grid\" key" );
1473
1474 sp->ygrid = g;
1475
1476 return 0;
1477 }
1478
1479
1480 /***************************************
1481 ***************************************/
1482
1483 static int
ff_read_sp_gridstyle(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)1484 ff_read_sp_gridstyle( FL_OBJECT * obj FL_UNUSED_ARG,
1485 SuperSPEC * sp )
1486 {
1487 int r;
1488 char *p;
1489 int g;
1490
1491 if ( ( r = ff_read( "%v", &p ) ) < 0 )
1492 return ff_err( "Can't read expected object gridstyle attribute" );
1493
1494 if ( r == 0 )
1495 return ff_err( "\"gridstyle\" key with no or invalid value" );
1496
1497 g = get_linestyle_value( p );
1498
1499 fli_safe_free( p );
1500
1501 if ( g < 0 )
1502 return ff_err( "Invalid value for \"gridstyle\" key" );
1503
1504 sp->grid_linestyle = g;
1505
1506 return 0;
1507 }
1508
1509
1510 /***************************************
1511 ***************************************/
1512
1513 static int
ff_read_sp_markactive(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)1514 ff_read_sp_markactive( FL_OBJECT * obj FL_UNUSED_ARG,
1515 SuperSPEC * sp )
1516 {
1517 int r;
1518
1519 if ( ( r = ff_read( "%d", &sp->mark_active ) ) < 0 )
1520 return ff_err( "Can't read expected object markactive attribute" );
1521
1522 if ( r == 0 )
1523 return ff_err( "\"markactive\" key with no or invalid value" );
1524
1525 return 0;
1526 }
1527
1528
1529 /***************************************
1530 ***************************************/
1531
1532 static int
ff_read_sp_dir(FL_OBJECT * obj FL_UNUSED_ARG,SuperSPEC * sp)1533 ff_read_sp_dir( FL_OBJECT * obj FL_UNUSED_ARG,
1534 SuperSPEC * sp )
1535 {
1536 int r;
1537 char *p;
1538 int dir;
1539
1540 if ( ( r = ff_read( "%v", &p ) ) < 0 )
1541 return ff_err( "Can't read expected object dir attribute" );
1542
1543 if ( r == 0 )
1544 return ff_err( "\"dir\" key with no or invalid value" );
1545
1546 dir = get_direction_value( p );
1547
1548 fli_safe_free( p );
1549
1550 if ( dir < 0 )
1551 return ff_err( "Invalid value for \"dir\" key" );
1552
1553 sp->direction = dir;
1554
1555 return 0;
1556 }
1557
1558
1559 /***************************************
1560 * Duplication of code in fd_file.c since in older versions
1561 * the return setting was considered an object specific
1562 * attribute while now all objects have it
1563 ***************************************/
1564
1565 static int
ff_read_sp_return(FL_OBJECT * obj,SuperSPEC * sp FL_UNUSED_ARG)1566 ff_read_sp_return( FL_OBJECT * obj,
1567 SuperSPEC * sp FL_UNUSED_ARG )
1568 {
1569 int r;
1570 char *return_name;
1571 int ret;
1572
1573 if ( ( r = ff_read( "%s", &return_name ) ) < 0 )
1574 return ff_err( "Can't read expected object return" );
1575
1576 if ( r == 0 )
1577 return ff_err( "\"return\" key with no or invalid value" );
1578
1579 ret = get_how_return_val( return_name );
1580
1581 fli_safe_free( return_name );
1582
1583 if ( ret == -1 )
1584 return ff_err( "Invalid value for \"return\" key" );
1585
1586 fl_set_object_return( obj, ret );
1587
1588 return 0;
1589 }
1590
1591
1592 /***************************************
1593 ***************************************/
1594
1595 typedef int ( * spec_attr_func )( FL_OBJECT *, SuperSPEC * );
1596
1597 typedef struct {
1598 const char * name;
1599 spec_attr_func func;
1600 } spec_attr_handlers;
1601
1602
1603 static spec_attr_handlers attr_array[ ] =
1604 {
1605 { "bounds", ff_read_sp_bounds },
1606 { "precision", ff_read_sp_precision },
1607 { "increment", ff_read_sp_increment },
1608 { "value", ff_read_sp_value },
1609 { "slsize", ff_read_sp_slsize },
1610 { "step", ff_read_sp_step },
1611 { "h_pref", ff_read_sp_h_pref },
1612 { "v_pref", ff_read_sp_v_pref },
1613 { "sstep", ff_read_sp_sstep },
1614 { "lstep", ff_read_sp_lstep },
1615 { "xbounds", ff_read_sp_xbounds },
1616 { "ybounds", ff_read_sp_ybounds },
1617 { "xvalue", ff_read_sp_xvalue },
1618 { "yvalue", ff_read_sp_yvalue },
1619 { "xstep", ff_read_sp_xstep },
1620 { "ystep", ff_read_sp_ystep },
1621 { "angles", ff_read_sp_angles },
1622 { "mbuttons", ff_read_sp_mbuttons },
1623 { "initial_val", ff_read_sp_initial_val },
1624 { "content", ff_read_sp_content },
1625 { "mode", ff_read_sp_mode },
1626 { "shortcut", ff_read_sp_shortcut },
1627 { "callback", ff_read_sp_callback },
1628 { "id", ff_read_sp_id },
1629 { "file", ff_read_sp_file },
1630 { "focus_file", ff_read_sp_focus_file },
1631 { "handler", ff_read_sp_handler },
1632 { "data", ff_read_sp_data },
1633 { "focus_data", ff_read_sp_focus_data },
1634 { "fullpath", ff_read_sp_fullpath },
1635 { "width", ff_read_sp_width },
1636 { "height", ff_read_sp_height },
1637 { "align", ff_read_sp_align },
1638 { "struct", ff_read_sp_struct },
1639 { "global", ff_read_sp_global },
1640 { "focus", ff_read_sp_focus },
1641 { "xtics", ff_read_sp_xtics },
1642 { "ytics", ff_read_sp_ytics },
1643 { "xscale", ff_read_sp_xscale },
1644 { "yscale", ff_read_sp_yscale },
1645 { "grid", ff_read_sp_grid },
1646 { "gridstyle", ff_read_sp_gridstyle },
1647 { "markactive", ff_read_sp_markactive },
1648 { "dir", ff_read_sp_dir },
1649 { "return", ff_read_sp_return }
1650 };
1651
1652
1653 /***************************************
1654 * If we don't know what to do with object specific informations skip them.
1655 * This way we (hopefully) remain compatible with later versions
1656 ***************************************/
1657
1658 static int
skip_spec_info(char * key)1659 skip_spec_info( char * key )
1660 {
1661 char *rest,
1662 *p;
1663 int r;
1664
1665 /* Skip everything up to either the start of the next form or object or
1666 the end of the file */
1667
1668 do
1669 {
1670 fli_safe_free( key );
1671
1672 if ( ff_read( "%s", &rest ) < 0 )
1673 return ff_err( "Failed to read from file" );
1674
1675 fli_safe_free( rest );
1676
1677 if ( ( r = ff_read( "%k", &key ) ) < 0 )
1678 return ff_err( "Failed to read from file" );
1679
1680 } while ( r != 0 && strcmp( key, "Name" ) && strcmp( key, "class" ) );
1681
1682 /* Check if we arrived at the start of a form or class */
1683
1684 if ( ! strcmp( key, "Name" ) )
1685 {
1686 fli_safe_free( key );
1687 return FF_AT_START_OF_FORM;
1688 }
1689 else if ( ! strcmp( key, "class" ) )
1690 {
1691 fli_safe_free( key );
1692 return FF_AT_START_OF_OBJECT;
1693 }
1694
1695 /* Otherwise we now have to look for the name of the main function */
1696
1697 if ( ff_read( "%v", &p ) < 1 )
1698 return ff_err( "Expected main function name, not found here" );
1699 else
1700 {
1701 fli_sstrcpy( main_name, p, MAX_VAR_LEN );
1702 fli_safe_free( p );
1703 }
1704
1705 return FF_AT_END_OF_FILE;
1706 }
1707
1708
1709 /***************************************
1710 * Function for reading in object specific information
1711 ***************************************/
1712
1713 int
load_objclass_spec_info(FL_OBJECT * obj,char * key)1714 load_objclass_spec_info( FL_OBJECT * obj,
1715 char * key )
1716 {
1717 int r;
1718 size_t i;
1719 char *p;
1720 SuperSPEC *sp = get_superspec( obj );
1721
1722 if ( ! find_entry( obj ) )
1723 return skip_spec_info( key );
1724
1725 /* Loop until no more object specific key is found. Note: when we
1726 arrive here the first key already has been read in! */
1727
1728 do
1729 {
1730 for ( i = 0; i < sizeof attr_array / sizeof *attr_array; i++ )
1731 if ( ! strcmp( key, attr_array[ i ].name ) )
1732 {
1733 fli_safe_free( key );
1734
1735 if ( attr_array[ i ].func( obj, sp ) == FF_READ_FAILURE )
1736 return FF_READ_FAILURE;
1737 break;
1738 }
1739
1740 /* An unexpected key has read, give up */
1741
1742 if ( i >= sizeof attr_array / sizeof *attr_array )
1743 {
1744 char *tmp = fl_malloc( strlen( "Read invalid object specific "
1745 "key: " )
1746 + strlen( key ) + 1 );
1747
1748 if ( tmp )
1749 {
1750 sprintf( tmp, "Read invalid object specific key: %s", key );
1751 ff_err( tmp );
1752 fl_free( tmp );
1753 }
1754
1755 fli_safe_free( key );
1756 return FF_READ_FAILURE;
1757 }
1758
1759 fli_safe_free( key );
1760
1761 if ( ( r = ff_read( "%k", &key ) ) < 0 )
1762 return ff_err( "Failed to read from file" );
1763
1764 } while ( r != 0 && strcmp( key, "Name" ) && strcmp( key, "class" ) );
1765
1766 superspec_to_spec( obj );
1767 restore_spec( obj );
1768
1769 /* Check if we should be at the last line of the file and then read
1770 name of main function */
1771
1772 if ( r == 0 )
1773 {
1774 if ( ff_read( "%v", &p ) < 1 )
1775 return ff_err( "Expected main function name, not found here" );
1776 else
1777 {
1778 fli_sstrcpy( main_name, p, MAX_VAR_LEN );
1779 fli_safe_free( p );
1780 }
1781
1782 return FF_AT_END_OF_FILE;
1783 }
1784
1785 /* Otherwise we should be at start of new object... */
1786
1787 if ( ! strcmp( key, "class" ) )
1788 {
1789 fli_safe_free( key );
1790 return FF_AT_START_OF_OBJECT;
1791 }
1792
1793 /* ...or start of new form */
1794
1795 fli_safe_free( key );
1796 return FF_AT_START_OF_FORM;
1797 }
1798
1799
1800 /* Utilities */
1801
1802 /***************************************
1803 ***************************************/
1804
1805 void
set_finput_value(FL_OBJECT * ob,double f,int prec)1806 set_finput_value( FL_OBJECT * ob,
1807 double f,
1808 int prec)
1809 {
1810 char buf[ 64 ];
1811
1812 if ( prec > 20 )
1813 prec = 20;
1814
1815 if ( prec >= 0 )
1816 {
1817 if ( fabs( f ) < 1.0e38 && fabs( f ) > 1.0e-38 )
1818 sprintf( buf, "%.*f", prec, f );
1819 else
1820 sprintf( buf, "%.*g", prec, f );
1821 }
1822 else
1823 sprintf( buf, "%g", f );
1824
1825 fl_set_input( ob, buf );
1826 }
1827
1828
1829 /***************************************
1830 ***************************************/
1831
1832 int
get_checked_float(const char * str,double * r)1833 get_checked_float( const char * str,
1834 double * r )
1835 {
1836 char *eptr;
1837
1838 if ( ! str || ! r || ! *str )
1839 return 0;
1840
1841 *r = strtod( str, &eptr );
1842
1843 return ! *eptr
1844 && ! ( ( *r == HUGE_VAL || *r == -HUGE_VAL ) && errno == ERANGE );
1845 }
1846
1847
1848 /***************************************
1849 ***************************************/
1850
1851 int
get_checked_int(const char * str,int * r)1852 get_checked_int( const char * str,
1853 int * r )
1854 {
1855 char *eptr;
1856
1857 if ( ! str || ! r || ! *str )
1858 return 0;
1859
1860 *r = strtol( str, &eptr, 10 );
1861
1862 return ! *eptr && *r <= INT_MAX && *r >= INT_MIN;
1863 }
1864
1865
1866 /***************************************
1867 ***************************************/
1868
1869 double
get_finput_value(FL_OBJECT * ob)1870 get_finput_value( FL_OBJECT * ob )
1871 {
1872 double f = 0;
1873 const char *s = fl_get_input( ob );
1874
1875 if ( s && *s )
1876 sscanf( s, "%lf", &f );
1877
1878 return f;
1879 }
1880
1881
1882 /* scrollbar preference settings */
1883
1884 #define VN( v ) { v, #v }
1885
1886 static FLI_VN_PAIR scrbpref[ ] =
1887 {
1888 VN( FL_OFF ),
1889 VN( FL_ON ),
1890 VN( FL_AUTO ),
1891 { -1, NULL }
1892 };
1893
1894
1895 /* must be in the same order as the above */
1896
1897
1898 /***************************************
1899 ***************************************/
1900
1901 const char *
get_scrollbar_pref_string(void)1902 get_scrollbar_pref_string( void )
1903 {
1904 return "Off|On|Auto ";
1905 }
1906
1907
1908 /***************************************
1909 ***************************************/
1910
1911 const char *
get_scrollbar_pref_name(int a)1912 get_scrollbar_pref_name( int a )
1913 {
1914 return fli_get_vn_name( scrbpref, a );
1915 }
1916
1917
1918 /***************************************
1919 ***************************************/
1920
1921 int
get_scrollbar_pref_value(const char * s)1922 get_scrollbar_pref_value( const char * s )
1923 {
1924 return fli_get_vn_value( scrbpref, s );
1925 }
1926
1927 /* xyplot scale */
1928
1929 static FLI_VN_PAIR scale_vn[ ] =
1930 {
1931 VN( FL_LINEAR ),
1932 VN( FL_LOG ),
1933 { -1, NULL }
1934 };
1935
1936
1937 /***************************************
1938 ***************************************/
1939
1940 const char *
get_scale_name(int a)1941 get_scale_name( int a )
1942 {
1943 return fli_get_vn_name( scale_vn, a );
1944 }
1945
1946
1947 /***************************************
1948 ***************************************/
1949
1950 int
get_scale_value(const char * s)1951 get_scale_value( const char * s )
1952 {
1953 return fli_get_vn_value( scale_vn, s );
1954 }
1955
1956
1957 /***************************************
1958 ***************************************/
1959
1960 const char *
get_scale_string(void)1961 get_scale_string( void )
1962 {
1963 return "Linear|Log";
1964 }
1965
1966
1967 /* xyplot grid */
1968
1969 static FLI_VN_PAIR grid_vn[ ] =
1970 {
1971 VN( FL_GRID_NONE ),
1972 VN( FL_GRID_MAJOR ),
1973 VN( FL_GRID_MINOR ),
1974 { -1, NULL }
1975 };
1976
1977
1978 /***************************************
1979 ***************************************/
1980
1981 const char *
get_grid_name(int a)1982 get_grid_name( int a )
1983 {
1984 return fli_get_vn_name( grid_vn, a );
1985 }
1986
1987
1988 /***************************************
1989 ***************************************/
1990
1991 int
get_grid_value(const char * s)1992 get_grid_value( const char * s )
1993 {
1994 return fli_get_vn_value( grid_vn, s );
1995 }
1996
1997
1998 /***************************************
1999 ***************************************/
2000
2001 const char *
get_grid_string(void)2002 get_grid_string( void )
2003 {
2004 return "None|Major|Minor";
2005 }
2006
2007
2008 /* Line style string stuff */
2009
2010 static FLI_VN_PAIR linestyle[ ] =
2011 {
2012 VN( FL_SOLID ),
2013 VN( FL_USERDASH ),
2014 VN( FL_USERDOUBLEDASH ),
2015 VN( FL_DOT ),
2016 VN( FL_DOTDASH ),
2017 VN( FL_DASH ),
2018 VN( FL_LONGDASH ),
2019 { -1, NULL }
2020 };
2021
2022
2023 /***************************************
2024 ***************************************/
2025
2026 const char *
get_linestyle_string(void)2027 get_linestyle_string( void )
2028 {
2029 return "Solid|UserDash|DoubleDash|Dot|DotDash|Dash|LongDash";
2030 }
2031
2032
2033 /***************************************
2034 ***************************************/
2035
2036 const char *
get_linestyle_name(int a)2037 get_linestyle_name( int a )
2038 {
2039 return fli_get_vn_name( linestyle, a );
2040 }
2041
2042
2043 /***************************************
2044 ***************************************/
2045
2046 int
get_linestyle_value(const char * s)2047 get_linestyle_value( const char * s )
2048 {
2049 return fli_get_vn_value( linestyle, s );
2050 }
2051
2052
2053 /* popup mode */
2054
2055 static FLI_VN_PAIR pupmode[ ] =
2056 {
2057 VN( FL_PUP_NONE ),
2058 VN( FL_PUP_GRAY ),
2059 VN( FL_PUP_BOX ),
2060 VN( FL_PUP_CHECK ),
2061 VN( FL_PUP_RADIO ),
2062 { -1, NULL }
2063 };
2064
2065
2066 /***************************************
2067 ***************************************/
2068
2069 const char *
get_pupmode_string(void)2070 get_pupmode_string( void )
2071 {
2072 return "PUP_NONE|PUP_GRAY|PUP_BOX|PUP_CHECK|PUP_RADIO";
2073 }
2074
2075
2076 /***************************************
2077 ***************************************/
2078
2079 const char *
get_pupmode_name(int a)2080 get_pupmode_name( int a )
2081 {
2082 return fli_get_vn_name( pupmode, a );
2083 }
2084
2085
2086 /***************************************
2087 ***************************************/
2088
2089 int
get_pupmode_value(const char * s)2090 get_pupmode_value( const char * s )
2091 {
2092 char buf[ 32 ];
2093
2094 strcpy( buf, s );
2095 if ( *buf != 'F' )
2096 strcat( strcpy( buf, "FL_" ), s );
2097 return fli_get_vn_value( pupmode, buf );
2098 }
2099
2100
2101 /*
2102 * Local variables:
2103 * tab-width: 4
2104 * indent-tabs-mode: nil
2105 * End:
2106 */
2107