acpi: Select proper one shot timer based on CPUs' C3 state.
[dragonfly.git] / contrib / bsdinstaller-1.1.6 / src / lib / libdfui / form.c
1 /*
2  * Copyright (c)2004 Cat's Eye Technologies.  All rights reserved.
3  * 
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 
8  *   Redistributions of source code must retain the above copyright
9  *   notice, this list of conditions and the following disclaimer.
10  * 
11  *   Redistributions in binary form must reproduce the above copyright
12  *   notice, this list of conditions and the following disclaimer in
13  *   the documentation and/or other materials provided with the
14  *   distribution.
15  * 
16  *   Neither the name of Cat's Eye Technologies nor the names of its
17  *   contributors may be used to endorse or promote products derived
18  *   from this software without specific prior written permission. 
19  * 
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
31  * OF THE POSSIBILITY OF SUCH DAMAGE. 
32  */
33
34 /*
35  * form.c
36  * $Id: form.c,v 1.18 2005/03/04 21:26:20 cpressey Exp $
37  */
38
39 #include <stdarg.h>
40 #include <stdlib.h>
41 #include <string.h>
42
43 #include <libaura/mem.h>
44
45 #define NEEDS_DFUI_STRUCTURE_DEFINITIONS
46 #include "dfui.h"
47 #undef  NEEDS_DFUI_STRUCTURE_DEFINITIONS
48 #include "dump.h"
49
50 /*** INFOS ***/
51
52 struct dfui_info *
53 dfui_info_new(const char *name, const char *short_desc, const char *long_desc)
54 {
55         struct dfui_info *i;
56
57         AURA_MALLOC(i, dfui_info);
58         i->name = aura_strdup(name);
59         i->short_desc = aura_strdup(short_desc);
60         i->long_desc = aura_strdup(long_desc);
61         
62         return(i);
63 }
64
65 void
66 dfui_info_free(struct dfui_info *i)
67 {
68         free(i->name);
69         free(i->short_desc);
70         free(i->long_desc);
71         AURA_FREE(i, dfui_info);
72 }
73
74 const char *
75 dfui_info_get_name(const struct dfui_info *i)
76 {
77         if (i == NULL)
78                 return("");
79         return(i->name);
80 }
81
82 const char *
83 dfui_info_get_short_desc(const struct dfui_info *i)
84 {
85         if (i == NULL)
86                 return("");
87         return(i->short_desc);
88 }
89
90 const char *
91 dfui_info_get_long_desc(const struct dfui_info *i)
92 {
93         if (i == NULL)
94                 return("");
95         return(i->long_desc);
96 }
97
98 void
99 dfui_info_set_name(struct dfui_info *i, const char *name)
100 {
101         if (i == NULL)
102                 return;
103         if (i->name != NULL)
104                 free(i->name);
105         i->name = aura_strdup(name);
106 }
107
108 void
109 dfui_info_set_short_desc(struct dfui_info *i, const char *short_desc)
110 {
111         if (i == NULL)
112                 return;
113         if (i->short_desc != NULL)
114                 free(i->short_desc);
115         i->short_desc = aura_strdup(short_desc);
116 }
117
118 void
119 dfui_info_set_long_desc(struct dfui_info *i, const char *long_desc)
120 {
121         if (i == NULL)
122                 return;
123         if (i->long_desc != NULL)
124                 free(i->long_desc);
125         i->long_desc = aura_strdup(long_desc);
126 }
127
128 /*** PROPERTIES ***/
129
130 struct dfui_property *
131 dfui_property_new(const char *name, const char *value)
132 {
133         struct dfui_property *p;
134
135         AURA_MALLOC(p, dfui_property);
136         p->name = aura_strdup(name);
137         p->value = aura_strdup(value);
138
139         return(p);
140 }
141
142 void
143 dfui_property_free(struct dfui_property *p)
144 {
145         if (p == NULL)
146                 return;
147         free(p->name);
148         free(p->value);
149         AURA_FREE(p, dfui_property);
150 }
151
152 void
153 dfui_properties_free(struct dfui_property *head)
154 {
155         struct dfui_property *p;
156
157         for (p = head; p != NULL; ) {
158                 head = p->next;
159                 dfui_property_free(p);
160                 p = head;
161         }
162 }
163
164 struct dfui_property *
165 dfui_property_find(struct dfui_property *head, const char *name)
166 {
167         struct dfui_property *p;
168
169         for (p = head; p != NULL; p = p->next) {
170                 if (strcmp(name, p->name) == 0)
171                         return(p);
172         }
173
174         return(NULL);
175 }
176
177 const char *
178 dfui_property_get(struct dfui_property *head, const char *name)
179 {
180         struct dfui_property *p;
181
182         if ((p = dfui_property_find(head, name)) != NULL)
183                 return(p->value);
184         return("");
185 }
186
187 struct dfui_property *
188 dfui_property_set(struct dfui_property **head, const char *name, const char *value)
189 {
190         struct dfui_property *p;
191
192         if (head == NULL)
193                 return(NULL);
194
195         if ((p = dfui_property_find(*head, name)) != NULL) {
196                 free(p->value);
197                 p->value = aura_strdup(value);
198                 return(p);
199         }
200
201         p = dfui_property_new(name, value);
202         p->next = *head;
203         *head = p;
204         
205         return(p);
206 }
207
208 const char *
209 dfui_property_get_name(const struct dfui_property *p)
210 {
211         return(p->name);
212 }
213
214 const char *
215 dfui_property_get_value(const struct dfui_property *p)
216 {
217         return(p->value);
218 }
219
220 /*** FIELDS ***/
221
222 struct dfui_field *
223 dfui_field_new(const char *id, struct dfui_info *info)
224 {
225         struct dfui_field *fi;
226
227         AURA_MALLOC(fi, dfui_field);
228         fi->id = aura_strdup(id);
229         fi->info = info;
230         fi->option_head = NULL;
231         fi->property_head = NULL;
232         fi->next = NULL;
233
234         dfui_field_property_set(fi, "editable", "true");
235
236         return(fi);
237 }
238
239 void
240 dfui_field_free(struct dfui_field *fi)
241 {
242         free(fi->id);
243         dfui_info_free(fi->info);
244         dfui_options_free(fi->option_head);
245         dfui_properties_free(fi->property_head);
246         AURA_FREE(fi, dfui_field);
247 }
248
249 void
250 dfui_fields_free(struct dfui_field *head)
251 {
252         struct dfui_field *fi;
253
254         fi = head;
255         while (fi != NULL) {
256                 head = fi->next;
257                 dfui_field_free(fi);
258                 fi = head;
259         }
260 }
261
262 struct dfui_field *
263 dfui_field_get_next(const struct dfui_field *fi)
264 {
265         if (fi == NULL)
266                 return(NULL);
267         return(fi->next);
268 }
269
270 const char *
271 dfui_field_get_id(const struct dfui_field *fi)
272 {
273         if (fi == NULL)
274                 return(NULL);
275         return(fi->id);
276 }
277
278 struct dfui_info *
279 dfui_field_get_info(const struct dfui_field *fi)
280 {
281         if (fi == NULL)
282                 return(NULL);
283         return(fi->info);
284 }
285
286 struct dfui_option *
287 dfui_field_option_add(struct dfui_field *fi, const char *value)
288 {
289         struct dfui_option *o;
290
291         if (fi == NULL)
292                 return(NULL);
293         o = dfui_option_new(value);
294         o->next = fi->option_head;
295         fi->option_head = o;
296
297         return(o);
298 }
299
300 struct dfui_option *
301 dfui_field_option_get_first(const struct dfui_field *fi)
302 {
303         if (fi == NULL)
304                 return(NULL);
305         return(fi->option_head);
306 }
307
308 struct dfui_property *
309 dfui_field_property_set(struct dfui_field *fi, const char *name, const char *value)
310 {
311         return(dfui_property_set(&fi->property_head, name, value));
312 }
313
314 const char *
315 dfui_field_property_get(const struct dfui_field *fi, const char *name)
316 {
317         return(dfui_property_get(fi->property_head, name));
318 }
319
320 int
321 dfui_field_property_is(const struct dfui_field *fi, const char *name, const char *value)
322 {
323         struct dfui_property *h;
324
325         if (fi == NULL)
326                 return(0);
327         if ((h = dfui_property_find(fi->property_head, name)) == NULL)
328                 return(0);
329         return(!strcmp(h->value, value));
330 }
331
332 /*** OPTIONS ***/
333
334 struct dfui_option *
335 dfui_option_new(const char *value)
336 {
337         struct dfui_option *o;
338
339         AURA_MALLOC(o, dfui_option);
340         o->value = aura_strdup(value);
341         o->next = NULL;
342
343         return(o);
344 }
345
346 void
347 dfui_option_free(struct dfui_option *o)
348 {
349         if (o == NULL)
350                 return;
351         free(o->value);
352         AURA_FREE(o, dfui_option);
353 }
354
355 void
356 dfui_options_free(struct dfui_option *head)
357 {
358         struct dfui_option *o;
359
360         o = head;
361         while (o != NULL) {
362                 head = o->next;
363                 dfui_option_free(o);
364                 o = head;
365         }
366 }
367
368 struct dfui_option *
369 dfui_option_get_next(const struct dfui_option *o)
370 {
371         if (o == NULL)
372                 return(NULL);
373         return(o->next);
374 }
375
376 const char *
377 dfui_option_get_value(const struct dfui_option *o)
378 {
379         if (o == NULL)
380                 return("");
381         return(o->value);
382 }
383
384 /*** ACTIONS ***/
385
386 struct dfui_action *
387 dfui_action_new(const char *id, struct dfui_info *info)
388 {
389         struct dfui_action *a;
390
391         AURA_MALLOC(a, dfui_action);
392         a->id = aura_strdup(id);
393         a->info = info;
394         a->next = NULL;
395         a->property_head = NULL;
396         
397         return(a);
398 }
399
400 void
401 dfui_action_free(struct dfui_action *a)
402 {
403         free(a->id);
404         dfui_info_free(a->info);
405         dfui_properties_free(a->property_head);
406         AURA_FREE(a, dfui_action);
407 }
408
409 void
410 dfui_actions_free(struct dfui_action *head)
411 {
412         struct dfui_action *a;
413
414         a = head;
415         while (a != NULL) {
416                 head = a->next;
417                 dfui_action_free(a);
418                 a = head;
419         }
420 }
421
422 struct dfui_action *
423 dfui_action_get_next(const struct dfui_action *a)
424 {
425         if (a == NULL)
426                 return(NULL);
427         return(a->next);
428 }
429
430 const char *
431 dfui_action_get_id(const struct dfui_action *a)
432 {
433         if (a == NULL)
434                 return(NULL);
435         return(a->id);
436 }
437
438 struct dfui_info *
439 dfui_action_get_info(const struct dfui_action *a)
440 {
441         if (a == NULL)
442                 return(NULL);
443         return(a->info);
444 }
445
446 struct dfui_property *
447 dfui_action_property_set(struct dfui_action *a, const char *name, const char *value)
448 {
449         return(dfui_property_set(&a->property_head, name, value));
450 }
451
452 const char *
453 dfui_action_property_get(const struct dfui_action *a, const char *name)
454 {
455         return(dfui_property_get(a->property_head, name));
456 }
457
458 int
459 dfui_action_property_is(const struct dfui_action *a, const char *name, const char *value)
460 {
461         struct dfui_property *h;
462
463         if (a == NULL)
464                 return(0);
465         if ((h = dfui_property_find(a->property_head, name)) == NULL)
466                 return(0);
467         return(!strcmp(h->value, value));
468 }
469
470 /*** FORMS ***/
471
472 struct dfui_form *
473 dfui_form_new(const char *id, struct dfui_info *info)
474 {
475         struct dfui_form *f;
476
477         AURA_MALLOC(f, dfui_form);
478         f->id = aura_strdup(id);
479         f->info = info;
480         f->multiple = 0;
481         f->extensible = 0;
482         f->field_head = NULL;
483         f->action_head = NULL;
484         f->dataset_head = NULL;
485         f->property_head = NULL;
486
487         return(f);
488 };
489
490 /*
491  * Convenience function for creating a form.
492  * This function takes a list of any number of strings.
493  * This list MUST be terminated by a NULL pointer.
494  * The first four strings are the id, name, short description, and long
495  * description of the form.
496  * Each subsequent string determines what the strings following it represent:
497  *    "f": create a field (id, name, short desc, long desc).
498  *    "o": add an option to the last field (value).
499  *    "a": create an action (id, name, short desc, long desc).
500  *    "p": add a property to the last object (name, value).
501  */
502 struct dfui_form *
503 dfui_form_create(const char *id, const char *name,
504                  const char *short_desc, const char *long_desc, ...)
505 {
506 #define DFUI_FORM_CREATE_FORM   0
507 #define DFUI_FORM_CREATE_FIELD  1
508 #define DFUI_FORM_CREATE_ACTION 2
509
510         struct dfui_form *f;
511         struct dfui_info *i;
512         va_list args;
513         int state = DFUI_FORM_CREATE_FORM;
514         char *arg;
515         void *object = NULL;
516         const char *a_id;
517         char *a_name, *a_short_desc, *a_long_desc;
518         
519         i = dfui_info_new(name, short_desc, long_desc);
520         f = dfui_form_new(id, i);
521
522         va_start(args, long_desc);
523         while ((arg = va_arg(args, char *)) != NULL) {
524                 switch (arg[0]) {
525                 case 'f':
526                         a_id = va_arg(args, const char *);
527                         a_name = va_arg(args, char *);
528                         a_short_desc = va_arg(args, char *);
529                         a_long_desc = va_arg(args, char *);
530                         i = dfui_info_new(a_name, a_short_desc, a_long_desc);
531                         object = (void *)dfui_form_field_add(f, a_id, i);
532                         state = DFUI_FORM_CREATE_FIELD;
533                         break;
534                 case 'a':
535                         a_id = va_arg(args, const char *);
536                         a_name = va_arg(args, char *);
537                         a_short_desc = va_arg(args, char *);
538                         a_long_desc = va_arg(args, char *);
539                         i = dfui_info_new(a_name, a_short_desc, a_long_desc);
540                         object = (void *)dfui_form_action_add(f, a_id, i);
541                         state = DFUI_FORM_CREATE_ACTION;
542                         break;
543                 case 'o':
544                         a_name = va_arg(args, char *);
545                         if (state == DFUI_FORM_CREATE_FIELD) {
546                                 dfui_field_option_add(object, a_name);
547                         } else {
548                                 dfui_debug("form_create: can't add option to non-field\n");
549                         }
550                         break;
551                 case 'h':
552                 case 'p':
553                         a_id = va_arg(args, char *);
554                         a_short_desc = va_arg(args, char *);
555
556                         if (state == DFUI_FORM_CREATE_FIELD) {
557                                 dfui_field_property_set(object, a_id, a_short_desc);
558                         } else if (state == DFUI_FORM_CREATE_ACTION) {
559                                 dfui_action_property_set(object, a_id, a_short_desc);
560                         } else if (state == DFUI_FORM_CREATE_FORM) {
561                                 dfui_form_property_set(f, a_id, a_short_desc);
562                         } else {
563                                 dfui_debug("form_create: can't add property in this state\n");
564                         }
565                         break;
566
567                 default:
568                         dfui_debug("form_create: unknown option `%c'\n", arg[0]);
569                         break;
570                 }
571         }
572
573         va_end(args);
574         return(f);
575 }
576
577 void
578 dfui_form_free(struct dfui_form *f)
579 {
580         free(f->id);
581         dfui_info_free(f->info);
582         dfui_fields_free(f->field_head);
583         dfui_actions_free(f->action_head);
584         dfui_datasets_free(f->dataset_head);
585         dfui_properties_free(f->property_head);
586         AURA_FREE(f, dfui_form);
587 }
588
589 struct dfui_field *
590 dfui_form_field_add(struct dfui_form *f, const char *id, struct dfui_info *info)
591 {
592         struct dfui_field *fi;
593
594         if (f == NULL)
595                 return(NULL);
596         fi = dfui_field_new(id, info);
597         fi->next = f->field_head;
598         f->field_head = fi;
599         
600         return(fi);
601 }
602
603 struct dfui_field *
604 dfui_form_field_attach(struct dfui_form *f, struct dfui_field *fi)
605 {
606         if (f == NULL)
607                 return(NULL);
608         fi->next = f->field_head;
609         f->field_head = fi;
610         
611         return(fi);
612 }
613
614 struct dfui_action *
615 dfui_form_action_add(struct dfui_form *f, const char *id, struct dfui_info *info)
616 {
617         struct dfui_action *a;
618
619         if (f == NULL)
620                 return(NULL);
621         a = dfui_action_new(id, info);
622         a->next = f->action_head;
623         f->action_head = a;
624         
625         return(a);
626 }
627
628 struct dfui_action *
629 dfui_form_action_attach(struct dfui_form *f, struct dfui_action *a)
630 {
631         if (f == NULL)
632                 return(NULL);
633         a->next = f->action_head;
634         f->action_head = a;
635         
636         return(a);
637 }
638
639 void
640 dfui_form_dataset_add(struct dfui_form *f, struct dfui_dataset *ds)
641 {
642         if (f == NULL || ds == NULL)
643                 return;
644         ds->next = f->dataset_head;
645         f->dataset_head = ds;
646 }
647
648 struct dfui_dataset *
649 dfui_form_dataset_get_first(const struct dfui_form *f)
650 {
651         if (f == NULL)
652                 return(NULL);
653         return(f->dataset_head);
654 }
655
656 int
657 dfui_form_dataset_count(const struct dfui_form *f)
658 {
659         int n = 0;
660         struct dfui_dataset *ds;
661
662         if (f == NULL)
663                 return(0);
664
665         ds = f->dataset_head;
666         while (ds != NULL) {
667                 n++;
668                 ds = ds->next;
669         }
670
671         return(n);
672 }
673
674 void
675 dfui_form_datasets_free(struct dfui_form *f)
676 {
677         if (f == NULL)
678                 return;
679         dfui_datasets_free(f->dataset_head);
680         f->dataset_head = NULL;
681 }
682
683 struct dfui_field *
684 dfui_form_field_find(const struct dfui_form *f, const char *id)
685 {
686         struct dfui_field *fi;
687
688         if (f == NULL)
689                 return(NULL);
690
691         fi = f->field_head;
692         while (fi != NULL) {
693                 if (!strcmp(id, fi->id))
694                         return(fi);
695                 fi = fi->next;
696         }
697
698         return(NULL);
699 }
700
701 struct dfui_field *
702 dfui_form_field_get_first(const struct dfui_form *f)
703 {
704         if (f == NULL)
705                 return(NULL);
706         return(f->field_head);
707 }
708
709 int
710 dfui_form_field_count(const struct dfui_form *f)
711 {
712         int n = 0;
713         struct dfui_field *fi;
714
715         if (f == NULL)
716                 return(0);
717
718         fi = f->field_head;
719         while (fi != NULL) {
720                 n++;
721                 fi = fi->next;
722         }
723
724         return(n);
725 }
726
727 struct dfui_action *
728 dfui_form_action_find(const struct dfui_form *f, const char *id)
729 {
730         struct dfui_action *a = f->action_head;
731
732         while (a != NULL) {
733                 if (!strcmp(id, a->id))
734                         return(a);
735                 a = a->next;
736         }
737
738         return(NULL);
739 }
740
741 struct dfui_action *
742 dfui_form_action_get_first(const struct dfui_form *f)
743 {
744         if (f == NULL)
745                 return(NULL);
746         return(f->action_head);
747 }
748
749 int
750 dfui_form_action_count(const struct dfui_form *f)
751 {
752         int n = 0;
753         struct dfui_action *a;
754
755         if (f == NULL)
756                 return(0);
757
758         a = f->action_head;
759         while (a != NULL) {
760                 n++;
761                 a = a->next;
762         }
763
764         return(n);
765 }
766
767 struct dfui_property *
768 dfui_form_property_set(struct dfui_form *f, const char *name, const char *value)
769 {
770         return(dfui_property_set(&f->property_head, name, value));
771 }
772
773 const char *
774 dfui_form_property_get(const struct dfui_form *f, const char *name)
775 {
776         return(dfui_property_get(f->property_head, name));
777 }
778
779 int
780 dfui_form_property_is(const struct dfui_form *f, const char *name, const char *value)
781 {
782         struct dfui_property *h;
783
784         if (f == NULL)
785                 return(0);
786         if ((h = dfui_property_find(f->property_head, name)) == NULL)
787                 return(0);
788         return(!strcmp(h->value, value));
789 }
790
791 const char *
792 dfui_form_get_id(const struct dfui_form *f)
793 {
794         if (f == NULL)
795                 return(NULL);   /* XXX ? */
796         return(f->id);
797 }
798
799 struct dfui_info *
800 dfui_form_get_info(const struct dfui_form *f)
801 {
802         if (f == NULL)
803                 return(NULL);
804         return(f->info);
805 }
806
807 void
808 dfui_form_set_multiple(struct dfui_form *f, int multiple)
809 {
810         if (f == NULL)
811                 return;
812         f->multiple = multiple;
813 }
814
815 int
816 dfui_form_is_multiple(const struct dfui_form *f)
817 {
818         if (f == NULL)
819                 return(0);
820         return(f->multiple);
821 }
822
823 void
824 dfui_form_set_extensible(struct dfui_form *f, int extensible)
825 {
826         if (f == NULL)
827                 return;
828         f->extensible = extensible;
829 }
830
831 int
832 dfui_form_is_extensible(const struct dfui_form *f)
833 {
834         if (f == NULL)
835                 return(0);
836         return(f->extensible);
837 }
838
839 /*** CELLDATAS ***/
840
841 struct dfui_celldata *
842 dfui_celldata_new(const char *field_id, const char *value)
843 {
844         struct dfui_celldata *c;
845
846         AURA_MALLOC(c, dfui_celldata);
847         c->field_id = aura_strdup(field_id);
848         c->value = aura_strdup(value);
849
850         return(c);
851 }
852
853 void
854 dfui_celldata_free(struct dfui_celldata *c)
855 {
856         if (c == NULL)
857                 return;
858         free(c->field_id);
859         free(c->value);
860         AURA_FREE(c, dfui_celldata);
861 }
862
863 void
864 dfui_celldatas_free(struct dfui_celldata *head)
865 {
866         struct dfui_celldata *c;
867
868         c = head;
869         while (c != NULL) {
870                 head = c->next;
871                 dfui_celldata_free(c);
872                 c = head;
873         }
874 }
875
876 struct dfui_celldata *
877 dfui_celldata_find(struct dfui_celldata *head, const char *id)
878 {
879         struct dfui_celldata *c;
880
881         c = head;
882         while (c != NULL) {
883                 if (!strcmp(id, c->field_id))
884                         return(c);
885                 c = c->next;
886         }
887
888         return(NULL);
889 }
890
891 struct dfui_celldata *
892 dfui_celldata_get_next(const struct dfui_celldata *cd)
893 {
894         if (cd != NULL) {
895                 return(cd->next);
896         } else {
897                 return(NULL);
898         }
899 }
900
901 const char *
902 dfui_celldata_get_field_id(const struct dfui_celldata *cd)
903 {
904         if (cd != NULL) {
905                 return(cd->field_id);
906         } else {
907                 return(NULL);
908         }
909 }
910
911 const char *
912 dfui_celldata_get_value(const struct dfui_celldata *cd)
913 {
914         if (cd != NULL) {
915                 return(cd->value);
916         } else {
917                 return("");
918         }
919 }
920
921 /*** DATASETS ***/
922
923 struct dfui_dataset *
924 dfui_dataset_new(void)
925 {
926         struct dfui_dataset *ds;
927
928         AURA_MALLOC(ds, dfui_dataset);
929         ds->celldata_head = NULL;
930         ds->next = NULL;
931
932         return(ds);
933 }
934
935 struct dfui_dataset *
936 dfui_dataset_dup(const struct dfui_dataset *ds)
937 {
938         struct dfui_dataset *nds;
939         struct dfui_celldata *cd;
940
941         nds = dfui_dataset_new();
942
943         for (cd = ds->celldata_head; cd != NULL; cd = cd->next) {
944                 dfui_dataset_celldata_add(nds,
945                     cd->field_id, cd->value);
946         }
947
948         return(nds);
949 }
950
951 void
952 dfui_dataset_free(struct dfui_dataset *ds)
953 {
954         dfui_celldatas_free(ds->celldata_head);
955         AURA_FREE(ds, dfui_dataset);
956 }
957
958 void
959 dfui_datasets_free(struct dfui_dataset *head)
960 {
961         struct dfui_dataset *ds;
962
963         ds = head;
964         while (ds != NULL) {
965                 head = ds->next;
966                 dfui_dataset_free(ds);
967                 ds = head;
968         }
969 }
970
971 struct dfui_celldata *
972 dfui_dataset_celldata_add(struct dfui_dataset *ds, const char *field_id, const char *value)
973 {
974         struct dfui_celldata *c;
975
976         if (ds == NULL)
977                 return(NULL);
978
979         c = dfui_celldata_new(field_id, value);
980         c->next = ds->celldata_head;
981         ds->celldata_head = c;
982         
983         return(c);
984 }
985
986 struct dfui_celldata *
987 dfui_dataset_celldata_get_first(const struct dfui_dataset *ds)
988 {
989         if (ds == NULL)
990                 return(NULL);
991         return(ds->celldata_head);
992 }
993
994 struct dfui_celldata *
995 dfui_dataset_celldata_find(const struct dfui_dataset *ds, const char *field_id)
996 {
997         if (ds == NULL)
998                 return(NULL);
999         return(dfui_celldata_find(ds->celldata_head, field_id));
1000 }
1001
1002 struct dfui_dataset *
1003 dfui_dataset_get_next(const struct dfui_dataset *ds)
1004 {
1005         if (ds == NULL)
1006                 return(NULL);
1007         return(ds->next);
1008 }
1009
1010 /*
1011  * Returns the value of the celldata with the given id found in the
1012  * given dataset.  If no such celldata is found, a constant zero-length
1013  * string is returned.  As such, the return value of this function is
1014  * guaranteed to not be NULL and must NEVER be freed after use.
1015  */
1016 const char *
1017 dfui_dataset_get_value(const struct dfui_dataset *ds, const char *id)
1018 {
1019         struct dfui_celldata *cd;
1020
1021         if ((cd = dfui_dataset_celldata_find(ds, id)) != NULL) {
1022                 return(dfui_celldata_get_value(cd));
1023         } else {
1024                 return("");
1025         }
1026 }
1027
1028 /*
1029  * Allocates a string to hold the value of the celldata with the
1030  * given id found in the given dataset.  Even if no such celldata
1031  * is found, an allocated, zero-length string is returned.  As such,
1032  * the return value of this function is guaranteed to not be NULL,
1033  * and must ALWAYS be freed after use.
1034  */
1035 char *
1036 dfui_dataset_dup_value(const struct dfui_dataset *ds, const char *id)
1037 {
1038         return(aura_strdup(dfui_dataset_get_value(ds, id)));
1039 }
1040
1041 /*** RESPONSES ***/
1042
1043 struct dfui_response *
1044 dfui_response_new(const char *form_id, const char *action_id)
1045 {
1046         struct dfui_response *r;
1047                 
1048         AURA_MALLOC(r, dfui_response);
1049         r->form_id = aura_strdup(form_id);
1050         r->action_id = aura_strdup(action_id);
1051         r->dataset_head = NULL;
1052         
1053         return(r);
1054 }
1055
1056 void
1057 dfui_response_free(struct dfui_response *r)
1058 {
1059         free(r->form_id);
1060         free(r->action_id);
1061         dfui_datasets_free(r->dataset_head);
1062         AURA_FREE(r, dfui_response);
1063 }
1064
1065 void
1066 dfui_response_dataset_add(struct dfui_response *r, struct dfui_dataset *ds)
1067 {
1068         if (ds == NULL || r == NULL)
1069                 return;
1070         ds->next = r->dataset_head;
1071         r->dataset_head = ds;
1072 }
1073
1074 struct dfui_dataset *
1075 dfui_response_dataset_get_first(const struct dfui_response *r)
1076 {
1077         if (r == NULL)
1078                 return(NULL);
1079         return(r->dataset_head);
1080 }
1081
1082 int
1083 dfui_response_dataset_count(const struct dfui_response *r)
1084 {
1085         int n = 0;
1086         struct dfui_dataset *ds;
1087
1088         if (r == NULL)
1089                 return(0);
1090
1091         ds = r->dataset_head;
1092         while (ds != NULL) {
1093                 n++;
1094                 ds = ds->next;
1095         }
1096
1097         return(n);
1098 }
1099
1100 const char *
1101 dfui_response_get_form_id(const struct dfui_response *r)
1102 {
1103         if (r == NULL)
1104                 return(NULL);   /* XXX ? */
1105         return(r->form_id);
1106 }
1107
1108 const char *
1109 dfui_response_get_action_id(const struct dfui_response *r)
1110 {
1111         if (r == NULL)
1112                 return(NULL);   /* XXX ? */
1113         return(r->action_id);
1114 }
1115
1116 /* PROGRESS BARS */
1117
1118 struct dfui_progress *
1119 dfui_progress_new(struct dfui_info *info, int amount)
1120 {
1121         struct dfui_progress *pr;
1122
1123         AURA_MALLOC(pr, dfui_progress);
1124         pr->info = info;
1125         pr->amount = amount;
1126         pr->streaming = 0;
1127         pr->msg_line = NULL;
1128
1129         return(pr);
1130 }
1131
1132 void
1133 dfui_progress_free(struct dfui_progress *pr)
1134 {
1135         if (pr == NULL)
1136                 return;
1137         dfui_info_free(pr->info);
1138         if (pr->msg_line != NULL)
1139                 free(pr->msg_line);
1140         AURA_FREE(pr, dfui_progress);
1141 }
1142
1143 struct dfui_info *
1144 dfui_progress_get_info(const struct dfui_progress *pr)
1145 {
1146         if (pr == NULL)
1147                 return(NULL);
1148         return(pr->info);
1149 }
1150
1151 void
1152 dfui_progress_set_amount(struct dfui_progress *pr, int amount)
1153 {
1154         if (pr == NULL)
1155                 return;
1156         pr->amount = amount;
1157 }
1158
1159 int
1160 dfui_progress_get_amount(const struct dfui_progress *pr)
1161 {
1162         if (pr == NULL)
1163                 return(0);
1164         return(pr->amount);
1165 }
1166
1167 void
1168 dfui_progress_set_streaming(struct dfui_progress *pr, int streaming)
1169 {
1170         if (pr == NULL)
1171                 return;
1172         pr->streaming = streaming;
1173 }
1174
1175 int
1176 dfui_progress_get_streaming(const struct dfui_progress *pr)
1177 {
1178         if (pr == NULL)
1179                 return(0);
1180         return(pr->streaming);
1181 }
1182
1183 void
1184 dfui_progress_set_msg_line(struct dfui_progress *pr, const char *msg_line)
1185 {
1186         if (pr == NULL)
1187                 return;
1188         if (pr->msg_line != NULL)
1189                 free(pr->msg_line);
1190         pr->msg_line = aura_strdup(msg_line);
1191 }
1192
1193 const char *
1194 dfui_progress_get_msg_line(const struct dfui_progress *pr)
1195 {
1196         if (pr == NULL)
1197                 return("");
1198         if (pr->msg_line == NULL)
1199                 return("");
1200         return(pr->msg_line);
1201 }