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_printC.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  *  Generate header/C files
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #include <stdlib.h>
34 #include <string.h>
35 #include <ctype.h>
36 
37 #include "fd_main.h"
38 #include "private/flsnprintf.h"
39 #include "fd_spec.h"
40 #include "sp_menu.h"
41 
42 #ifdef WIN32
43 #include <io.h>
44 #endif
45 
46 
47 /***************************************
48  ***************************************/
49 
50 void
make_backup(const char * s)51 make_backup( const char *s )
52 {
53     char *buf;
54 
55     if ( access( s, R_OK ) )
56     {
57         if ( errno != ENOENT )
58             M_err( "make_backup", "Creating backup file %s.bak failed", s );
59         return;
60     }
61 
62     buf = malloc( strlen( s ) + 5 );
63     sprintf( buf, "%s.bak", s );
64 
65 #ifdef  __EMX__
66     if ( unlink( buf ) )
67     {
68         M_err( "make_backup", "Creating backup file %s failed", buf );
69         free( buf );
70         return;
71     }
72 #endif
73 
74     if ( rename( s, buf ) )
75         M_err( "make_backup", "Creating backup file %s failed %s", buf, strerror( errno ) );
76 
77     free( buf );
78 }
79 
80 
81 /***************************************
82  ***************************************/
83 
84 static char const *
filename_only(char const * filename)85 filename_only( char const * filename )
86 {
87     char const * ptr = strrchr( filename, '/' );
88 
89     if ( ptr )
90         return ptr + 1;
91     return filename;
92 }
93 
94 
95 /***************************************
96  ***************************************/
97 
98 static int
build_fname(char * fname,size_t fname_capacity,char const * filename,char const * ext)99 build_fname( char       * fname,
100              size_t       fname_capacity,
101              char const * filename,
102              char const * ext )
103 {
104     int npc;
105 
106     if ( fdopt.output_dir )
107         npc = fli_snprintf( fname, fname_capacity, "%s%s%s%s",
108                             fdopt.output_dir,
109                             fdopt.output_dir[ strlen( fdopt.output_dir ) - 1 ]
110                                                               != '/' ? "/" : "",
111                            filename_only( filename ), ext );
112     else
113         npc = fli_snprintf( fname, fname_capacity, "%s%s", filename, ext );
114 
115     /* Older libc return -1 if text doesn't, newer ones the total number
116        of chars that would have been written if there would have been
117        enough space */
118 
119     return npc >= 0 && ( size_t ) npc <= fname_capacity;
120 }
121 
122 
123 /***************************************
124  * Note: 'filename' has no extensions
125  ***************************************/
126 
127 int
C_output(const char * filename,FRM * forms,int fnumb)128 C_output( const char * filename,
129           FRM        * forms,
130           int          fnumb )
131 {
132     char fname[ PATH_MAX + 1 ];
133     const char *name_only;
134     int i;
135     FILE *fn;
136     FL_OBJECT *obj;
137     int use_glcanvas = 0;
138 
139     /* Figure out the name of the file without any path */
140 
141     if ( ( name_only = strrchr( filename, '/' ) ) )
142         ++name_only;
143     else
144         name_only = filename;
145 
146     if ( ! build_fname( fname, sizeof fname, filename, ".h" ) )
147     {
148         if ( ! fdopt.conv_only )
149             fl_show_alert( "Can't create header file!",
150                            "Filename is too long:", "", 1 );
151         else
152             M_err( "C_output",
153                    "Can't create header file, filename is too long" );
154         return 0;
155     }
156 
157     make_backup( fname );
158 
159     if ( ! ( fn = fopen( fname, "w" ) ) )
160     {
161         if ( ! fdopt.conv_only )
162             fl_show_alert( "Can't open header file!", fname, "", 1 );
163         else
164             M_err( "C_output", "Can't create open header file '%s'", fname );
165         return 0;
166     }
167 
168     fprintf( fn, "/* Header file generated by fdesign on %s */\n\n"
169                  "#ifndef %s_h_\n"
170                  "#define %s_h_\n\n"
171                  "#include %c%s%c\n",
172              fl_now( ),
173              get_fd_name( forms[ 0 ].fname ),
174              get_fd_name( forms[ 0 ].fname ),
175              xform_header[ 0 ] == '"' ? ' ' : '<',
176              xform_header,
177              xform_header[ 0 ] == '"' ? ' ' : '>' );
178 
179     for ( i = 0; i < fnumb && ! use_glcanvas; i++ )
180     {
181         obj = forms[ i ].form->first;
182         while ( ( obj = obj->next ) != NULL )
183             if ( obj->objclass == FL_GLCANVAS )
184             {
185                 use_glcanvas = 1;
186                 break;
187             }
188     }
189 
190     if ( use_glcanvas )
191         fprintf( fn, "#include <%s>\n", glcanvas_header );
192 
193     fprintf( fn, "\n/* Callbacks, globals and object handlers */\n\n" );
194 
195     for ( i = 0; i < fnumb; i++ )
196         print_callbacks_and_globals( fn, forms[ i ].form, 0 );
197 
198     fprintf( fn, "\n/* Forms and Objects */\n\n" );
199     for ( i = 0; i < fnumb; i++ )
200         print_header( fn, forms[ i ].form, forms[ i ].fname );
201 
202     if ( fdopt.altformat )
203         fprintf( fn, "\n/* Creation Routine */\n\n"
204                      "void %s( void );\n", main_name );
205 
206     fprintf( fn, "\n#endif /* %s_h_ */\n", get_fd_name( forms[ 0 ].fname ) );
207     fclose( fn );
208 
209     /* Make the .c file. */
210 
211     if ( ! build_fname( fname, sizeof fname, filename, ".c" ) )
212     {
213         if ( ! fdopt.conv_only )
214             fl_show_alert( "Can't create C file!",
215                            "Filename is too long.", "", 1 );
216         else
217             M_err( "C_output", "Can't create C file, filename is too long" );
218         return 0;
219     }
220 
221     make_backup( fname );
222 
223     if ( ! ( fn = fopen( fname, "w" ) ) )
224     {
225         if ( ! fdopt.conv_only )
226             fl_show_alert( "Can't open C file!", fname, "", 1 );
227         else
228             M_err( "C_output", "Can't open C file '%s'", fname );
229         return 0;
230     }
231 
232     fprintf( fn, "/* Form definition file generated by fdesign on %s */\n\n"
233                  "#include <stdlib.h>\n"
234                  "#include \"%s.h\"\n\n", fl_now( ), name_only );
235 
236     for ( i = 0; i < fnumb; i++ )
237         print_form( fn, forms[ i ].form, forms[ i ].fname );
238 
239     if ( fdopt.altformat )
240     {
241         fprintf( fn, "void %s( void )\n{\n", main_name );
242         for ( i = 0; i < fnumb; i++ )
243             fprintf( fn, "    create_form_%s( );\n", forms[ i ].fname );
244         fprintf( fn, "}\n" );
245     }
246 
247     fclose( fn );
248 
249     /* Check if we need to output a template for the main program */
250 
251     if ( fdopt.emit_main )
252     {
253         if ( ! build_fname( fname, sizeof fname, filename, "_main.c" ) )
254         {
255             if ( ! fdopt.conv_only )
256                 fl_show_alert( "Can't create C file for main() function!",
257                                "Filename is too long:", "", 1 );
258             else
259                 M_err( "C_output", "Can't create C file for main() function, "
260                        "filename is too long" );
261             reset_dupinfo_cache( );
262             return 0;
263         }
264 
265         make_backup( fname );
266 
267         if ( ! ( fn = fopen( fname, "w" ) ) )
268         {
269             if ( ! fdopt.conv_only )
270                 fl_show_alert( "Can't open file for main() function!",
271                                "", "", 1 );
272             else
273                 M_err( "C_output", "Can't open file for main() function!" );
274             reset_dupinfo_cache( );
275             return 0;
276         }
277 
278         /* Print out the include for the header file and then all the code */
279 
280         fprintf( fn, "#include \"%s.h\"\n\n", name_only );
281         output_main( fn, forms, fnumb );
282 
283         fclose( fn );
284     }
285 
286     /* Output callback stubs */
287 
288     if ( fdopt.emit_cb )
289     {
290         if ( ! build_fname( fname, sizeof fname, filename, "_cb.c" ) )
291         {
292             if ( ! fdopt.conv_only )
293                 fl_show_alert( "Can't create C file for callbacks!",
294                                "Filename is too long:", "", 1 );
295             else
296                 M_err( "C_output", "Can't create C file for callbacks, "
297                        "filename is too long" );
298             reset_dupinfo_cache( );
299             return 0;
300         }
301 
302         make_backup( fname );
303         if ( ! ( fn = fopen( fname, "w" ) ) )
304         {
305             if ( ! fdopt.conv_only )
306                 fl_show_alert( "Can't open C file for callbacks!", fname,
307                                "", 1 );
308             else
309                 M_err( "C_output",
310                        "Can't open C file for callbacks '%s'", fname );
311             reset_dupinfo_cache( );
312             return 0;
313         }
314 
315         /* Print out the include for the header file and then all the code */
316 
317         fprintf( fn, "#include \"%s.h\"\n\n", name_only );
318         output_callbacks( fn, forms, fnumb );
319 
320         fclose( fn );
321     }
322 
323     reset_dupinfo_cache( );
324     return 1;
325 }
326 
327 
328 
329 /* Some attributes query routines */
330 
331 #define VN( v )    { v, #v, NULL, NULL }
332 #define PVN( v )   v, #v
333 
334 
335 VN_pair vn_btype[ ] =
336 {
337     { PVN( FL_NO_BOX ),                "No box%r1",            "Nn#n" },
338     { PVN( FL_UP_BOX ),                "Up box%r1",            "Uu#u" },
339     { PVN( FL_DOWN_BOX ),              "Down box%r1",          "Dd#d" },
340     { PVN( FL_BORDER_BOX ),            "Border box%r1",        "Bb#b" },
341     { PVN( FL_SHADOW_BOX ),            "Shadow box%r1",        "Ss#s" },
342     { PVN( FL_FRAME_BOX ),             "Frame box%r1",         "Ff#f" },
343     { PVN( FL_ROUNDED_BOX ),           "Rounded box%r1",       "Rr#r" },
344     { PVN( FL_EMBOSSED_BOX ),          "Embossed box%r1",      "Ee#e" },
345     { PVN( FL_FLAT_BOX ),              "Flat box%r1",          "Ff#f" },
346     { PVN( FL_RFLAT_BOX ),             "Rflat box%r1",         "lL#l" },
347     { PVN( FL_RSHADOW_BOX ),           "Rshadow box%r1",       "wW#w" },
348     { PVN( FL_OVAL_BOX ),              "Oval box%r1",          "Oo#o" },
349     { PVN( FL_ROUNDED3D_UPBOX ),       "rounded3d upbox%r1",   "nN#n" },
350     { PVN( FL_ROUNDED3D_DOWNBOX ),     "rounded3d downbox%r1", "oO#o" },
351     { PVN( FL_OVAL3D_UPBOX ),          "Oval3d upbox%r1",      "vV#v" },
352     { PVN( FL_OVAL3D_DOWNBOX ),        "Oval3d downbox%r1",    "lL#l" },
353     { PVN( FL_OVAL3D_FRAMEBOX ),       "Oval3d framebox%r1",   "eE#e" },
354     { PVN( FL_OVAL3D_EMBOSSEDBOX ),    "Oval3d embossed%r1",   "eE#e" },
355 #if 0
356     { PVN( FL_TOPTAB_UPBOX ),          "toptab%r1",            "tT#t" },
357     { PVN( FL_SELECTED_TOPTAB_UPBOX ), "selected toptab%r1",   "sS#s" },
358 #endif
359     { PVN( -1 ),                       NULL,                   NULL   }
360 };
361 
362 VN_pair vn_align[ ] =
363 {
364     VN( FL_ALIGN_TOP          ),
365     VN( FL_ALIGN_BOTTOM       ),
366     VN( FL_ALIGN_LEFT         ),
367     VN( FL_ALIGN_RIGHT        ),
368     VN( FL_ALIGN_CENTER       ),
369     VN( FL_ALIGN_RIGHT_TOP    ),
370     VN( FL_ALIGN_LEFT_TOP     ),
371     VN( FL_ALIGN_RIGHT_BOTTOM ),
372     VN( FL_ALIGN_LEFT_BOTTOM  ),
373     VN( FL_ALIGN_TOP_RIGHT    ),    /* need them for backward compatibility */
374     VN( FL_ALIGN_TOP_LEFT     ),
375     VN( FL_ALIGN_BOTTOM_RIGHT ),
376     VN( FL_ALIGN_BOTTOM_LEFT  ),
377     { -1, NULL, NULL, NULL    }
378 };
379 
380 static VN_pair vn_lsize[ ] =
381 {
382     VN( FL_DEFAULT_SIZE ),
383     VN( FL_TINY_SIZE    ),
384     VN( FL_SMALL_SIZE   ),
385     VN( FL_NORMAL_SIZE  ),
386     VN( FL_MEDIUM_SIZE  ),
387     VN( FL_LARGE_SIZE   ),
388     VN( FL_HUGE_SIZE    ),
389 
390     VN( FL_DEFAULT_FONT ),
391     VN( FL_TINY_FONT    ),
392     VN( FL_SMALL_FONT   ),
393     VN( FL_NORMAL_FONT  ),
394     VN( FL_MEDIUM_FONT  ),
395     VN( FL_LARGE_FONT   ),
396     VN( FL_HUGE_FONT    ),
397     { FL_SMALL_FONT,  "FL_NORMAL_FONT1", NULL, NULL },
398     { FL_NORMAL_FONT, "FL_NORMAL_FONT2", NULL, NULL },
399     { -1, NULL, NULL, NULL    }
400 };
401 
402 static VN_pair vn_lstyle[ ] =
403 {
404     VN( FL_NORMAL_STYLE ),
405     VN( FL_BOLD_STYLE ),
406     VN( FL_ITALIC_STYLE ),
407     VN( FL_BOLDITALIC_STYLE ),
408     VN( FL_FIXED_STYLE ),
409     VN( FL_FIXEDBOLD_STYLE ),
410     VN( FL_FIXEDITALIC_STYLE ),
411     VN( FL_FIXEDBOLDITALIC_STYLE ),
412     VN( FL_TIMES_STYLE ),
413     VN( FL_TIMESBOLD_STYLE ),
414     VN( FL_TIMESITALIC_STYLE ),
415     VN( FL_TIMESBOLDITALIC_STYLE ),
416     VN( FL_SHADOW_STYLE ),
417     VN( FL_ENGRAVED_STYLE ),
418     VN( FL_EMBOSSED_STYLE ),
419     { -1, NULL, NULL, NULL    }
420 };
421 
422 VN_pair vn_gravity[] =
423 {
424     VN( FL_NoGravity ),
425     VN( FL_NorthWest ),
426     VN( FL_North ),
427     VN( FL_NorthEast ),
428     VN( FL_West ),
429 
430     VN( FL_East ),
431     VN( FL_South ),
432     VN( FL_SouthEast ),
433     VN( FL_SouthWest ),
434 
435     VN( FL_ForgetGravity ),
436     VN( ForgetGravity ),
437     VN( NorthWestGravity ),
438     VN( NorthGravity ),
439     VN( NorthEastGravity ),
440     VN( WestGravity ),
441 
442     VN( EastGravity ),
443     VN( SouthGravity ),
444     VN( SouthEastGravity ),
445     VN( SouthWestGravity ),
446 
447     { -1, NULL, NULL, NULL    }
448 };
449 
450 VN_pair vn_resize[ ] =
451 {
452     VN( FL_RESIZE_NONE ),
453     VN( FL_RESIZE_X ),
454     VN( FL_RESIZE_Y ),
455     VN( FL_RESIZE_ALL ),
456     { -1, NULL, NULL, NULL }
457 };
458 
459 static VN_pair vn_unit[ ] =
460 {
461     VN( FL_COORD_PIXEL ),
462     VN( FL_COORD_MM ),
463     VN( FL_COORD_centiMM ),
464     VN( FL_COORD_POINT ),
465     VN( FL_COORD_centiPOINT ),
466     { FL_COORD_PIXEL,      "pixel",  NULL, NULL },
467     { FL_COORD_MM,         "mm",     NULL, NULL },
468     { FL_COORD_POINT,      "point",  NULL, NULL },
469     { FL_COORD_centiPOINT, "cp",     NULL, NULL },
470     { FL_COORD_centiMM,    "cmm",    NULL, NULL },
471     { FL_COORD_centiPOINT, "cpoint", NULL, NULL },
472     { -1,                  NULL,     NULL, NULL }
473 };
474 
475 
476 /***************************************
477  ***************************************/
478 
479 int
get_vn_val(VN_pair * vn,const char * name)480 get_vn_val( VN_pair *    vn,
481             const char * name )
482 {
483     long val;
484     char *ep;
485 
486     for ( ; vn->name; vn++ )
487         if ( strcmp( name, vn->name ) == 0 )
488             return vn->val;
489 
490     val = strtol( name, &ep, 10 );
491 
492     if ( ep != name && ! *ep && val >= INT_MIN && val <= INT_MAX )
493         return val;
494 
495     return -1;
496 }
497 
498 
499 /***************************************
500  ***************************************/
501 
502 char *
get_vn_name(VN_pair * vn,int val)503 get_vn_name( VN_pair * vn,
504              int       val )
505 {
506     static char buf[ MAX_TYPE_NAME_LEN ];
507 
508     for ( ; vn->name; vn++ )
509     if ( vn->val == val )
510         return vn->name;
511 
512     sprintf( buf, "%d", val );
513     return buf;
514 }
515 
516 
517 static void output_object( FILE * fn, FL_OBJECT * obj, int );
518 static void pre_form_output( FILE * fn );
519 static void post_form_output( FILE * fn );
520 
521 
522 /***************************************
523  ***************************************/
524 
525 static void
emit_attrib(FILE * fp,int a,VN_pair * vn,const char * aname)526 emit_attrib( FILE *       fp,
527              int          a,
528              VN_pair    * vn,
529              const char * aname )
530 {
531     const char *s;
532 
533     if ( vn == vn_align )
534         s = align_name( a, 1 );
535     else
536         s = get_vn_name( vn, a );
537 
538     fprintf( fp, "    %s( obj, %s );\n", aname, s );
539 }
540 
541 
542 /***************************************
543  ***************************************/
544 
545 static char *
pure_style_name(int val)546 pure_style_name( int val )
547 {
548     VN_pair *vn = vn_lstyle;
549     static char buf[ 64 ];
550 
551     for ( ; vn->name && vn->val != val; vn++ )
552         /* empty */ ;
553 
554     if ( vn->val == val )
555         return vn->name;
556     else
557     {
558         sprintf( buf, "%d", val );
559         return buf;
560     }
561 }
562 
563 
564 /***************************************
565  ***************************************/
566 
567 static int
pure_style_val(const char * cc)568 pure_style_val( const char * cc )
569 {
570     VN_pair *vn = vn_lstyle;
571 
572     for ( ; vn->name && strcmp( cc, vn->name ); vn++ )
573         /* empty */;
574     return ( vn->name && ! strcmp( cc, vn->name ) ) ? vn->val : atoi( cc );
575 }
576 
577 
578 /***************************************
579  ***************************************/
580 
581 char *
style_name(int style)582 style_name( int style )
583 {
584     static char buf[ 64 ];
585     int lstyle = style % FL_SHADOW_STYLE;
586     int spstyle = ( style / FL_SHADOW_STYLE ) * FL_SHADOW_STYLE;
587 
588     strcpy( buf, pure_style_name( lstyle ) );
589     if ( spstyle )
590         strcat( strcat( buf, " + " ), pure_style_name( spstyle ) );
591     return buf;
592 }
593 
594 
595 /***************************************
596  ***************************************/
597 
598 int
style_val(const char * cc)599 style_val( const char * cc )
600 {
601     char lstyle[ MAX_TYPE_NAME_LEN ],
602          spstyle[ MAX_TYPE_NAME_LEN ],
603          *p;
604 
605     fli_sstrcpy( lstyle, cc, sizeof lstyle );
606     *spstyle = '\0';
607     if ( ( p = strchr( lstyle, '|' ) ) || ( p = strchr( lstyle, '+' ) ) )
608     {
609         strcpy( spstyle, p + 1 );
610         *p = 0;
611     }
612 
613     return pure_style_val( lstyle ) + pure_style_val( spstyle );
614 }
615 
616 
617 /***************************************
618  ***************************************/
619 
620 char *
lsize_name(int val)621 lsize_name( int val )
622 {
623     return get_vn_name( vn_lsize, val );
624 }
625 
626 
627 /***************************************
628  ***************************************/
629 
630 int
lsize_val(const char * cc)631 lsize_val( const char * cc )
632 {
633     return get_vn_val( vn_lsize, cc );
634 }
635 
636 
637 /***************************************
638  ***************************************/
639 
640 char *
gravity_name(int val)641 gravity_name( int val )
642 {
643     return get_vn_name( vn_gravity, val );
644 }
645 
646 
647 /***************************************
648  ***************************************/
649 
650 int
gravity_val(const char * cc)651 gravity_val( const char * cc )
652 {
653     return get_vn_val( vn_gravity, cc );
654 }
655 
656 
657 /***************************************
658  ***************************************/
659 
660 char *
resize_name(int val)661 resize_name( int val )
662 {
663     return get_vn_name( vn_resize, val );
664 }
665 
666 
667 /***************************************
668  ***************************************/
669 
670 int
resize_val(const char * cc)671 resize_val( const char * cc )
672 {
673     return get_vn_val( vn_resize, cc );
674 }
675 
676 
677 /***************************************
678  ***************************************/
679 
680 const char *
align_name(int val,int with_spaces)681 align_name( int val,
682             int with_spaces )
683 {
684     static char buf[ 128 ];
685 
686     strcpy( buf, get_vn_name( vn_align, fl_to_outside_lalign( val ) ) );
687     if ( fl_is_inside_lalign( val ) && ! fl_is_center_lalign( val ) )
688     {
689         strcat( buf, with_spaces ? " | " : "|" );
690         strcat( buf, "FL_ALIGN_INSIDE" );
691     }
692 
693     return buf;
694 }
695 
696 
697 /***************************************
698  ***************************************/
699 
700 int
align_val(const char * cc)701 align_val( const char * cc )
702 {
703     char s[ MAX_TYPE_NAME_LEN ],
704          *p;
705     int val;
706 
707     fli_sstrcpy( s, cc, sizeof s );
708     if ( ( p = strchr( s, '|' ) ) )
709     {
710         *p = '\0';
711         while ( isspace( ( unsigned char ) *--p  ) )
712             *p = '\0';
713     }
714     val = get_vn_val( vn_align, s );
715 
716     return p ? fl_to_inside_lalign( val ) : val;
717 }
718 
719 
720 /***************************************
721  ***************************************/
722 
723 char *
boxtype_name(int val)724 boxtype_name( int val )
725 {
726     return get_vn_name( vn_btype, val );
727 }
728 
729 
730 /***************************************
731  ***************************************/
732 
733 int
boxtype_val(const char * cc)734 boxtype_val( const char * cc )
735 {
736     return get_vn_val( vn_btype, cc );
737 }
738 
739 
740 /***************************************
741  ***************************************/
742 
743 char *
unit_name(int val)744 unit_name( int val )
745 {
746     return get_vn_name( vn_unit, val );
747 }
748 
749 
750 /***************************************
751  ***************************************/
752 
753 int
unit_val(const char * s)754 unit_val( const char * s )
755 {
756     return get_vn_val( vn_unit, s );
757 }
758 
759 
760 /*** End of attributes query routines ***/
761 
762 /*------------- Keeping track of array names. -------------------*/
763 
764 #define MAXARNAME   100
765 
766 static char *arnames[ MAXARNAME ];
767 static unsigned long arsizes[ MAXARNAME ];
768 static size_t anumb = 0;
769 
770 
771 /***************************************
772  * Initializes the aray names.
773  ***************************************/
774 
775 static void
init_array_names(void)776 init_array_names( void )
777 {
778     anumb = 0;
779 }
780 
781 
782 /***************************************
783  * Checks whether an object name is an array name and remembers it
784  ***************************************/
785 
786 static int
check_array_name(char * aname)787 check_array_name( char * aname )
788 {
789     char tmpstr[ MAX_VAR_LEN ];
790     char *p, *ep;
791     unsigned long ind;
792     size_t i;
793 
794     if ( ! ( p = strchr( aname, '[' ) ) )
795         return FL_FALSE;
796 
797     strcpy( tmpstr, aname );
798     p = tmpstr + ( p - aname );
799 
800     ind = strtoul( p + 1, &ep, 10 );
801     if ( ep == p + 1 )
802         ind = 0;
803 
804     *p = 0;
805 
806     for ( i = 0; i < anumb; i++ )
807         if ( strcmp( arnames[ i ], tmpstr ) == 0 )
808         {
809             if ( ind + 1 > arsizes[ i ] )
810                 arsizes[ i ] = ind + 1;
811             return FL_TRUE;
812         }
813 
814     if ( anumb == MAXARNAME )
815         return FL_FALSE;
816 
817     arnames[ anumb ] = malloc( MAX_VAR_LEN );
818     strcpy( arnames[ anumb ], tmpstr);
819     arsizes[ anumb++ ] = ind + 1;
820     return FL_TRUE;
821 }
822 
823 
824 /***************************************
825  ***************************************/
826 
827 static int
are_there_array_names(void)828 are_there_array_names( void )
829 {
830     return anumb > 0;
831 }
832 
833 
834 /***************************************
835  * Prints the array names of the file.
836  ***************************************/
837 
838 static void
print_array_names(FILE * fn,int newf)839 print_array_names( FILE * fn,
840                    int    newf )
841 {
842     size_t i;
843 
844     for ( i = 0; i < anumb; i++ )
845         if ( ! newf )
846         {
847             fprintf( fn, "    *%s[ %lu ]", arnames[ i ], arsizes[ i ] );
848             if ( i < anumb - 1 )
849                 fprintf( fn, ",\n" );
850         }
851         else
852             fprintf( fn, "    FL_OBJECT * %s[ %lu ];\n",
853                      arnames[ i ], arsizes[ i ] );
854 }
855 
856 
857 /*----------------------- Printing the C-code --------------------*/
858 
859 
860 /***************************************
861  * Prints the form description in C-code. Note that no matter what
862  * the internal coordinate system is, externally we always have
863  * positive y pointing upward from the lower-left corner of the
864  * screen
865  ***************************************/
866 
867 const char *
get_fd_name(const char * form_name)868 get_fd_name( const char * form_name )
869 {
870     static char fdtname[ MAX_VAR_LEN ];
871 
872     sprintf( fdtname, "FD_%s", form_name );
873     return fdtname;
874 }
875 
876 
877 /***************************************
878  ***************************************/
879 
880 double
get_conversion_factor(void)881 get_conversion_factor( void )
882 {
883     double sc = 1.0;
884 
885     if ( fdopt.unit == FL_COORD_POINT )
886         sc = 72.00 / fl_dpi;
887     else if ( fdopt.unit == FL_COORD_MM )
888         sc = 25.40 / fl_dpi;
889     else if ( fdopt.unit == FL_COORD_centiPOINT )
890         sc = 7200.00 / fl_dpi;
891     else if ( fdopt.unit == FL_COORD_centiMM )
892         sc = 2540.00 / fl_dpi;
893 
894     return sc;
895 }
896 
897 
898 /***************************************
899  ***************************************/
900 
901 int
convert_u(FL_Coord l)902 convert_u( FL_Coord l )
903 {
904     return FL_nint( get_conversion_factor( ) * l );
905 }
906 
907 
908 /*
909  * emit fl_set_xxxx_shortcut instead of fl_set_object_shortcut
910  */
911 
912 static VN_pair scclass[ ] =
913 {
914     { FL_BUTTON,       "button", 0, 0 },
915     { FL_LIGHTBUTTON,  "button", 0, 0 },
916     { FL_ROUNDBUTTON,  "button", 0, 0 },
917     { FL_CHECKBUTTON,  "button", 0, 0 },
918     { FL_BITMAPBUTTON, "button", 0, 0 },
919     { FL_PIXMAPBUTTON, "button", 0, 0 },
920     { FL_INPUT,        "input",  0, 0 },
921     { -1,              NULL,     0, 0 }   /* sentinel */
922 };
923 
924 
925 /***************************************
926  ***************************************/
927 
928 static const char *
supported_shortcut(int objclass)929 supported_shortcut( int objclass )
930 {
931     VN_pair *vn = scclass;
932 
933     for ( ; vn->val >= 0; vn++ )
934         if ( vn->val == objclass )
935             return vn->name;
936     return "object";
937 }
938 
939 
940 /***************************************
941  * Generate the C file for the forms we've defined. Header is generated
942  * elsewhere. All default attributes are omitted.
943  ***************************************/
944 
945 static void
print_form_newformat(FILE * fn,FL_FORM * form,const char * fname)946 print_form_newformat( FILE       * fn,
947                       FL_FORM    * form,
948                       const char * fname )
949 {
950     FL_OBJECT *obj;
951     char fdtname[ MAX_VAR_LEN ],
952          fdvname[ MAX_VAR_LEN ];
953 
954     strcpy( fdtname, get_fd_name( fname ) );
955     strcpy( fdvname, "fdui" );
956 
957     /* Check if object specific stuff wants to write anything */
958 
959     for ( obj = form->first; obj; obj = obj->next )
960         emit_objclass_spec_header( fn, obj );
961 
962     fprintf( fn, "\n/***************************************\n"
963                  " ***************************************/\n\n" );
964 
965     fprintf( fn, "%s *\ncreate_form_%s( void )\n{\n    FL_OBJECT *obj;\n",
966              fdtname, fname );
967 
968     /* Note: we output code that casts the return value of fl_malloc()
969        in order to make the it acceptable for C++ compilers */
970 
971     fprintf( fn, "    %s *%s = ( %s * ) fl_malloc( sizeof *%s );\n\n",
972              fdtname, fdvname, fdtname, fdvname );
973 
974     /* Take care of unit, borderwidth etc. that affect the entire form */
975 
976     pre_form_output( fn );
977 
978     fprintf( fn, "    %s->vdata = %s->cdata = NULL;\n"
979                  "    %s->ldata = 0;\n\n", fdvname, fdvname, fdvname );
980 
981     fprintf( fn, "    %s->%s = fl_bgn_form( FL_NO_BOX, %d, %d );\n",
982              fdvname, fname, convert_u( form->w ), convert_u( form->h ) );
983 
984     /* Don't output the first object, it's a box only used by fdesign */
985 
986     if ( form->first )
987         for ( obj = form->first->next; obj; obj = obj->next )
988             output_object( fn, obj, 0 );
989 
990     fprintf( fn, "\n    fl_end_form( );\n\n");
991 
992     if ( fdopt.compensate )
993         fprintf( fn, "    fl_adjust_form_size( %s->%s );\n", fdvname, fname );
994 
995     fprintf( fn, "    %s->%s->%s = %s;\n", fdvname, fname, fdvname, fdvname );
996 
997     /* Restore */
998 
999     post_form_output( fn );
1000 
1001     fprintf( fn, "\n    return %s;\n}\n", fdvname );
1002 }
1003 
1004 
1005 /***************************************
1006  * Output C files for the forms defined, but slightly different from
1007  * the earlier routines. Activated by -altformat on the command line
1008  ***************************************/
1009 
1010 static void
print_form_altformat(FILE * fn,FL_FORM * form,const char * fname)1011 print_form_altformat( FILE       * fn,
1012                       FL_FORM    * form,
1013                       const char * fname )
1014 {
1015     FL_OBJECT *obj;
1016     char name[ MAX_VAR_LEN ];
1017     int first = 1;
1018 
1019     /* Print the form declaration */
1020 
1021     fprintf( fn, "FL_FORM *%s;\n\n", fname );
1022 
1023     /* Print the object declarations */
1024 
1025     init_array_names( );
1026     obj = form->first;
1027 
1028     while ( ( obj = obj->next ) != NULL )
1029     {
1030         get_object_name( obj, name, NULL, NULL );
1031         if ( *name )
1032         {
1033             if ( ! check_array_name( name ) )
1034             {
1035                 fprintf( fn, first ? "FL_OBJECT\n" : ",\n" );
1036                 first = 0;
1037                 fprintf( fn, "        *%s", name );
1038             }
1039         }
1040     }
1041 
1042     if ( are_there_array_names( ) )
1043     {
1044         fprintf( fn, first ? "FL_OBJECT\n" : ",\n");
1045         first = 0;
1046         print_array_names( fn, 0 );
1047     }
1048 
1049     fprintf( fn, first ? "\n" : ";\n\n" );
1050 
1051     /* Check if object specific stuff wants to write anything */
1052 
1053     for ( obj = form->first; obj; obj = obj->next )
1054         emit_objclass_spec_header( fn, obj );
1055 
1056     /* Print the defining procedure */
1057 
1058     fprintf( fn, "\n\n/***************************************\n"
1059                  " ***************************************/\n\n" );
1060 
1061     fprintf( fn, "void\ncreate_form_%s( void )\n{\n    FL_OBJECT *obj;\n\n",
1062              fname );
1063 
1064     pre_form_output( fn );
1065 
1066     fprintf( fn, "    if ( %s )\n"
1067                  "        return;\n\n", fname );
1068     fprintf( fn, "    %s = fl_bgn_form( FL_NO_BOX, %d, %d );\n",
1069              fname, convert_u( form->w ), convert_u( form->h ) );
1070 
1071     for ( obj = form->first; obj; obj = obj->next )
1072         output_object( fn, obj, 1 );
1073 
1074     fprintf( fn, "    fl_end_form( );\n" );
1075     if ( fdopt.compensate )
1076         fprintf( fn, "    fl_adjust_form_size( %s );\n", fname );
1077 
1078     post_form_output( fn );
1079 
1080     fprintf( fn, "\n}\n\n\n/*---------------------------------------*/\n\n" );
1081 }
1082 
1083 
1084 /***************************************
1085  * This is the routine called the output rotuine in fd_forms.c
1086  ***************************************/
1087 
1088 void
print_form(FILE * fn,FL_FORM * form,const char * fname)1089 print_form( FILE       * fn,
1090             FL_FORM    * form,
1091             const char * fname )
1092 {
1093     ( ! fdopt.altformat ? print_form_newformat : print_form_altformat )
1094         ( fn, form, fname );
1095 }
1096 
1097 
1098 /***************************************
1099  * Check if a callback stub has already been emitted so we can suppress
1100  * duplicates as callbacks can be bound to multiple objects.
1101  * Potential problems: this check is only for a particular form,
1102  * if a callback is bound to multiple objects across many forms,
1103  * the callback will be output at least once per form.
1104  ***************************************/
1105 
1106 static int
already_emitted(FL_OBJECT * first,FL_OBJECT * curobj,const char * cb)1107 already_emitted( FL_OBJECT  * first,
1108                  FL_OBJECT  * curobj,
1109                  const char * cb )
1110 {
1111     char cbname[ MAX_VAR_LEN ];
1112     FL_OBJECT *ob = first;
1113 
1114     for ( ob = first->next; ob && ob != curobj; ob = ob->next )
1115     {
1116         get_object_name( ob, NULL, cbname, NULL );
1117         if ( *cbname && strcmp( cbname, cb ) == 0 )
1118             return 1;
1119     }
1120 
1121     return 0;
1122 }
1123 
1124 
1125 #define MAXFREEOBJ 16
1126 
1127 
1128 /***************************************
1129  ***************************************/
1130 
1131 static char *
get_free_handle(FL_OBJECT * ob,const char * name)1132 get_free_handle( FL_OBJECT  * ob,
1133                  const char * name )
1134 {
1135     static int n;
1136     static char buf[ 1024 ];
1137     static FL_OBJECT *freeobj[ MAXFREEOBJ ];
1138 
1139     if ( ob->c_vdata )
1140         strcpy( buf, ob->c_vdata );
1141     else if ( *name )
1142         sprintf( buf, "freeobj_%s_handler", name );
1143     else if ( *ob->label )
1144         sprintf( buf, "freeobj_%s_handler", ob->label );
1145     else
1146     {
1147         int i,
1148             k;
1149 
1150         for ( k = -1, i = 0; i < MAXFREEOBJ && k < 0; i++ )
1151             if ( freeobj[ i ] == ob )
1152                 k = i;
1153 
1154         if ( k < 0 )
1155         {
1156             k = ++n;
1157             freeobj[ k ] = ob;
1158         }
1159 
1160         sprintf( buf, "freeobj%d_handler", k );
1161     }
1162 
1163     return buf;
1164 }
1165 
1166 
1167 /***************************************
1168  * Prints the callback routines used in form
1169  ***************************************/
1170 
1171 void
print_callbacks_and_globals(FILE * fn,FL_FORM * form,int code)1172 print_callbacks_and_globals( FILE    * fn,
1173                              FL_FORM * form,
1174                              int       code )
1175 {
1176     FL_OBJECT *obj;
1177     char name[ MAX_VAR_LEN ],
1178          cbname[ MAX_VAR_LEN ];
1179 
1180     obj = form->first;
1181 
1182     while ( ( obj = obj->next ) != NULL )
1183     {
1184         get_object_name( obj, name, cbname, NULL );
1185 
1186         if ( obj->objclass == FL_FREE )
1187         {
1188             if ( ! code )
1189             {
1190                 fprintf( fn, "int %s( FL_OBJECT *, int, FL_Coord, "
1191                          "FL_Coord, int, void * );\n",
1192                          get_free_handle( obj, name ) );
1193             }
1194             else
1195             {
1196                 const char * hname = get_free_handle( obj, name );
1197                 int width = strlen( hname ) + 1;
1198 
1199                 fprintf( fn, "/***************************************\n"
1200                              " ***************************************/\n\n"
1201                              "int\n%s( FL_OBJECT * obj,\n"
1202                              "%*s int         ev,\n"
1203                              "%*s FL_Coord    mx,\n"
1204                              "%*s FL_Coord    my,\n"
1205                              "%*s int         key,\n"
1206                              "%*s void      * xev )\n"
1207                              "{\n"
1208                              "    /* Free object handler code */\n\n"
1209                              "    return 0;\n"
1210                              "}\n\n\n",
1211                          hname, width, " ", width, " ", width, " ",
1212                          width, " ", width, " " );
1213             }
1214         }
1215 
1216         if (    *cbname
1217              && ! strstr( cbname, "::" )
1218              && ! already_emitted( form->first, obj, cbname ) )
1219         {
1220             if ( ! code )
1221                 fprintf( fn, "void %s( FL_OBJECT *, long );\n", cbname );
1222             else
1223                 fprintf( fn, "/***************************************\n"
1224                              " ***************************************/\n\n"
1225                              "void\n%s( FL_OBJECT * obj,\n"
1226                              "%*s long        data )\n"
1227                              "{\n"
1228                              "    /* Fill-in code for callback here */\n"
1229                          "}\n\n\n", cbname, ( int ) strlen( cbname ) + 1, " " );
1230         }
1231 
1232         if ( obj->objclass == FL_MENU )
1233             menu_emit_item_callback_headers( fn, obj, code );
1234 
1235         if ( ! code )
1236             emit_objclass_spec_global( fn, obj );
1237     }
1238 
1239     fprintf( fn, "\n" );
1240 }
1241 
1242 
1243 /***************************************
1244  * Output header file that contains the form definition.
1245  ***************************************/
1246 
1247 static void
print_header_newformat(FILE * fn,FL_FORM * form,const char * fname)1248 print_header_newformat( FILE       * fn,
1249                         FL_FORM    * form,
1250                         const char * fname)
1251 {
1252     FL_OBJECT *obj;
1253     char name[ MAX_VAR_LEN ],
1254          fdtname[ MAX_VAR_LEN ];
1255 
1256     sprintf( fdtname, "FD_%s", fname );
1257     fprintf( fn, "typedef struct {\n"
1258                  "    FL_FORM   * %s;\n", fname );
1259     fprintf( fn, "    void      * vdata;\n"
1260                  "    char      * cdata;\n"
1261                  "    long        ldata;\n");
1262 
1263     init_array_names( );
1264 
1265     for ( obj = form->first; obj; obj = obj->next )
1266     {
1267         get_object_name( obj, name, NULL, NULL );
1268         if ( *name && ! check_array_name( name ) )
1269             fprintf( fn, "    FL_OBJECT * %s;\n", name );
1270     }
1271 
1272     if ( are_there_array_names( ) )
1273         print_array_names( fn, 1 );
1274 
1275     fprintf( fn, "} %s;\n", fdtname );
1276 
1277     fprintf( fn, "\n%s * create_form_%s( void );\n",
1278              fdtname, fname );
1279 }
1280 
1281 
1282 /***************************************
1283  * Prints the object declarations used in form
1284  ***************************************/
1285 
1286 static void
print_header_altformat(FILE * fn,FL_FORM * form,const char * fname)1287 print_header_altformat( FILE       * fn,
1288                         FL_FORM    * form,
1289                         const char * fname)
1290 {
1291     FL_OBJECT *obj;
1292     char name[ MAX_VAR_LEN ];
1293     int first = 1;
1294 
1295     fprintf( fn, "extern FL_FORM *%s;\n\n", fname );
1296     init_array_names( );
1297     obj = form->first;
1298 
1299     while ( ( obj = obj->next ) != NULL )
1300     {
1301         get_object_name( obj, name, NULL, NULL );
1302         if ( *name )
1303         {
1304             if ( ! check_array_name( name ) )
1305             {
1306                 fprintf( fn, first ? "extern FL_OBJECT\n" : ",\n" );
1307                 first = 0;
1308                 fprintf( fn, "        *%s", name );
1309             }
1310         }
1311     }
1312 
1313     if ( are_there_array_names( ) )
1314     {
1315         fprintf( fn, first ? "extern FL_OBJECT\n" : ",\n" );
1316         first = 0;
1317         print_array_names( fn, 0 );
1318     }
1319 
1320     if ( ! first )
1321         fprintf( fn, ";\n\n" );
1322 }
1323 
1324 
1325 /***************************************
1326  ***************************************/
1327 
1328 void
print_header(FILE * fn,FL_FORM * form,const char * fname)1329 print_header( FILE       * fn,
1330               FL_FORM    * form,
1331               const char * fname )
1332 {
1333     ( ! fdopt.altformat ? print_header_newformat : print_header_altformat )
1334         ( fn, form, fname );
1335 }
1336 
1337 
1338 /*
1339  * All callback stubs
1340  */
1341 
1342 /***************************************
1343  ***************************************/
1344 
1345 void
output_callbacks(FILE * fn,FRM * fdform,int nform)1346 output_callbacks( FILE * fn,
1347                   FRM  * fdform,
1348                   int    nform )
1349 {
1350     int i;
1351 
1352     for ( i = 0; i < nform; i++ )
1353     {
1354         fprintf( fn, "/* Callbacks and freeobj handlers for form %s */\n\n\n",
1355                  fdform[ i ].fname );
1356         print_callbacks_and_globals( fn, fdform[i].form, 1 );
1357         fprintf( fn, "\n" );
1358     }
1359 }
1360 
1361 
1362 /***************************************
1363  ***************************************/
1364 
1365 const char *
get_placement(FL_FORM * form)1366 get_placement( FL_FORM * form )
1367 {
1368     if ( ! form->first )
1369         return "FL_PLACE_CENTER";
1370     else if ( ! form->first->next )
1371         return "FL_PLACE_CENTER";
1372     else if ( form->first->next->resize )
1373         return "FL_PLACE_CENTERFREE";
1374 
1375     return "FL_PLACE_CENTER";
1376 }
1377 
1378 
1379 /*
1380  * A Main stub.
1381  */
1382 
1383 /***************************************
1384  ***************************************/
1385 
1386 static void
output_main_newformat(FILE * fn,FRM * fdform,int nform)1387 output_main_newformat( FILE * fn,
1388                        FRM  * fdform,
1389                        int    nform )
1390 {
1391     char fdtname[ MAX_VAR_LEN ];
1392     char * fname;
1393     int i;
1394 
1395     /* Only output callback stubs if not already output */
1396 
1397     if ( ! fdopt.emit_cb )
1398         output_callbacks( fn, fdform, nform );
1399 
1400     fprintf( fn, "\n/***************************************\n"
1401                  " ***************************************/\n\n"
1402                  "int\nmain( int    argc,\n      char * argv[ ] )\n{\n" );
1403 
1404     for ( i = 0; i < nform; i++ )
1405     {
1406         fname = fdform[ i ].fname;
1407         sprintf( fdtname, "FD_%s", fname );
1408         fprintf( fn, "    %s *fd_%s;\n", fdtname, fname );
1409     }
1410 
1411     fprintf( fn, "\n" );
1412 
1413     fprintf( fn, "    fl_initialize( &argc, argv, 0, 0, 0 );\n" );
1414 
1415     for ( i = 0; i < nform; i++ )
1416     {
1417         fname = fdform[ i ].fname;
1418         fprintf( fn, "    fd_%s = create_form_%s( );\n", fname, fname );
1419     }
1420 
1421     fprintf( fn, "\n    /* Fill-in form initialization code */\n\n" );
1422 
1423     fprintf( fn, "    /* Show the first form */\n\n" );
1424     fprintf( fn, "    fl_show_form( fd_%s->%s, %s, FL_FULLBORDER, "
1425                  "\"%s\" );\n\n",
1426              fdform[ 0 ].fname, fdform[ 0 ].fname,
1427              get_placement( fdform[ 0 ].form),
1428              fdform[ 0 ].fname );
1429 
1430     fprintf( fn, "    fl_do_forms( );\n\n" );
1431     for ( i = 0; i < nform; i++ )
1432         fprintf( fn, "    if ( fl_form_is_visible( fd_%s->%s ) )\n"
1433                      "        fl_hide_form( fd_%s->%s );\n"
1434                      "    fl_free( fd_%s );\n",
1435                  fdform[ i ].fname, fdform[ i ].fname, fdform[ i ].fname,
1436                  fdform[ i ].fname, fdform[ i ].fname );
1437     fprintf( fn, "    fl_finish( );\n\n"
1438                  "    return 0;\n"
1439                  "}\n" );
1440 }
1441 
1442 /***************************************
1443  ***************************************/
1444 
1445 static void
output_main_altformat(FILE * fn,FRM * fdform,int nform)1446 output_main_altformat( FILE * fn,
1447                        FRM  * fdform,
1448                        int    nform )
1449 {
1450     /* Only output callback stubs if not already output */
1451 
1452     if ( ! fdopt.emit_cb )
1453         output_callbacks( fn, fdform, nform );
1454 
1455     fprintf( fn, "int\nmain( int    argc,\n      char * argv[ ] )\n{\n" );
1456 
1457     fprintf( fn, "    fl_initialize( &argc, argv, 0, 0, 0 );\n\n" );
1458     fprintf( fn, "\n     %s( );\n\n", main_name );
1459     fprintf( fn, "\n     /* Fill-in form initialization code */\n\n" );
1460     fprintf( fn, "    /* Show the first form */\n\n" );
1461     fprintf( fn, "    fl_show_form( %s, FL_PLACE_CENTER, FL_FULLBORDER, "
1462              "\"%s\" );\n", fdform[ 0 ].fname, fdform[ 0 ].fname);
1463     fprintf( fn, "    fl_do_forms( );\n\n    return 0;\n}\n" );
1464 }
1465 
1466 
1467 /***************************************
1468  ***************************************/
1469 
1470 void
output_main(FILE * fn,FRM * fdform,int nform)1471 output_main( FILE * fn,
1472              FRM  * fdform,
1473              int    nform )
1474 {
1475     ( fdopt.altformat ? output_main_altformat : output_main_newformat )
1476         ( fn, fdform, nform );
1477 }
1478 
1479 
1480 /***************************************
1481  * set some defaults, unit/bw etc.
1482  ***************************************/
1483 
1484 static void
pre_form_output(FILE * fn)1485 pre_form_output( FILE * fn )
1486 {
1487     /* Some global defaults */
1488 
1489     if ( fdopt.unit != FL_COORD_PIXEL )
1490         fprintf( fn, "    int old_unit = fl_get_coordunit( );\n" );
1491 
1492     if ( fd_bwidth != FL_BOUND_WIDTH && fd_bwidth != 0 )
1493         fprintf( fn, "    int old_bw = fl_get_border_width( );\n" );
1494 
1495     if ( fdopt.unit != FL_COORD_PIXEL )
1496         fprintf( fn, "    fl_set_coordunit( %s );\n", unit_name( fdopt.unit ) );
1497 
1498     if ( fd_bwidth != FL_BOUND_WIDTH && fd_bwidth != 0 )
1499         fprintf( fn, "    fl_set_border_width( %d );\n", fd_bwidth );
1500 
1501     if (    fdopt.unit != FL_COORD_PIXEL
1502          || ( fd_bwidth != FL_BOUND_WIDTH && fd_bwidth != 0 ) )
1503         fprintf( fn, "\n" );
1504 }
1505 
1506 
1507 /***************************************
1508  ***************************************/
1509 
1510 static void
post_form_output(FILE * fn)1511 post_form_output( FILE * fn )
1512 {
1513     if ( fdopt.unit != FL_COORD_PIXEL )
1514         fprintf( fn, "    fl_set_coordunit( old_unit );\n" );
1515     if ( fd_bwidth != FL_BOUND_WIDTH && fd_bwidth )
1516         fprintf( fn, "    fl_set_border_width( old_bw );\n" );
1517 }
1518 
1519 
1520 /***************************************
1521  ***************************************/
1522 
1523 static void
output_object(FILE * fp,FL_OBJECT * obj,int altfmt)1524 output_object( FILE      * fp,
1525                FL_OBJECT * obj,
1526                int         altfmt )
1527 {
1528     FL_OBJECT * defobj,
1529                 fakeobj;
1530     char name[ MAX_VAR_LEN ],
1531          cbname[ MAX_VAR_LEN ],
1532          argname[ MAX_VAR_LEN ];
1533     char * p,
1534            fdvname[ MAX_VAR_LEN ];
1535     char *label;
1536     double sc = get_conversion_factor( );
1537 
1538     if ( obj->parent )
1539         return;
1540 
1541     strcpy( fdvname, "fdui" );
1542     get_object_name( obj, name, cbname, argname );
1543 
1544     if ( obj->objclass == FL_BEGIN_GROUP )
1545     {
1546         if ( *name )
1547         {
1548             if ( ! altfmt )
1549                 fprintf( fp, "\n    %s->%s = ", fdvname, name );
1550             else
1551                 fprintf( fp, "\n    %s = ", name );
1552         }
1553         else
1554             fprintf( fp, "\n    %s", name );
1555 
1556         fprintf( fp, "fl_bgn_group( );\n" );
1557     }
1558     else if ( obj->objclass == FL_END_GROUP )
1559         fprintf( fp, "\n    fl_end_group( );\n");
1560     else
1561     {
1562         defobj = find_class_default( obj->objclass, obj->type );
1563         if ( ! defobj )
1564         {
1565             M_err( "output_object",
1566                    "Failed to create default (class = %s, type = %s)",
1567                    find_class_name( obj->objclass ),
1568                    find_type_name( obj->objclass, obj->type ) );
1569             exit( 1 );
1570         }
1571 
1572         fprintf( fp, "\n    " );
1573 
1574         if ( *name )
1575         {
1576             if ( ! altfmt )
1577                 fprintf( fp, "%s->%s = ", fdvname, name );
1578             else
1579                 fprintf( fp, "%s = ", name );
1580         }
1581 
1582         fprintf( fp, "obj = " );
1583         fprintf( fp, "fl_add_%s( ", find_class_name( obj->objclass ) );
1584         fprintf( fp, "FL_%s,", find_type_name( obj->objclass, obj->type ) );
1585 
1586         fakeobj.x = obj->x;
1587         fakeobj.y = obj->y;
1588         fakeobj.w = obj->w;
1589         fakeobj.h = obj->h;
1590         fli_scale_object( &fakeobj, sc, sc );
1591 
1592         label = get_label( obj, 1 );
1593         if ( obj->objclass != FL_FREE )
1594             fprintf( fp, " %d, %d, %d, %d, \"%s\" );\n", fakeobj.x, fakeobj.y,
1595                      fakeobj.w, fakeobj.h, label );
1596         else
1597             fprintf( fp, "% d, %d, %d, %d, \"%s\", %s );\n",
1598                      fakeobj.x, fakeobj.y, fakeobj.w, fakeobj.h,
1599                      label, get_free_handle( obj, name ) );
1600         fl_free( label );
1601 
1602         if  (    ( p = get_shortcut_string( obj ) )
1603               && *p
1604               && obj->type != FL_RETURN_BUTTON )
1605             fprintf( fp, "    fl_set_%s_shortcut( obj, \"%s\", 1 );\n",
1606                      supported_shortcut( obj->objclass ),
1607                      get_shortcut_string( obj ) );
1608 
1609         if ( obj->boxtype != defobj->boxtype && obj->objclass != FL_BOX )
1610         {
1611             if ( obj->objclass != FL_CANVAS && obj->objclass != FL_FRAME )
1612                 emit_attrib( fp, obj->boxtype, vn_btype,
1613                              "fl_set_object_boxtype" );
1614         }
1615 
1616         if ( obj->col1 != defobj->col1 || obj->col2 != defobj->col2 )
1617         {
1618             if ( obj->objclass != FL_CANVAS )
1619                 fprintf( fp, "    fl_set_object_color( obj, %s, %s );\n",
1620                          fli_query_colorname( obj->col1 ),
1621                          fli_query_colorname( obj->col2 ) );
1622         }
1623 
1624         if ( obj->lcol != defobj->lcol )
1625             fprintf( fp, "    fl_set_object_lcolor( obj, %s );\n",
1626                      fli_query_colorname( obj->lcol ) );
1627 
1628         if ( obj->lsize != defobj->lsize )
1629             emit_attrib( fp, obj->lsize, vn_lsize, "fl_set_object_lsize" );
1630 
1631         if ( obj->align != defobj->align )
1632             emit_attrib( fp, obj->align, vn_align, "fl_set_object_lalign" );
1633 
1634         if ( obj->lstyle != defobj->lstyle )
1635             fprintf( fp, "    fl_set_object_lstyle( obj, %s );\n",
1636                      style_name( obj->lstyle ) );
1637 
1638         /* 'resize' must be checked for consistency with the gravity settings */
1639 
1640         obj->resize = check_resize( obj->resize,
1641                                     obj->nwgravity, obj->segravity );
1642         if ( obj->resize != defobj->resize )
1643             fprintf( fp, "    fl_set_object_resize( obj, %s );\n",
1644                      resize_name( obj->resize ) );
1645 
1646         if (    obj->nwgravity != defobj->nwgravity
1647              || obj->segravity != defobj->segravity)
1648             fprintf( fp, "    fl_set_object_gravity( obj, %s, %s );\n",
1649                      gravity_name( obj->nwgravity ),
1650                      gravity_name( obj->segravity ) );
1651 
1652         if ( *cbname )
1653             fprintf( fp, "    fl_set_object_callback( obj, %s, %s );\n",
1654                      cbname, argname );
1655 
1656         if ( obj->how_return != defobj->how_return )
1657             fprintf( fp, "    fl_set_object_return( obj, %s );\n",
1658                      get_how_return_name( obj->how_return, 1 ) );
1659     }
1660 
1661     /* Generate object class specifc settings */
1662 
1663     emit_objclass_spec_info( fp, obj );
1664 }
1665 
1666 
1667 /*
1668  * Local variables:
1669  * tab-width: 4
1670  * indent-tabs-mode: nil
1671  * End:
1672  */
1673