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_super.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 * translation between superspec and spec
27 */
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #include "fd_main.h"
34 #include "fd_spec.h"
35
36 #include "private/pslider.h"
37 #include "private/pbrowser.h"
38 #include "private/ppositioner.h"
39 #include "private/pcounter.h"
40 #include "private/pspinner.h"
41 #include "private/pscrollbar.h"
42 #include "private/pdial.h"
43 #include "private/pxyplot.h"
44 #include "private/pchoice.h"
45 #include "private/pmenu.h"
46 #include "private/pinput.h"
47
48
49 /***************************************
50 ***************************************/
51
52 SuperSPEC *
get_superspec(FL_OBJECT * ob)53 get_superspec( FL_OBJECT * ob )
54 {
55 SuperSPEC *sp = ob->u_vdata;
56
57 return sp ? sp : spec_to_superspec( ob );
58 }
59
60
61 /***************************************
62 ***************************************/
63
64 SuperSPEC *
spec_to_superspec(FL_OBJECT * obj)65 spec_to_superspec( FL_OBJECT * obj )
66 {
67 SuperSPEC *ssp;
68 int i;
69 int n;
70
71 if ( ! obj->u_vdata )
72 {
73 obj->u_vdata = ssp = fl_calloc( 1, sizeof *ssp );
74
75 ssp->content = NULL;
76 ssp->shortcut = NULL;
77 ssp->callback = NULL;
78 ssp->mode = NULL;
79 ssp->mval = NULL;
80 ssp->misc_char = NULL;
81
82 ssp->new_menuapi = 0;
83 ssp->nlines = 0;
84 }
85 else
86 ssp = obj->u_vdata;
87
88 if ( obj->objclass == FL_BROWSER )
89 {
90 FLI_BROWSER_SPEC *sp = obj->spec;
91
92 ssp->h_pref = sp->h_pref;
93 ssp->v_pref = sp->v_pref;
94
95 for ( i = 1; i <= ssp->nlines; i++ )
96 fl_free( ssp->content[ i ] );
97
98 n = ssp->nlines = fl_get_browser_maxline( obj );
99
100 ssp->content = fl_realloc( ssp->content,
101 ( n + 1 ) * sizeof *ssp->content );
102
103 for ( i = 1; i <= n; i++ )
104 ssp->content[ i ] = fl_strdup( fl_get_browser_line( obj, i ) );
105 }
106 else if ( obj->objclass == FL_CHOICE )
107 {
108 FLI_CHOICE_SPEC *sp = obj->spec;
109
110 for ( i = 1; i <= ssp->nlines; i++ )
111 {
112 fl_free( ssp->content[ i ] );
113 fl_free( ssp->shortcut[ i ] );
114 }
115
116 n = ssp->nlines = sp->numitems;
117
118 ssp->content = fl_realloc( ssp->content,
119 ( n + 1 ) * sizeof *ssp->content );
120 ssp->shortcut = fl_realloc( ssp->shortcut,
121 ( n + 1 ) * sizeof *ssp->shortcut );
122 ssp->mode = fl_realloc( ssp->mode,
123 ( n + 1 ) * sizeof *ssp->mode );
124
125 ssp->align = sp->align;
126 ssp->int_val = sp->val;
127
128 for ( i = 1; i <= n; i++ )
129 {
130 ssp->content[ i ] = fl_strdup( fl_get_choice_item_text( obj, i ) );
131
132 if ( sp->shortcut[ i ] )
133 ssp->shortcut[ i ] = fl_strdup( sp->shortcut[ i ] );
134 else
135 ssp->shortcut[ i ] = NULL;
136 }
137
138 memcpy( ssp->mode, sp->mode, ( n + 1 ) * sizeof *ssp->mode );
139
140 }
141 else if ( obj->objclass == FL_MENU )
142 {
143 FLI_MENU_SPEC *sp = obj->spec;
144
145 for ( i = 1; i <= ssp->nlines; i++ )
146 {
147 fl_free( ssp->content[ i ] );
148 fl_free( ssp->shortcut[ i ] );
149 fl_free( ssp->callback[ i ] );
150 }
151
152 n = ssp->nlines = sp->numitems;
153
154 ssp->content = fl_realloc( ssp->content,
155 ( n + 1 ) * sizeof *ssp->content );
156 ssp->shortcut = fl_realloc( ssp->shortcut,
157 ( n + 1 ) * sizeof *ssp->shortcut );
158 ssp->callback = fl_realloc( ssp->callback,
159 ( n + 1 ) * sizeof *ssp->callback );
160 ssp->mode = fl_realloc( ssp->mode,
161 ( n + 1 ) * sizeof *ssp->mode );
162 ssp->mval = fl_realloc( ssp->mval,
163 ( n + 1 ) * sizeof *ssp->mval );
164
165 for ( i = 1; i <= n; i++ )
166 {
167 ssp->content[ i ] =
168 fl_strdup( fl_get_menu_item_text( obj, sp->mval[ i ] ) );
169
170 if ( sp->shortcut[ i ] )
171 ssp->shortcut[ i ] = fl_strdup( sp->shortcut[ i ] );
172 else
173 ssp->shortcut[ i ] = NULL;
174
175 if ( sp->cb[ i ] )
176 ssp->callback[ i ] = fl_strdup( ( char * ) sp->cb[ i ] );
177 else
178 ssp->callback[ i ] = NULL;
179 }
180
181 memcpy( ssp->mode, sp->mode, ( n + 1 ) * sizeof *ssp->mode );
182 memcpy( ssp->mval, sp->mval, ( n + 1 ) * sizeof *ssp->mval );
183
184 }
185 else if ( obj->objclass == FL_SLIDER
186 || obj->objclass == FL_VALSLIDER
187 || obj->objclass == FL_THUMBWHEEL )
188 {
189 FLI_SLIDER_SPEC *sp = obj->spec;
190
191 ssp->val = sp->val;
192 ssp->min = sp->min;
193 ssp->max = sp->max;
194 ssp->step = sp->step;
195 ssp->prec = sp->prec;
196 ssp->ldelta = sp->ldelta;
197 ssp->rdelta = sp->rdelta;
198 ssp->slsize = sp->slsize;
199 }
200 else if ( ISBUTTON( obj->objclass )
201 || obj->objclass == FL_PIXMAP
202 || obj->objclass == FL_BITMAP )
203 {
204 FL_BUTTON_SPEC *sp = obj->spec;
205
206 ssp->mbuttons = 0;
207 for ( i = 0; i < 5; i++ )
208 if ( sp->react_to[ i ] )
209 ssp->mbuttons |= 1 << i;
210
211 ssp->int_val = sp->val;
212 }
213 else if ( obj->objclass == FL_POSITIONER )
214 {
215 FLI_POSITIONER_SPEC *sp = obj->spec;
216
217 ssp->xstep = sp->xstep;
218 ssp->ystep = sp->ystep;
219 ssp->xmin = sp->xmin;
220 ssp->xmax = sp->xmax;
221 ssp->xval = sp->xval;
222 ssp->ymin = sp->ymin;
223 ssp->ymax = sp->ymax;
224 ssp->yval = sp->yval;
225 }
226 else if ( obj->objclass == FL_COUNTER )
227 {
228 FLI_COUNTER_SPEC *sp = obj->spec;
229
230 ssp->val = sp->val;
231 ssp->lstep = sp->lstep;
232 ssp->sstep = sp->sstep;
233 ssp->min = sp->min;
234 ssp->max = sp->max;
235 ssp->prec = sp->prec;
236 }
237 else if ( obj->objclass == FL_DIAL )
238 {
239 FLI_DIAL_SPEC *sp = obj->spec;
240
241 ssp->min = sp->min;
242 ssp->max = sp->max;
243 ssp->val = sp->val;
244 ssp->step = sp->step;
245 ssp->thetai = sp->thetai;
246 ssp->thetaf = sp->thetaf;
247 ssp->direction = sp->direction;
248 }
249 else if ( obj->objclass == FL_XYPLOT )
250 {
251 FLI_XYPLOT_SPEC *sp = obj->spec;
252
253 ssp->xmajor = sp->xmajor;
254 ssp->xminor = sp->xminor;
255 ssp->ymajor = sp->ymajor;
256 ssp->yminor = sp->yminor;
257 ssp->xscale = sp->xscale;
258 ssp->yscale = sp->yscale;
259 ssp->xgrid = sp->xgrid;
260 ssp->ygrid = sp->ygrid;
261 ssp->grid_linestyle = sp->grid_linestyle;
262 ssp->xbase = sp->xbase;
263 ssp->ybase = sp->ybase;
264 ssp->mark_active = sp->mark_active;
265 }
266 else if ( obj->objclass == FL_SCROLLBAR )
267 {
268 FLI_SCROLLBAR_SPEC *scbsp = obj->spec;
269 FLI_SLIDER_SPEC *sp = scbsp->slider->spec;
270
271 ssp->val = sp->val;
272 ssp->min = sp->min;
273 ssp->max = sp->max;
274 ssp->prec = sp->prec;
275 ssp->step = sp->step;
276 ssp->slsize = sp->slsize;
277 ssp->ldelta = sp->ldelta;
278 ssp->rdelta = sp->rdelta;
279 }
280 else if ( obj->objclass == FL_SPINNER )
281 {
282 FLI_SPINNER_SPEC *sp = obj->spec;
283
284 ssp->val = fl_get_spinner_value( obj );
285 fl_get_spinner_bounds( obj, &ssp->min, &ssp->max );
286 ssp->step = fl_get_spinner_step( obj );
287 ssp->prec = fl_get_spinner_precision( obj );
288 ssp->orient = sp->orient;
289 }
290
291 return ssp;
292 }
293
294
295 /***************************************
296 ***************************************/
297
298 void *
superspec_to_spec(FL_OBJECT * obj)299 superspec_to_spec( FL_OBJECT * obj )
300 {
301 void *v = obj->spec;
302 SuperSPEC *ssp = obj->u_vdata;
303 int i = 0;
304
305 if ( ! ssp )
306 return v;
307
308 if ( obj->objclass == FL_BROWSER )
309 {
310 FLI_BROWSER_SPEC *sp = obj->spec;
311
312 fl_clear_browser( obj );
313
314 sp->h_pref = ssp->h_pref;
315 sp->v_pref = ssp->v_pref;
316
317 for ( i = 1; i <= ssp->nlines; i++ )
318 fl_addto_browser( obj, ssp->content[ i ] );
319 }
320 else if ( obj->objclass == FL_CHOICE )
321 {
322 fl_clear_choice( obj );
323
324 ( ( FLI_CHOICE_SPEC * ) obj->spec)->align = ssp->align;
325
326 for ( i = 1; i <= ssp->nlines; i++ )
327 {
328 fl_addto_choice( obj, ssp->content[ i ] );
329 if ( ssp->shortcut[ i ] )
330 fl_set_choice_item_shortcut( obj, i, ssp->shortcut[ i ] );
331 fl_set_choice_item_mode( obj, i, ssp->mode[ i ] );
332 }
333
334 if ( ssp->nlines >= ssp->int_val )
335 fl_set_choice( obj, ssp->int_val );
336 }
337 else if ( obj->objclass == FL_MENU )
338 {
339 fl_clear_menu( obj );
340
341 for ( i = 1; i <= ssp->nlines; i++ )
342 {
343 fl_addto_menu( obj, ssp->content[ i ] );
344 if ( ssp->shortcut[ i ] )
345 fl_set_menu_item_shortcut( obj, i, ssp->shortcut[ i ] );
346 if ( ssp->callback[ i ] )
347 fl_set_menu_item_callback( obj, i,
348 ( FL_PUP_CB ) fl_strdup( ssp->callback[ i ] ) );
349 fl_set_menu_item_mode( obj, i, ssp->mode[ i ] );
350 if ( ssp->mval[ i ] != i )
351 fl_set_menu_item_id( obj, i, ssp->mval[ i ] );
352 }
353 }
354 else if ( obj->objclass == FL_SLIDER
355 || obj->objclass == FL_VALSLIDER
356 || obj->objclass == FL_THUMBWHEEL)
357 {
358 FLI_SLIDER_SPEC *sp = obj->spec;
359
360 sp->val = ssp->val;
361 sp->min = ssp->min;
362 sp->max = ssp->max;
363 sp->step = ssp->step;
364 sp->prec = ssp->prec;
365 sp->ldelta = ssp->ldelta;
366 sp->rdelta = ssp->rdelta;
367 sp->slsize = ssp->slsize;
368 }
369 else if ( ISBUTTON( obj->objclass )
370 || obj->objclass == FL_PIXMAP
371 || obj->objclass == FL_BITMAP )
372 {
373 FL_BUTTON_SPEC *sp = obj->spec;
374
375 for ( i = 0; i < 5; i++ )
376 sp->react_to[ i ] = ( ssp->mbuttons & ( 1 << i ) ) != 0;
377 if ( ISBUTTON( obj->objclass ) )
378 fl_set_button_mouse_buttons( obj, ssp->mbuttons );
379
380 sp->val = ssp->int_val;
381
382 if ( ISBUTTON( obj->objclass ) )
383 fl_set_button( obj, sp->val );
384 }
385 else if ( obj->objclass == FL_POSITIONER )
386 {
387 FLI_POSITIONER_SPEC *sp = obj->spec;
388
389 sp->xstep = ssp->xstep;
390 sp->ystep = ssp->ystep;
391 sp->xmin = ssp->xmin;
392 sp->xmax = ssp->xmax;
393 sp->xval = ssp->xval;
394 sp->ymin = ssp->ymin;
395 sp->ymax = ssp->ymax;
396 sp->yval = ssp->yval;
397 }
398 else if ( obj->objclass == FL_COUNTER )
399 {
400 FLI_COUNTER_SPEC *sp = obj->spec;
401
402 sp->val = ssp->val;
403 sp->sstep = ssp->sstep;
404 sp->lstep = ssp->lstep;
405 sp->min = ssp->min;
406 sp->max = ssp->max;
407 sp->prec = ssp->prec;
408 }
409 else if ( obj->objclass == FL_SPINNER )
410 {
411 FLI_SPINNER_SPEC *sp = obj->spec;
412
413 fl_set_spinner_value( obj, ssp->val );
414 fl_set_spinner_bounds( obj, ssp->min, ssp->max );
415 fl_set_spinner_step( obj, ssp->step );
416 fl_set_spinner_precision( obj, ssp->prec );
417 sp->orient = ssp->orient;
418 }
419 else if ( obj->objclass == FL_DIAL )
420 {
421 FLI_DIAL_SPEC *sp = obj->spec;
422
423 sp->min = ssp->min;
424 sp->max = ssp->max;
425 sp->val = ssp->val;
426 sp->step = ssp->step;
427 sp->thetai = ssp->thetai;
428 sp->thetaf = ssp->thetaf;
429 sp->direction = ssp->direction;
430 }
431 else if ( obj->objclass == FL_XYPLOT )
432 {
433 FLI_XYPLOT_SPEC *sp = obj->spec;
434
435 sp->xmajor = ssp->xmajor;
436 sp->xminor = ssp->xminor;
437 sp->ymajor = ssp->ymajor;
438 sp->yminor = ssp->yminor;
439 sp->xscale = ssp->xscale;
440 sp->yscale = ssp->yscale;
441 sp->xgrid = ssp->xgrid;
442 sp->ygrid = ssp->ygrid;
443 sp->xbase = ssp->xbase;
444 sp->ybase = ssp->ybase;
445 sp->grid_linestyle = ssp->grid_linestyle;
446 sp->mark_active = ssp->mark_active;
447 }
448 else if ( obj->objclass == FL_SCROLLBAR )
449 {
450 FLI_SCROLLBAR_SPEC *scbsp = obj->spec;
451 FLI_SLIDER_SPEC *sp = scbsp->slider->spec;
452
453 sp->val = ssp->val;
454 sp->min = ssp->min;
455 sp->max = ssp->max;
456 sp->prec = ssp->prec;
457 sp->step = ssp->step;
458 sp->slsize = ssp->slsize;
459 sp->ldelta = ssp->ldelta;
460 sp->rdelta = ssp->rdelta;
461 }
462 else if ( obj->objclass == FL_SLIDER )
463 {
464 FLI_SPINNER_SPEC *sp = obj->spec;
465
466 ssp->val = fl_get_spinner_value( obj );
467 fl_get_spinner_bounds( obj, &ssp->min, &ssp->max );
468 ssp->step = fl_get_spinner_step( obj );
469 ssp->prec = fl_get_spinner_precision( obj );
470 ssp->orient = sp->orient;
471 }
472 else if ( obj->objclass == FL_INPUT )
473 {
474 /* Simply reset some attributes of the object to the defaults -
475 this makes only sense when, during testing, text was entered
476 into the input field and new we need to get rid of it */
477
478 FLI_INPUT_SPEC *sp = obj->spec;
479
480 sp->position = -1;
481 sp->endrange = -1;
482 sp->lines = sp->ypos = 1;
483 *sp->str = '\0';
484 }
485
486 return v;
487 }
488
489
490 /***************************************
491 ***************************************/
492
493 void
copy_superspec(FL_OBJECT * target,FL_OBJECT * src)494 copy_superspec( FL_OBJECT * target,
495 FL_OBJECT * src )
496 {
497 SuperSPEC *t = fl_malloc( sizeof *t ),
498 *s = get_superspec( src );
499 int i;
500
501 t->mode = NULL;
502 t->content = NULL;;
503 t->shortcut = NULL;
504 t->callback = NULL;
505 t->misc_char = NULL;
506
507 *t = *s;
508
509 t->content = NULL;
510 t->shortcut = NULL;
511 t->callback = NULL;
512 t->mode = NULL;
513 t->mval = NULL;
514
515 /* Take care of pointers in the SuperSPEC */
516
517 if ( s->nlines )
518 {
519 int cnt = s->nlines + 1;
520
521 t->content = s->content ?
522 fl_malloc( cnt * sizeof * t->content) : NULL;
523
524 t->shortcut = s->shortcut ?
525 fl_malloc( cnt * sizeof *t->shortcut ) : NULL;
526
527 t->callback = s->callback ?
528 fl_malloc( cnt * sizeof *t->callback ) : NULL;
529
530 t->mode = s->mode ? fl_malloc( cnt * sizeof *t->mode ) : NULL;
531
532 t->mval = s->mval ?
533 fl_malloc( cnt * sizeof *t->mval ) : NULL;
534 }
535
536 for ( i = 1; i <= s->nlines; i++ )
537 {
538 if ( t->content )
539 t->content[ i ] = s->content[ i ] ?
540 fl_strdup( s->content[ i ] ) : NULL;
541
542 if ( t->shortcut )
543 t->shortcut[ i ] = s->shortcut[ i ] ?
544 fl_strdup( s->shortcut[ i ] ) : NULL;
545
546 if ( t->callback )
547 t->callback[ i ] = s->callback[ i ] ?
548 fl_strdup( s->callback[ i ] ) : NULL;
549 }
550
551 if ( t->mode )
552 memcpy( t->mode, s->mode, ( s->nlines + 1 ) * sizeof *t->mode );
553
554 if ( t->mval )
555 memcpy( t->mval, s->mval, ( s->nlines + 1 ) * sizeof *t->mval );
556
557 if ( t->misc_char )
558 t->misc_char = fl_strdup( s->misc_char );
559
560 free_superspec( target );
561 target->u_vdata = t;
562 }
563
564
565 /***************************************
566 ***************************************/
567
568 void
free_superspec(FL_OBJECT * obj)569 free_superspec( FL_OBJECT * obj )
570 {
571 SuperSPEC *ssp = obj->u_vdata;
572 int i;
573
574 if ( ! ssp )
575 return;
576
577 for ( i = 1; i <= ssp->nlines; ++i )
578 {
579 if ( ssp->content )
580 fl_free( ssp->content[ i ] );
581 if ( ssp->shortcut )
582 fl_free( ssp->shortcut[ i ] );
583 if ( ssp->callback )
584 fl_free( ssp->callback[ i ] );
585 }
586
587 fl_free( ssp->misc_char );
588 fl_free( ssp->mode );
589 fl_free( ssp->mval );
590 fl_free( ssp->content );
591 fl_free( ssp->shortcut );
592 fl_free( ssp->callback );
593 }
594
595
596 /*
597 * Local variables:
598 * tab-width: 4
599 * indent-tabs-mode: nil
600 * End:
601 */
602