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_main.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 * This is the main module of the Form Designer, a program that
27 * helps you to design form in a fully interactive way. It
28 * automatically generates the corresponding C-code.
29 */
30
31 #ifdef HAVE_CONFIG_H
32 #include "config.h"
33 #endif
34
35 #include "fd_main.h"
36 #include "fd/ui_theforms.h"
37 #include "xpm/fd_logo.xpm"
38
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42
43 #if defined( __EMX__ ) || defined( WIN32 )
44 #define strcasecmp stricmp
45 #endif
46
47 #if defined __VMS && __VMS_VER < 70000000
48 extern int strcasecmp( const char *, const char * );
49 #endif
50
51
52 /***************************************
53 * Info about the program
54 ***************************************/
55
56 #define S( a ) #a
57 #define LIBVERSION( a, b ) S( a ) "." S( b )
58
59 static const char *fd_version[ ] =
60 {
61 "fdesign (FORM Designer) " LIBVERSION( FL_VERSION, FL_REVISION ) "." FL_FIXLEVEL,
62 "Copyright (c) 1996-2002 by T.C. Zhao and Mark Overmars",
63 "GNU Lesser General Public License sinc 2002",
64 NULL
65 };
66
67
68 /***************************************
69 ***************************************/
70
71 static void
print_version(int die)72 print_version( int die )
73 {
74 const char **p = fd_version;
75
76 for ( ; *p; p++ )
77 fprintf( stderr, "%s\n", *p );
78
79 if ( die )
80 exit( 0 );
81 }
82
83
84 char xform_header[ 128 ] = "forms.h";
85 char glcanvas_header[ 128 ] = "glcanvas.h";
86 long main_window = 0; /* The main screen window */
87 FL_Coord winw,
88 winh;
89
90
91 /* Various options of the program */
92
93 FD_Opt fdopt;
94 Conv convertor[ MAX_CONVERTOR + 1 ];
95
96 int fd_cntlborder;
97 int fd_bwidth;
98 int is_pasting;
99 int fd_trackgeometry = 1;
100 int fd_show_palette;
101 int fd_buttonLabelSize;
102 int fd_helpfontsize = 14;
103 int fd_align_fontsize = FL_TINY_SIZE;
104 int fd_type_fontsize = FL_TINY_SIZE;
105 int no_selection = 0;
106
107 GC fd_gc;
108 Colormap fd_colormap;
109 unsigned long fd_red,
110 fd_black,
111 fd_white,
112 fd_col;
113 Display * fd_display;
114 int changed = FL_FALSE; /* whether something has changed. */
115 char main_name[ MAX_VAR_LEN ]; /* name of the main calling routine */
116 char * loadedfile;
117
118
119 /***************************************
120 * Lets the user add some object to the form
121 ***************************************/
122
123 static void
add_something(void)124 add_something( void )
125 {
126 FL_OBJECT *obj;
127 double xx,
128 yy,
129 ww = 0.0,
130 hh = 0.0;
131
132 if ( ! cur_form )
133 return;
134
135 fl_winset( main_window );
136 get_mouse_pos( &xx, &yy );
137 scale_box( &xx, &yy, &ww, &hh );
138
139 if ( ww < 5.0 || hh < 5.0 )
140 return;
141
142 obj = add_an_object( cur_class, -1, xx, yy, ww, hh );
143 clear_selection( );
144 addto_selection( obj );
145 changed = FL_TRUE;
146
147 /* Reset the object type selection */
148
149 fl_deselect_browser( fd_control->objectbrowser );
150 reset_pallette( );
151 cur_class = -1;
152 }
153
154
155 /***************************************
156 * Changes the main calling name.
157 ***************************************/
158
159 void
mainname_cb(FL_OBJECT * obj FL_UNUSED_ARG,long arg FL_UNUSED_ARG)160 mainname_cb( FL_OBJECT * obj FL_UNUSED_ARG,
161 long arg FL_UNUSED_ARG )
162 {
163 const char *s;
164
165 if ( ! ( s = fl_show_input( "Main creation routine name:", main_name ) ) )
166 return;
167
168 if ( *s )
169 strcpy( main_name, s );
170 else
171 strcpy( main_name, "create_the_forms" );
172
173 changed = FL_TRUE;
174 }
175
176
177 /***************************************
178 ***************************************/
179
180 static int
double_click(const XEvent * xev)181 double_click( const XEvent * xev )
182 {
183 static Time lasttime;
184 static unsigned int lastbut;
185 static int lastx,
186 lasty;
187 int dblclk,
188 x = xev->xbutton.x,
189 y = xev->xbutton.y;
190
191 dblclk = xev->xbutton.button == lastbut
192 && xev->xbutton.time - lasttime < FL_CLICK_TIMEOUT
193 && lastx == x
194 && lasty == y;
195
196 lasttime = xev->xbutton.time;
197 lastbut = xev->xbutton.button;
198 lastx = x;
199 lasty = y;
200
201 return dblclk;
202 }
203
204
205 /***************************************
206 * Handle mouse click inside the working window
207 ***************************************/
208
209 static int
handle_click(XEvent * xev,void * p FL_UNUSED_ARG)210 handle_click( XEvent * xev,
211 void * p FL_UNUSED_ARG )
212 {
213 int dblclk = double_click( xev );
214
215 /* If no form exists yet ask the user to create it */
216
217 if ( ! cur_form )
218 {
219 addform_cb( NULL, 0 );
220 return 0;
221 }
222
223 if ( no_selection )
224 return 0;
225
226 if ( dblclk )
227 {
228 if ( xev->xbutton.button == 3 )
229 cut_selection( );
230 else if ( xev->xbutton.button == 1 && cur_class < 0 )
231 change_selection( );
232
233 redraw_the_form( 0 );
234 return 0;
235 }
236
237 if ( xev->xbutton.button == 1 && cur_class >= 0 )
238 {
239 XEvent ev;
240
241 XNextEvent( fl_display, &ev );
242
243 if ( ev.type == MotionNotify )
244 add_something( );
245 }
246 else if ( xev->xbutton.button == 3 && cur_class >= 0 )
247 {
248 cur_class = -1;
249 fl_deselect_browser( fd_control->objectbrowser );
250 select_pallette_entry( cur_class );
251 }
252 else if ( is_pasting )
253 /* empty */;
254 else if ( within_selection( xev->xbutton.x, xev->xbutton.y )
255 && xev->xbutton.button != 3 )
256 {
257 XEvent ev;
258
259 XNextEvent( fl_display, &ev );
260 if ( ev.type == MotionNotify )
261 handle_move( xev );
262 else if ( ev.type == ButtonRelease )
263 handle_select( &ev );
264 }
265 else
266 handle_select( xev );
267
268 redraw_the_form( 0 );
269 return 0;
270 }
271
272
273 /***************************************
274 ***************************************/
275
276 static void
handle_keypress(const XKeyEvent * xev)277 handle_keypress( const XKeyEvent * xev )
278 {
279 KeySym keysym;
280 char keybuf[ 128 ];
281 int stp = get_snap_size( );
282 int shift = ShiftIsDown( xev->state );
283
284 XLookupString( ( XKeyEvent * ) xev, keybuf, sizeof keybuf, &keysym, 0 );
285
286 if ( keysym >= XK_F1 && keysym <= XK_F12 )
287 func_cb( 0, keysym - XK_F1 + 1 );
288 else if ( IsRight( keysym ) )
289 ( shift ? resize_selection : move_selection )( stp, 0 );
290 else if ( IsLeft( keysym ) )
291 ( shift ? resize_selection : move_selection )( -stp, 0 );
292 else if ( IsUp( keysym ) )
293 ( shift ? resize_selection : move_selection )( 0, -stp );
294 else if ( IsDown( keysym ) )
295 ( shift ? resize_selection : move_selection )( 0, stp );
296 else if ( keysym == XK_Escape )
297 exit_cb( 0, 0 );
298 else if ( keysym == XK_t || keysym == XK_T )
299 ( fd_test->test->visible ? stoptest_cb : test_cb )( 0, 0 );
300 else if ( keysym == XK_s || keysym == XK_S )
301 saveforms_as_cb( 0, 0 );
302 else if ( IsTab( keysym ) )
303 ( shift ? prev_selection : next_selection )( );
304 else if ( keysym >= '0' && keysym <= '9' )
305 {
306 if ( ( stp = keysym - '0' ) == 0 )
307 stp = 10;
308 set_snap_size( stp, 1 );
309 }
310 }
311
312
313 /***************************************
314 * Process events on the main window. Since rubber band was implemented
315 * badly, can't use buttonpress callback
316 ***************************************/
317
318 static void
process_xevent(void)319 process_xevent( void )
320 {
321 XEvent xev;
322
323 fl_XNextEvent( &xev );
324 fli_xevent_name( "fd_main", &xev );
325 fl_winset( main_window );
326
327 switch ( xev.type )
328 {
329 case KeyPress:
330 handle_keypress( ( XKeyEvent * ) & xev );
331 break;
332 }
333 }
334
335
336 /***************************************
337 * The main event handling loop.
338 ***************************************/
339
340 static void
main_loop(void)341 main_loop( void )
342 {
343 FL_OBJECT *obj;
344 char str[ 3 * MAX_VAR_LEN + 20 ],
345 name[ MAX_VAR_LEN ];
346 char cbname[ MAX_VAR_LEN ],
347 argname[ MAX_VAR_LEN ];
348
349 while ( 1 )
350 {
351 obj = fl_do_forms( );
352
353 /* Check whether we're just testing a form */
354
355 if ( thetestform != NULL && obj != FL_EVENT )
356 {
357 get_object_name( obj, name, cbname, argname );
358 if ( ! *name )
359 strcpy( name, "<noname>" );
360 if ( ! *cbname )
361 sprintf( str, "Called: %s( %s, %s );", cbname, name, argname );
362 else
363 sprintf( str, "Returned: %s", name );
364 fl_addto_browser( fd_test->browser, str );
365 }
366
367 if ( obj == FL_EVENT )
368 process_xevent( );
369 }
370 }
371
372
373 #define DEFGeom "320x250+150+420" /* working area geometry */
374 #define DEFcntlGeom "+150+1" /* control panel position */
375 #define DEFattribGeom "+210+25" /* Attributes panel position */
376 #define DEFtestGeom "-275+2" /* Test panel position */
377 #define DEFalignGeom "-1+1" /* align panel position */
378 #define DEFhelpGeom "-1+1" /* Help panel position */
379
380 static FL_CMD_OPT fd_cmdopt[ ] =
381 {
382 { "-geometry", "*geometry", XrmoptionSepArg, NULL },
383 { "-border", ".XForm.Border", XrmoptionNoArg, "1" },
384 { "-convert", ".convert", XrmoptionNoArg, "1" },
385 { "-dir", ".dir", XrmoptionSepArg, NULL },
386 { "-unit", "*unit", XrmoptionSepArg, NULL },
387 { "-altformat", "*altformat", XrmoptionNoArg, "1" },
388 { "-I", "*xformHeader", XrmoptionSepArg, NULL },
389 { "-G", "*glcanvasHeader", XrmoptionSepArg, NULL },
390 { "-main", "*main", XrmoptionNoArg, "1" },
391 { "-callback", "*callback", XrmoptionNoArg, "1" },
392 { "-lax", "*lax", XrmoptionNoArg, "1" },
393 { "-nocode", "*nocode", XrmoptionNoArg, "0" },
394 { "-version", ".fdversion", XrmoptionNoArg, "1" },
395 { "-compensate", ".compensate", XrmoptionNoArg, "1" },
396 { "-ada", ".language", XrmoptionNoArg, "ada95" },
397 { "-ada95", ".language", XrmoptionNoArg, "ada95" },
398 { "-perl", ".language", XrmoptionNoArg, "perl" },
399 { "-python", ".language", XrmoptionNoArg, "python" },
400 { "-fortran", ".language", XrmoptionNoArg, "fortran" },
401 { "-pascal", ".language", XrmoptionNoArg, "pascal" },
402 { "-scm", ".language", XrmoptionNoArg, "scm" },
403 { "-ps", ".language", XrmoptionNoArg, "ps" },
404 { "-filter", ".filter", XrmoptionSepArg, NULL },
405 { "-migrate", ".migrate", XrmoptionNoArg, "1" },
406 { "-help", ".help", XrmoptionNoArg, "1" }
407 };
408
409 #define Ncopt ( sizeof fd_cmdopt / sizeof *fd_cmdopt )
410
411 /* resources */
412
413 #define NG 64
414 static char fdgeom[ NG ] = DEFGeom;
415 static char fdcntlgeom[ NG ] = DEFcntlGeom;
416 static char fdattribgeom[ NG ] = DEFattribGeom;
417 static char fdtestgeom[ NG ] = DEFtestGeom;
418 static char fdaligngeom[ NG ] = DEFalignGeom;
419 static char fdhelpgeom[ NG ] = DEFhelpGeom;
420 static char fd_attrib_col[ NG ];
421 static char fd_sunit[ 32 ];
422 static char fd_slanguage[ 32 ];
423 static char fd_sfilter[ 32 ];
424
425 static FL_resource fdres[ ] =
426 {
427 { "formDesign.geometry", "Geometry", FL_STRING, fdgeom, 0, NG },
428 { "workingArea.geometry", "Geometry", FL_STRING, fdgeom, 0, NG },
429 { "control.geometry", "Control.Geometry", FL_STRING, fdcntlgeom, 0, NG },
430 { "attributes.geometry", "Attributes.Geometry", FL_STRING, fdattribgeom,
431 0, NG },
432 { "attributes.background", "Attributes.Background", FL_STRING,
433 fd_attrib_col, 0, NG },
434 { "test.geometry", "Test.Geometry", FL_STRING, fdtestgeom, 0, NG },
435 { "help.geometry", "Help.Geometry", FL_STRING, fdhelpgeom, 0, NG },
436 { "align.geometry", "Align.Geometry", FL_STRING, fdaligngeom, 0, NG },
437 { "control.border", "XForm.Border", FL_BOOL, &fd_cntlborder, "0", 0 },
438 { "convert", "Convert", FL_BOOL, &fdopt.conv_only, "0", 0 },
439 { "migrate", "Migrate", FL_BOOL, &fdopt.conv_only, "0", 0 },
440 { "compensate", "Compensate", FL_BOOL, &fdopt.compensate, "0", 0 },
441 { "unit", "Unit", FL_STRING, fd_sunit, "pixel", 30 },
442 { "language", "Language", FL_STRING, fd_slanguage, "C", 30 },
443 { "filter", "Filter", FL_STRING, fd_sfilter, 0, 30 },
444 { "xformHeader", "XFormHeader", FL_STRING, xform_header, "forms.h", 128 },
445 { "glcanvasHeader", "GLCanvasHeader", FL_STRING, glcanvas_header,
446 "glcanvas.h", 128 },
447 { "altformat", "AltFormat", FL_BOOL, &fdopt.altformat, "0", 0 },
448 { "helpFontSize", "HelpFontSize", FL_INT, &fd_helpfontsize, "12", 0 },
449 { "nocode", "NoCode", FL_BOOL, &fdopt.emit_code, "1", 0 },
450 { "main", "Main", FL_BOOL, &fdopt.emit_main, "0", 0 },
451 { "callback", "Callback", FL_BOOL, &fdopt.emit_cb, "0", 0 },
452 { "lax", "Lax", FL_BOOL, &fdopt.lax, "0", 0 },
453 };
454
455 #define Nropt ( sizeof fdres / sizeof *fdres )
456
457 char *helps[ ] =
458 {
459 "-help this message",
460 "-display host:dpy display name",
461 "-name appname change app name",
462 "-border add border to control panel",
463 "-unit {mm|point|pixel|cp|cmm} unit of measure. Default pixel",
464 "-nocode supress code generation",
465 "-main emit main program template",
466 "-callback emit callback stubs",
467 "-altformat select alternative output format",
468 "-compensate emit font/server compensation code",
469 "-lax go easy on syntax checking",
470 "-I headername alternate header file (forms.h default)",
471 "-G glcanvas headername alternate glcanvas header file (glcanvas.h default)",
472 "-convert file-list convert .fd to code non-interactively",
473 "-migrate file-list convert & migrate .fd list non-interactively",
474 "-dir destdir output any generated files in destdir",
475 "-geometry geom initial working area geometry",
476 0,
477 };
478
479
480 /***************************************
481 ***************************************/
482
483 static void
usage(char * s,int die)484 usage( char * s,
485 int die )
486 {
487 char **q = helps;
488 Conv *cv = convertor;
489
490 fprintf( stderr, "usage: %s: [options] [file.fd]\n", s );
491 fprintf( stderr, " where options are\n" );
492 for ( ; *q; q++ )
493 fprintf( stderr, " %s\n", *q );
494
495 fprintf( stderr, " Language Options\n " );
496 for ( cv += 2; cv->lang_name; cv++ )
497 fprintf( stderr, "-%s ", cv->lang_name );
498
499 fprintf( stderr, "\n -filter f filter name" );
500 fprintf( stderr, "\n\n See also the online Help for resources info\n" );
501
502 if ( die )
503 exit( 1 );
504 }
505
506
507 /***************************************
508 ***************************************/
509
510 static int
lang_val(const char * s)511 lang_val( const char *s )
512 {
513 int i;
514
515 for ( i = 1; i < MAX_CONVERTOR; i++ )
516 if ( strcasecmp( s, convertor[ i ].lang_name ) == 0
517 || strncmp( s, convertor[ i ].lang_name, 3 ) == 0 )
518 return i;
519
520 return FD_C;
521 }
522
523
524 static int ignored_fake_configure;
525
526 /***************************************
527 ***************************************/
528
529 static int
handle_configure(XEvent * xev,void * p FL_UNUSED_ARG)530 handle_configure( XEvent * xev,
531 void * p FL_UNUSED_ARG )
532 {
533 /* Some window managers sends bogus configure events. Make a note of it */
534
535 if ( xev->xconfigure.send_event )
536 ignored_fake_configure = winw != xev->xconfigure.width
537 && winh != xev->xconfigure.height;
538 else
539 {
540 winw = xev->xconfigure.width;
541 winh = xev->xconfigure.height;
542
543 if ( cur_form && ( cur_form->w > winw || cur_form->h > winh ) )
544 {
545 reshape_form_background( winw, winh );
546 redraw_the_form( 1 );
547 }
548
549 if ( fd_resize->resize->visible )
550 {
551 fl_set_spinner_value( fd_resize->width, winw );
552 fl_set_spinner_value( fd_resize->height, winh );
553 }
554
555 changed = FL_TRUE;
556 }
557
558 return 1;
559 }
560
561
562 /***************************************
563 ***************************************/
564
565 static int
handle_expose(XEvent * xev,void * p FL_UNUSED_ARG)566 handle_expose( XEvent * xev,
567 void * p FL_UNUSED_ARG )
568 {
569 if ( xev->xexpose.count == 0 )
570 {
571 M_warn( "FD_Expose", "" );
572
573 /* If we have ignored a previous configure event, need the window
574 size might not be correct. Re-read */
575
576 if ( ignored_fake_configure )
577 fl_get_winsize( main_window, &winw, &winh );
578
579 /* Change form background size */
580
581 if ( cur_form && ( cur_form->w != winw || cur_form->h != winh ) )
582 reshape_form_background( winw, winh );
583
584 redraw_the_form( 1 );
585 ignored_fake_configure = 0;
586 return 1;
587 }
588
589 return 0;
590 }
591
592
593 /***************************************
594 * Need the ability to convert/help without requiring an X connection.
595 ***************************************/
596
597 static void
pre_connect(int argc,char * argv[])598 pre_connect( int argc,
599 char * argv[ ] )
600 {
601 int i,
602 s;
603 static char filter[ 128 ];
604
605 for ( i = 1; i < argc && *argv[ i ] == '-'; i++ )
606 {
607 if ( strncmp( argv[ i ] + 1, "help", 1 ) == 0 )
608 usage( argv[ 0 ], 1 );
609 else if ( strncmp( argv[ i ] + 1, "version", 4 ) == 0 )
610 print_version( 1 );
611 else if ( strncmp( argv[ i ] + 1, "altformat", 3 ) == 0 )
612 fdopt.altformat = 1;
613 else if ( strncmp( argv[ i ] + 1, "callback", 3 ) == 0 )
614 fdopt.emit_cb = 1;
615 else if ( strncmp( argv[ i ] + 1, "compensate", 4 ) == 0 )
616 fdopt.compensate = 1;
617 else if ( strncmp( argv[ i ] + 1, "main", 3 ) == 0 )
618 fdopt.emit_main = 1;
619 else if ( strncmp( argv[ i ] + 1, "noc", 3 ) == 0 )
620 fdopt.emit_code = 0;
621 else if ( strncmp( argv[ i ] + 1, "unit", 4 ) == 0 && i + 1 < argc )
622 fdopt.unit = unit_val( argv[ ++i ] );
623 else if ( strncmp( argv[ i ] + 1, "filter", 4 ) == 0 && i + 1 < argc )
624 strcpy( filter, argv[ ++i ] );
625 else if ( strncmp( argv[ i ], "-I", 2 ) == 0 )
626 {
627 if ( argv[ i ][ 2 ] != '\0' )
628 strcpy( xform_header, argv[ i ] + 2 );
629 else if ( i + 1 < argc )
630 strcpy( xform_header, argv[ ++i ] );
631 }
632 else if ( strcmp( argv[ i ], "-G" ) == 0 && i + 1 < argc )
633 strcpy( glcanvas_header, argv[ ++i ] );
634 else if ( strcmp( argv[ i ], "-bw" ) == 0 && i + 1 < argc )
635 fd_bwidth = atoi( argv[ ++i ] );
636 else if ( strncmp( argv[ i ] + 1, "convert", 1 ) == 0 )
637 {
638 fli_no_connection = 1;
639 fli_internal_init( );
640 fdopt.conv_only = 1;
641 }
642 else if ( strncmp( argv[ i ] + 1, "migrate", 1 ) == 0 )
643 {
644 fli_no_connection = 1;
645 fli_internal_init( );
646 fdopt.conv_only = 2;
647 }
648 else if ( strncmp( argv[ i ] + 1, "dir", 3 ) == 0 && i + 1 < argc )
649 {
650 fdopt.output_dir = malloc( strlen( argv[ ++i ] ) + 1 );
651 strcpy( fdopt.output_dir, argv[ i ] );
652 }
653 else if ( strncmp( argv[ i ] + 1, "lang", 4 ) == 0 && i + 1 < argc )
654 fdopt.language = lang_val( argv[ ++i ] );
655 else
656 fdopt.language = lang_val( argv[ i ] + 1 );
657 }
658
659 if ( fdopt.language < FD_C || fdopt.language > FD_EXP )
660 fdopt.language = FD_C;
661
662 if ( filter[ 0 ] )
663 convertor[ fdopt.language ].extern_convertor = filter;
664
665 if ( convertor[ fdopt.language ].init )
666 convertor[ fdopt.language ].init( );
667
668 /* No need to check for C syntax if not C program */
669
670 if ( fdopt.language != FD_C )
671 fdopt.lax = 1;
672
673 if ( ! fdopt.conv_only )
674 return;
675
676 fli_set_app_name( argv[ 0 ], "Fdesign" ); /* resource routine needs it */
677 fli_init_context( );
678 create_the_forms( );
679 init_classes( );
680
681 fl_dpi = 96;
682
683 if ( i > argc - 1 )
684 {
685 if ( fdopt.conv_only == 1 )
686 fprintf( stderr, "'-convert' requires argument(s)\n" );
687 else
688 fprintf( stderr, "'-migrate' requires argument(s)\n" );
689
690 usage( argv[ 0 ], 1 );
691 }
692
693 for ( s = i; s < argc; s++ )
694 {
695 reset_object_list( );
696
697 if ( load_forms( FL_FALSE, argv[ s ] ) < 0 )
698 {
699 fprintf( stderr, "Unable to load '%s'\n", argv[ s ] );
700 exit( 1 );
701 }
702
703 if ( ! save_forms( argv[ s ] ) )
704 {
705 fprintf( stderr, "Unable to convert '%s'\n", argv[ s ] );
706 exit( 1 );
707 }
708 }
709
710 exit( 0 );
711 }
712
713
714 /***************************************
715 ***************************************/
716
717 static int
parse_geometry(const char * gstr,int * x,int * y,unsigned int * w,unsigned int * h)718 parse_geometry( const char * gstr,
719 int * x,
720 int * y,
721 unsigned int * w,
722 unsigned int * h )
723 {
724 int s;
725
726 s = XParseGeometry( ( char * ) gstr, x, y, w, h );
727 if ( s & XValue && s & XNegative )
728 *x = fl_scrw - FL_abs( *x );
729 if ( s & YValue && s & YNegative )
730 *y = fl_scrh - FL_abs( *y );
731 return s;
732 }
733
734 #include <signal.h>
735
736 /***************************************
737 ***************************************/
738
739 static void
interrupted(int s FL_UNUSED_ARG,void * data FL_UNUSED_ARG)740 interrupted( int s FL_UNUSED_ARG,
741 void * data FL_UNUSED_ARG )
742 {
743 exit_cb( 0, 0 );
744 }
745
746
747 /***************************************
748 * Default action for delete window client message
749 ***************************************/
750
751 static int
delete_handler(FL_FORM * form FL_UNUSED_ARG,void * data FL_UNUSED_ARG)752 delete_handler( FL_FORM * form FL_UNUSED_ARG,
753 void * data FL_UNUSED_ARG )
754 {
755 if ( changed
756 && fl_show_question( "Changes have not been saved\n"
757 "Save them now ?", 1 )
758 && ! save_forms( NULL ) )
759 return FL_IGNORE;
760
761 exit( 0 );
762 return 0; /* shut up compiler */
763 }
764
765
766 /***************************************
767 * Always output perl code in altformat
768 ***************************************/
769
770 static void
perl_init(void)771 perl_init( void )
772 {
773 fdopt.altformat = 1;
774 }
775
776
777 /***************************************
778 ***************************************/
779
780 static void
initialize(void)781 initialize( void )
782 {
783 fdopt.conv_only = 0;
784 fdopt.language = FD_C;
785 fdopt.emit_code = 1;
786
787 convertor[ FD_EXP ].lang_name = "exp";
788 convertor[ MAX_CONVERTOR ].lang_name = NULL;
789
790 convertor[ FD_C ].lang_name = "C";
791 convertor[ FD_C ].convert = C_output;
792
793 convertor[ FD_ADA95 ].lang_name = "ada";
794 convertor[ FD_ADA95 ].extern_convertor = "flc2ada";
795 convertor[ FD_ADA95 ].need_c_code = 1;
796
797 convertor[ FD_PASCAL ].lang_name = "pascal";
798 convertor[ FD_PASCAL ].extern_convertor = "fd2pascal";
799
800 convertor[ FD_PS ].lang_name = "ps";
801 convertor[ FD_PS ].extern_convertor = "fd2ps";
802
803 convertor[ FD_PERL ].lang_name = "perl";
804 convertor[ FD_PERL ].need_c_code = 1;
805 convertor[ FD_PERL ].extern_convertor = "fd2perl";
806 convertor[ FD_PERL ].init = perl_init;
807
808 convertor[ FD_PYTHON ].lang_name = "python";
809 convertor[ FD_PYTHON ].extern_convertor = "fd2python";
810
811 convertor[ FD_FORTRAN ].lang_name = "fortran";
812 convertor[ FD_FORTRAN ].extern_convertor = "fd2fortran";
813
814 convertor[ FD_SCM ].lang_name = "scm";
815 convertor[ FD_SCM ].extern_convertor = "fd2scm";
816 }
817
818
819 /***************************************
820 ***************************************/
821
822 static int
ignore_close(FL_FORM * a FL_UNUSED_ARG,void * b FL_UNUSED_ARG)823 ignore_close( FL_FORM *a FL_UNUSED_ARG,
824 void *b FL_UNUSED_ARG )
825 {
826 return FL_IGNORE;
827 }
828
829
830 /***************************************
831 ***************************************/
832
833 int
main(int argc,char * argv[])834 main( int argc,
835 char * argv[ ] )
836 {
837 unsigned int w = 0,
838 h = 0;
839 int x = 0,
840 y = 0,
841 s,
842 version,
843 revision;
844 FL_IOPT cntl;
845 unsigned int mask;
846 char *tmp = NULL;
847
848 /* Before doing anything, check to make sure the library is made
849 correctly */
850
851 if ( FL_INCLUDE_VERSION != fl_library_version( &version, &revision ) )
852 {
853 fprintf( stderr, "Library and header mismatch\n" );
854 fprintf( stderr, " Header Version:%d.%d.%s\n",
855 FL_VERSION, FL_REVISION, FL_FIXLEVEL );
856 fprintf( stderr, " Library version:%d.%d\n", version, revision );
857 }
858
859 initialize( );
860
861 /* For conversion, version and usage help, we don't need a connection.
862 pre_connect will exit in such circumstances. */
863
864 pre_connect( argc, argv );
865
866 /* Force fdesign to come up in default visual */
867
868 cntl.vclass = FL_DefaultVisual;
869 cntl.doubleBuffer = 0;
870 cntl.browserFontSize = FL_NORMAL_FONT;
871 mask = FL_PDVisual | FL_PDDouble | FL_PDBrowserFontSize;
872
873 cntl.sharedColormap = 1;
874 mask |= FL_PDSharedMap;
875
876 fl_set_defaults( mask, &cntl );
877
878 if ( ! ( fd_display = fl_initialize( &argc, argv, 0, fd_cmdopt, Ncopt ) ) )
879 exit( 1 );
880
881 fl_get_app_resources( fdres, Nropt );
882 fl_add_signal_callback( SIGINT, interrupted, 0 );
883
884 if ( argv[ 1 ] && argv[ 1 ][ 0 ] == '-' )
885 {
886 fprintf( stderr, " Unknown option: %s\n", argv[ 1 ] );
887 usage( argv[ 0 ], 1 );
888 }
889
890 fli_cntl.coordUnit = FL_COORD_PIXEL;
891 fdopt.unit = unit_val( fd_sunit );
892 fdopt.language = lang_val( fd_slanguage );
893
894 if ( *fd_sfilter )
895 convertor[ fdopt.language ].extern_convertor = fd_sfilter;
896
897 /* No need to check for C syntax if not C program */
898
899 if ( fdopt.language != FD_C )
900 fdopt.lax = 1;
901
902 if ( convertor[ fdopt.language ].init )
903 convertor[ fdopt.language ].init( );
904
905 fd_bwidth = fli_cntl.borderWidth;
906 M_warn( "fdesign", "UNIT=%s BW=%d", unit_name( fdopt.unit ), fd_bwidth );
907
908 create_the_forms( );
909 fl_set_atclose( delete_handler, 0 );
910
911 /* Must suspend user requested button label font throughout fdesign and
912 enable it only when testing */
913
914 fd_buttonLabelSize = fli_cntl.buttonFontSize;
915 fli_cntl.buttonFontSize = 0;
916
917 /* Initialize stuff */
918
919 init_classes( );
920
921 fl_set_counter_bounds( fd_align->snapobj, 1.0, 500.0 );
922 fl_set_counter_step( fd_align->snapobj, 1.0, 5.0 );
923 fl_set_counter_value( fd_align->snapobj, 10.0 );
924 fl_set_counter_precision( fd_align->snapobj, 0 );
925 fl_set_form_atclose( fd_align->align, ignore_close, NULL );
926
927 fl_set_spinner_bounds( fd_resize->width, 1, SHRT_MAX );
928 fl_set_spinner_bounds( fd_resize->height, 1, SHRT_MAX );
929 fl_set_form_atclose( fd_resize->resize, ignore_close, NULL );
930
931 fl_set_form_atclose( fd_attrib->attrib, ignore_close, NULL );
932 fl_set_form_atclose( fd_attrib->attrib, ignore_close, NULL );
933 fl_set_form_atclose( fd_test->test, ignore_close, NULL );
934 fl_set_form_atclose( fd_help->helpform, ignore_close, NULL );
935
936 thetestform = NULL;
937 strcpy( main_name, "create_the_forms" );
938
939 /* Load files */
940
941 /* If only one argument is given and the file does not exist, we can
942 assume that the intention is to create a new file so we don't bother
943 to try to load it */
944
945 if ( argc >= 2
946 && access( tmp = append_fd_suffix( argv[ argc - 1 ] ), R_OK ) == 0 )
947 {
948 for ( s = 1; s < argc; s++ )
949 if ( load_forms( s == 1 ? FL_FALSE : FL_TRUE, argv[ s ] ) < 0 )
950 break;
951 }
952 else
953 {
954 select_object_by_class( FL_BUTTON );
955 select_pallette_entry( FL_BUTTON );
956 }
957
958 fli_safe_free( tmp );
959
960 /* Do auto-naming for single file only */
961
962 if ( argc == 2 )
963 loadedfile = rel2abs( argv[ 1 ] );
964
965 /* See if color change */
966
967 if ( fd_attrib_col[ 0 ] )
968 {
969 long c = FL_FREE_COL1 - 10;
970
971 fl_mapcolor_name( c, fd_attrib_col );
972 modify_attrib_basic_color( c, c );
973 }
974
975 parse_geometry( fdcntlgeom, &x, &y, &w, &h );
976 fl_set_form_position( fd_control->control, x, y );
977
978 fl_set_app_mainform( fd_control->control );
979 fli_set_form_icon_data( fd_control->control, fd_logo_pixels );
980 fl_show_form( fd_control->control, FL_PLACE_GEOMETRY,
981 ( 1 || fd_cntlborder ) ? FL_FULLBORDER : FL_TRANSIENT,
982 "Control" );
983
984 /* Other geometries */
985
986 parse_geometry( fdattribgeom, &x, &y, &w, &h );
987 fl_set_form_position( fd_attrib->attrib, x, y );
988
989 parse_geometry( fdtestgeom, &x, &y, &w, &h );
990 fl_set_form_position( fd_test->test, x, y );
991
992 parse_geometry( fdaligngeom, &x, &y, &w, &h );
993 fl_set_form_position( fd_align->align, x, y );
994
995 parse_geometry( fdhelpgeom, &x, &y, &w, &h );
996 fl_set_form_position( fd_help->helpform, x, y );
997
998 s = parse_geometry( fdgeom, &x, &y, &w, &h );
999 if ( s & XValue || s & YValue )
1000 fl_winposition( x, y );
1001 if ( s & WidthValue && s & HeightValue )
1002 fl_initial_winsize( w, h );
1003
1004 /* If a form is already loaded, use that size */
1005
1006 if ( cur_form )
1007 {
1008 y -= cur_form->h - h;
1009 w = cur_form->w;
1010 h = cur_form->h;
1011 fl_initial_wingeometry( x, y, w, h );
1012 }
1013
1014 winw = w;
1015 winh = h;
1016
1017 fd_colormap = fl_state[ fl_vmode ].colormap;
1018 fd_white = fl_get_flcolor( FL_WHITE );
1019 fd_red = fl_get_flcolor( FL_RED );
1020 fd_black = fl_get_flcolor( FL_BLACK );
1021 fd_col = fl_get_flcolor( FL_COL1 );
1022
1023 main_window = fli_cmap_winopen( fl_root, fd_colormap, "Form Design" );
1024
1025 fl_set_fselector_transient( 1 );
1026
1027 fl_add_event_callback( main_window, Expose, handle_expose, 0 );
1028 fl_add_event_callback( main_window, ConfigureNotify, handle_configure, 0 );
1029 fl_add_event_callback( main_window, ButtonPress, handle_click, 0 );
1030 fl_addto_selected_xevent( main_window,
1031 ButtonMotionMask | PointerMotionHintMask );
1032 fl_addto_selected_xevent( main_window, ButtonReleaseMask );
1033
1034 redraw_the_form( 1 );
1035
1036 /* GC is valid only after at least one window is created */
1037
1038 fd_gc = fl_state[ fl_vmode ].gc[ 8 ];
1039
1040 main_loop( );
1041
1042 return 0;
1043 }
1044
1045
1046 /***************************************
1047 ***************************************/
1048
1049 void
set_snap_size(int n,int cb)1050 set_snap_size( int n,
1051 int cb )
1052 {
1053 fl_set_counter_value( fd_align->snapobj, n > 0 ? n : 5 );
1054 if ( cb )
1055 fl_call_object_callback( fd_align->snapobj );
1056 }
1057
1058
1059 /***************************************
1060 ***************************************/
1061
1062 int
get_snap_size(void)1063 get_snap_size( void )
1064 {
1065 return 0.01 + fl_get_counter_value( fd_align->snapobj );
1066 }
1067
1068
1069 /*
1070 * Local variables:
1071 * tab-width: 4
1072 * indent-tabs-mode: nil
1073 * End:
1074 */
1075