2 * CDE - Common Desktop Environment
4 * Copyright (c) 1993-2012, The Open Group. All rights reserved.
6 * These libraries and programs are free software; you can
7 * redistribute them and/or modify them under the terms of the GNU
8 * Lesser General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option)
12 * These libraries and programs are distributed in the hope that
13 * they will be useful, but WITHOUT ANY WARRANTY; without even the
14 * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU Lesser General Public License for more
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with these librararies and programs; if not, write
20 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21 * Floor, Boston, MA 02110-1301 USA
23 /* $TOG: DataBaseLoad.c /main/9 1998/01/12 16:46:23 cshi $ */
24 /*****************************************************************************
26 * File: DataBaseLoad.c
30 * Description: This file contains the functions which load and parse
31 * the front panel databases.
33 * (c) Copyright 1993, 1994 Hewlett-Packard Company
34 * (c) Copyright 1993, 1994 International Business Machines Corp.
35 * (c) Copyright 1993, 1994 Sun Microsystems, Inc.
36 * (c) Copyright 1993, 1994 Unix System Labs, Inc., a subsidiary of Novell, Inc.
39 ****************************************************************************/
42 #include <X11/Xresource.h> /* XrmQuark */
43 #include <Dt/DtP.h> /* required for DtDirPaths type */
44 #include <Dt/DbReader.h> /* required for DtDbPathId type */
45 #include <Dt/Connect.h> /* required for DtDbPathId type */
47 #include <Dt/Utility.h>
48 #include <Dt/IconFile.h>
50 #include <Dt/UserMsg.h>
53 #include "DataBaseLoad.h"
62 /************************************************************************
64 * panel is the global top of the panel tree structure.
66 * switch is a local that is held until the hierary is built.
68 ************************************************************************/
71 static SwitchData * switch1;
72 static ElementValue * control_element_values = NULL;
73 static Boolean control_element_value_found = False;
77 #define ANY_CONTAINER_TYPE 99
79 static char * TYPES_DIR = "/.dt/types/fp_dynamic/";
80 static char * TYPES_DIR_NO_SLASH = "/.dt/types/fp_dynamic";
81 static char * HOME_DIR = NULL;
82 static char * RM = "/bin/rm";
85 typedef Boolean (*FieldParse)(char *, void **);
86 typedef void (*FieldFree)(void **);
90 FieldParse parse_function;
92 FieldFree free_function;
98 /************************************************************************
100 * Definitions and structure initializations for PANEL record type.
102 ************************************************************************/
104 static char * panel_keywords[] =
113 "DISPLAY_CONTROL_LABELS",
121 static ParseFunction panel_parse_functions[] =
123 { StringToString, NULL, FreeString}, /* Name */
124 { StringToString, NULL, FreeString}, /* Panel Geometry */
125 { StringToBoolean, (void *) True, NULL}, /* Display Handles */
126 { StringToBoolean, (void *) True, NULL}, /* Display Menu */
127 { StringToBoolean, (void *) True, NULL}, /* Display Minimize */
128 { StringToResolution, (void *) 3, NULL}, /* Resolution */
129 { StringToControlBehavior, (void *) 0, NULL}, /* Control Behavior */
130 { StringToBoolean, (void *) False, NULL}, /* Display Control Labels */
131 { StringToBoolean, (void *) True, NULL}, /* Subpanel Unpost */
132 { StringToBoolean, (void *) False, NULL}, /* Locked */
133 { StringToString, NULL, FreeString}, /* Help String */
134 { StringToString, NULL, FreeString}, /* Help Volume */
135 { StringToString, NULL, FreeString}, /* Help Topic */
139 /************************************************************************
141 * Definitions and structure initializations for BOX record type.
143 ************************************************************************/
145 static char * box_keywords[] =
157 static ParseFunction box_parse_functions[] =
159 {StringToString, NULL, FreeString}, /* Name */
160 {StringToString, NULL, FreeString}, /* Container Name */
161 {StringToPositionHints, (void *) 0, NULL}, /* Position Hints */
162 {StringToBoolean, (void *) False, NULL}, /* Locked */
163 {StringToBoolean, (void *) False, NULL}, /* Delete */
164 {StringToString, NULL, FreeString}, /* Help String */
165 {StringToString, NULL, FreeString}, /* Help Volume */
166 {StringToString, NULL, FreeString}, /* Help Topic */
170 /************************************************************************
172 * Definitions and structure initializations for SUBPANEL record type.
174 ************************************************************************/
176 static char * subpanel_keywords[] =
189 static ParseFunction subpanel_parse_functions[] =
191 { StringToString, NULL, FreeString}, /* Name */
192 { StringToString, NULL, FreeString}, /* Container Name */
193 { StringToBoolean, (void *) True, NULL}, /* Control Install */
194 { StringToString, NULL, FreeString}, /* Title */
195 { StringToBoolean, (void *) False, NULL}, /* Locked */
196 { StringToBoolean, (void *) False, NULL}, /* Delete */
197 { StringToString, NULL, FreeString}, /* Help String */
198 { StringToString, NULL, FreeString}, /* Help Volume */
199 { StringToString, NULL, FreeString}, /* Help Topic */
203 /************************************************************************
205 * Definitions and structure initializations for SWITCH record type.
207 ************************************************************************/
209 static char * switch_keywords[] =
223 static ParseFunction switch_parse_functions[] =
225 { StringToString, NULL, FreeString}, /* Name */
226 { StringToString, NULL, FreeString}, /* Container Name */
227 { StringToPositionHints, (void *) 0, NULL}, /* Position Hints */
228 { StringToInt, (void *) 2, NULL}, /* Number of Rows */
229 { StringToBoolean, (void *) False, NULL}, /* Locked */
230 { StringToBoolean, (void *) False, NULL}, /* Delete */
231 { StringToString, NULL, FreeString}, /* Help String */
232 { StringToString, NULL, FreeString}, /* Help Volume */
233 { StringToString, NULL, FreeString}, /* Help Topic */
237 /************************************************************************
239 * Definitions and structure initializations for CONTROL record type.
241 ************************************************************************/
243 static char * control_keywords[] =
270 static ParseFunction control_parse_functions[] =
272 {StringToString, NULL, FreeString}, /* Name */
273 {StringToControlType, (void *)CONTROL_ICON, NULL}, /* Type */
274 {StringToControlContainerType, NULL, NULL}, /* Container Type */
275 {StringToString, NULL, FreeString}, /* Container Name */
276 {StringToPositionHints,(void *) 0, NULL}, /* Position Hints */
277 {StringToString, NULL, FreeString}, /* Image */
278 {StringToString, NULL, FreeString}, /* Altername Image */
279 {StringToString, NULL, FreeString}, /* Label */
280 {StringToAction, NULL, FreeAction}, /* Push Action */
281 {StringToString, NULL, FreeString}, /* Push Animation */
282 {StringToAction, NULL, FreeAction}, /* Drop Action */
283 {StringToString, NULL, FreeString}, /* Drop Animation */
284 {StringToBoolean, (void *) False, NULL}, /* Push Recall */
285 {StringToMonitorType, (void *) MONITOR_NONE,NULL}, /* Monitor Type */
286 {StringToString, NULL, FreeString}, /* Client Name */
287 {StringToGeometry, NULL, FreeGeometry}, /* Client Geometry */
288 {StringToFileName, NULL, FreeString}, /* File Name */
289 {StringToString, NULL, FreeString}, /* Date Format */
290 {StringToBoolean, (void *) False, NULL}, /* Locked */
291 {StringToBoolean, (void *) False, NULL}, /* Delete */
292 {StringToString, NULL, FreeString}, /* Help String */
293 {StringToString, NULL, FreeString}, /* Help Volume */
294 {StringToString, NULL, FreeString}, /* Help Topic */
299 /************************************************************************
301 * Structure definition and initialization for the front panel
304 ************************************************************************/
306 char * entry_types[] =
315 char * control_types[] =
327 char * resolution_types[] =
335 char * monitor_types[] =
342 #define ANIMATION "ANIMATION"
346 char * record_keyword;
348 char ** field_keywords;
349 ParseFunction * parse_functions;
353 static RecordKeywords record_keywords[] =
355 { "PANEL", PANEL_KEYWORD_COUNT,
356 panel_keywords, panel_parse_functions },
358 { "BOX", BOX_KEYWORD_COUNT,
359 box_keywords, box_parse_functions },
361 { "SUBPANEL", SUBPANEL_KEYWORD_COUNT,
362 subpanel_keywords, subpanel_parse_functions },
364 { "SWITCH", SWITCH_KEYWORD_COUNT,
365 switch_keywords, switch_parse_functions },
367 { "CONTROL", CONTROL_KEYWORD_COUNT,
368 control_keywords, control_parse_functions },
372 /************************************************************************
374 * Static and external function definitions
376 ************************************************************************/
379 extern void WmFrontPanelSetBusy (Boolean);
380 extern char * _DtDbGetDataBaseEnv (void);
382 static Boolean PanelParseCB (DtDtsDbField *, DtDbPathId, char *, Boolean);
383 static Boolean BoxParseCB (DtDtsDbField *, DtDbPathId, char *, Boolean);
384 static Boolean SubpanelParseCB (DtDtsDbField *, DtDbPathId, char *, Boolean);
385 static Boolean SwitchParseCB (DtDtsDbField *, DtDbPathId, char *, Boolean);
386 static Boolean ControlParseCB (DtDtsDbField *, DtDbPathId, char *, Boolean);
387 static Boolean AnimationParseCB (DtDtsDbField *, DtDbPathId, char *, Boolean);
388 static Boolean ControlSingleParseCB(DtDtsDbField *, DtDbPathId, char *, Boolean);
389 static void ProcessRecord (DtDtsDbField *, ElementValue *);
390 static void AllocateRecordData (RecordData **, int, int *, int *);
391 static void ReorderByContainerType(RecordData *, int , int);
392 static void ReorderByContainerName(RecordData *, int , int, int);
393 static void ReorderByName(RecordData *, int , int, int);
394 static void ReorderByPosition(RecordData *, int , int, int, int);
395 static void OrderRecord (RecordData *, int, int);
396 static char ** GetNameList (RecordData *, int, int, int, int);
397 static void EliminateUnused (RecordData *, int *, char **, int, int, int, int);
398 static void EliminateDeleted (RecordData *, int *, int, int, int, int, int);
399 static void ResolveDuplicates (RecordData *, int *, int, int, int, int, int);
400 static void InitializeField (ElementValue *, int, ParseFunction *);
401 static void ProcessBox (BoxData *);
402 static int ProcessBoxControl (ControlData *);
403 static void ProcessSubpanel (SubpanelData *);
404 static void ProcessSwitch (SwitchData *);
405 static void ProcessControl (XtPointer, char, ControlData ***, int *, ElementValue *);
406 static void InitializePrimaryControlFields (ElementValue *);
407 static void InitializeSecondaryControlFields (ElementValue *);
408 static void InitializeFileControlFields (ElementValue *, char *);
412 /************************************************************************
414 * Variable and record declarations and initializations to keep track
415 * of the data base info as it is read and to be used as storage for
416 * subsequent parsing and reprocessing.
418 ************************************************************************/
420 static panel_count = 0;
421 static panel_data_count = 0;
422 static RecordData * panel_data = NULL;
424 static box_count = 0;
425 static box_data_count = 0;
426 static RecordData * box_data = NULL;
428 static subpanel_count = 0;
429 static subpanel_data_count = 0;
430 static RecordData * subpanel_data = NULL;
432 static switch_count = 0;
433 static switch_data_count = 0;
434 static RecordData * switch_data = NULL;
436 static control_count = 0;
437 static control_data_count = 0;
438 static RecordData * control_data = NULL;
442 static DtDbConverter panel_converter[] = { (DtDbConverter) PanelParseCB,
444 static DtDbConverter box_converter[] = { (DtDbConverter) BoxParseCB,
446 static DtDbConverter subpanel_converter[] = { (DtDbConverter) SubpanelParseCB,
448 static DtDbConverter switch_converter[] = { (DtDbConverter) SwitchParseCB,
450 static DtDbConverter control_converter[] = { (DtDbConverter) ControlParseCB,
452 static DtDbConverter animation_converter[] ={ (DtDbConverter) AnimationParseCB,
455 static DtDbRecordDesc record_descriptor[] =
457 { "PANEL", PANEL_KEYWORD_COUNT, panel_converter },
458 { "BOX", BOX_KEYWORD_COUNT, box_converter },
459 { "SUBPANEL", SUBPANEL_KEYWORD_COUNT, subpanel_converter },
460 { "SWITCH", SWITCH_KEYWORD_COUNT, switch_converter },
461 { "CONTROL", CONTROL_KEYWORD_COUNT, control_converter },
462 { "ANIMATION", DTUNLIMITEDFIELDS, animation_converter }
465 static DtDbConverter control_single_converter[] =
466 { (DtDbConverter) ControlSingleParseCB, NULL};
468 static DtDbRecordDesc control_record_descriptor[] =
470 { "CONTROL", CONTROL_KEYWORD_COUNT, control_single_converter },
471 { "ANIMATION", DTUNLIMITEDFIELDS, animation_converter }
478 /************************************************************************
480 * FrontPanelReadDatabases
481 * Read in the front panel database, parse out each line, build
482 * the internal data structures that are then used to create the
483 * visual representation.
485 * Processing occurs in a series of steps:
487 * 1. Read in all of the database records and copy the unparsed
488 * string information into a structure.
489 * a. Group the records according to type.
490 * b. Group the records according to container.
491 * c. Ensure the original read order is maintained to process
494 * This step occurs out of the callback for each of the component
497 * 2. Eliminate the unused component definitions by working top-down
498 * throught the lists. Select the PANEL and SWITCH definition
499 * to be used at this time.
501 * 3. Eliminate overridden components by either selecting the first
502 * locked definition or if none are locked, selecting the last
505 * 4. Reorder the component groups according to the position hints
507 * 5. Build hierarchical data structure from record sets, top-down.
508 * Fully parse each record as the structure is built.
513 ************************************************************************/
516 FrontPanelReadDatabases (void)
521 char * new_search_paths;
522 struct passwd * pw_info;
525 struct stat stat_info;
532 DtDirPaths * dir_paths;
535 panel.animation_data = NULL;
536 panel.animation_count = 0;
540 /* Before reading the databases, add the front panel dynamic */
541 /* directory to the search path. */
543 search_paths = _DtDbGetDataBaseEnv();
545 if ((HOME_DIR = (char *) getenv ("HOME")) == NULL)
547 pw_info = getpwuid (getuid());
548 HOME_DIR = pw_info->pw_dir;
551 HOME_DIR = XtNewString (HOME_DIR);
554 XtMalloc (strlen ("DTDATABASESEARCHPATH") + strlen (HOME_DIR) +
555 strlen (TYPES_DIR_NO_SLASH) + strlen (search_paths) + 3);
556 sprintf (new_search_paths, "%s=%s%s,%s",
557 "DTDATABASESEARCHPATH", HOME_DIR, TYPES_DIR_NO_SLASH, search_paths);
558 putenv (new_search_paths);
560 XtFree (search_paths);
563 /* See if the fp_dynamic directory exists. If not, create it */
565 dynamic_dir = XtMalloc (strlen (HOME_DIR) + strlen (TYPES_DIR) + 3);
566 sprintf (dynamic_dir, "%s%s", HOME_DIR, TYPES_DIR);
568 if (lstat (dynamic_dir, &stat_info) != 0)
569 if ((fd=mkdir (dynamic_dir, S_IRWXU | S_IRGRP | S_IROTH |
570 S_IXGRP | S_IXOTH)) != 0)
575 XtFree ((char *) dynamic_dir);
578 /* Read the database and do the initial set of processing on */
579 /* the file based information. This work occurs within the */
580 /* callback function referenced in the data read call. */
582 dir_paths = _DtGetDatabaseDirPaths();
584 #ifdef DT_PERFORMANCE
585 _DtPerfChkpntMsgSend("Begin Front panel database read");
588 _DtDbRead (dir_paths, FILE_TYPE_SUFFIX, record_descriptor, 6);
590 #ifdef DT_PERFORMANCE
591 _DtPerfChkpntMsgSend("End Front panel database read");
594 if (panel_count == 0)
596 _DtFreeDatabaseDirPaths (dir_paths);
600 /* Once all of the PANEL records have been read in, select the panel */
601 /* record that is to be used to build the front panel. */
603 /* This selection is done by first scanning the list to find a LOCKED */
604 /* panel. The first one found is selected. If none are found, the */
605 /* last panel read is selectd. */
607 for (i = panel_count - 1; i > 0; i--)
609 if ((Boolean)(panel_data[i].element_values[PANEL_LOCKED].parsed_value))
613 panel.element_values = panel_data[i].element_values;
616 /* Parse out additional panel element values */
618 InitializeField (panel.element_values, PANEL_GEOMETRY, panel_parse_functions);
619 InitializeField (panel.element_values, PANEL_DISPLAY_HANDLES, panel_parse_functions);
620 InitializeField (panel.element_values, PANEL_DISPLAY_MENU, panel_parse_functions);
621 InitializeField (panel.element_values, PANEL_DISPLAY_MINIMIZE, panel_parse_functions);
622 InitializeField (panel.element_values, PANEL_RESOLUTION, panel_parse_functions);
623 InitializeField (panel.element_values, PANEL_CONTROL_BEHAVIOR, panel_parse_functions);
624 InitializeField (panel.element_values, PANEL_DISPLAY_CONTROL_LABELS, panel_parse_functions);
625 InitializeField (panel.element_values, PANEL_SUBPANEL_UNPOST, panel_parse_functions);
626 InitializeField (panel.element_values, PANEL_HELP_STRING, panel_parse_functions);
627 InitializeField (panel.element_values, PANEL_HELP_TOPIC, panel_parse_functions);
628 InitializeField (panel.element_values, PANEL_HELP_VOLUME, panel_parse_functions);
630 XtFree ((char *) panel_data);
633 /* Eliminate the records within the other component types that */
634 /* are not part of this selected panel. */
636 /* This elimination occurs top down because boxes have to be */
637 /* removed before controls can be removed... */
639 name_list = (char **) XtMalloc (sizeof (char **) * 2);
640 name_list[0] = panel.element_values[PANEL_NAME].parsed_value;
642 EliminateUnused (box_data, &box_count, name_list, BOX_CONTAINER_NAME,
643 ANY_CONTAINER_TYPE, PANEL, BOX);
644 XtFree ((char *) name_list);
646 /* Remove entries that have the deleted keyword set to True unless */
647 /* it is a locked file. */
648 EliminateDeleted (box_data, &box_count, BOX_CONTAINER_NAME,
649 BOX_NAME, BOX, BOX_DELETE, BOX_LOCKED);
650 EliminateDeleted (switch_data, &switch_count, SWITCH_CONTAINER_NAME,
651 SWITCH_NAME, SWITCH, SWITCH_DELETE, SWITCH_LOCKED);
652 EliminateDeleted (subpanel_data, &subpanel_count, SUBPANEL_CONTAINER_NAME,
653 SUBPANEL_NAME, SUBPANEL, SUBPANEL_DELETE, SUBPANEL_LOCKED);
654 EliminateDeleted (control_data, &control_count, CONTROL_CONTAINER_NAME,
655 CONTROL_NAME, CONTROL, CONTROL_DELETE, CONTROL_LOCKED);
657 name_list = GetNameList (box_data, box_count,
658 BOX_NAME, ANY_CONTAINER_TYPE, 0);
660 EliminateUnused(switch_data, &switch_count, name_list,
661 SWITCH_CONTAINER_NAME, ANY_CONTAINER_TYPE,
664 EliminateUnused(control_data, &control_count, name_list,
665 CONTROL_CONTAINER_NAME, CONTROL_CONTAINER_TYPE,
668 XtFree ((char *) name_list);
671 /* Once the elimination of superfluous switch definitions is complete, */
672 /* make the selection of the single Switch. This makes the elimination */
673 /* of the switch based controls efficient. */
675 /* This selection is done by first scanning the list to find a LOCKED */
676 /* switch. The first one found is selected. If none are found, the */
677 /* last switch read is selected. */
679 if (switch_count != 0) {
680 for (i = switch_count - 1; i > 0; i--)
682 if ((Boolean)(switch_data[i].element_values[SWITCH_LOCKED].parsed_value))
686 switch1 = (SwitchData *) XtMalloc (sizeof (SwitchData));
687 switch1->element_values = switch_data[i].element_values;
688 switch1->control_data = NULL;
689 switch1->control_data_count = 0;
691 switch1->buttons = NULL;
692 switch1->atom_names = NULL;
693 switch1->switch_names = NULL;
694 switch1->switch_count = 0;
695 switch1->active_switch = 0;
696 switch1->popup_data = NULL;
699 /* Parse the remaining database values for the switch */
701 InitializeField (switch1->element_values, SWITCH_POSITION_HINTS, switch_parse_functions);
702 InitializeField (switch1->element_values, SWITCH_NUMBER_OF_ROWS, switch_parse_functions);
703 InitializeField (switch1->element_values, SWITCH_HELP_STRING, switch_parse_functions);
704 InitializeField (switch1->element_values, SWITCH_HELP_TOPIC, switch_parse_functions);
705 InitializeField (switch1->element_values, SWITCH_HELP_STRING, switch_parse_functions);
708 XtFree ((char *) switch_data);
711 /* Continue the elimination of unused records */
713 name_list = (char **) XtMalloc (sizeof (char **) * 2);
714 if (switch_count != 0)
715 name_list[0] = switch1->element_values[SWITCH_NAME].parsed_value;
719 EliminateUnused (control_data, &control_count, name_list,
720 CONTROL_CONTAINER_NAME, CONTROL_CONTAINER_TYPE,
722 XtFree ((char *)name_list);
724 name_list = GetNameList (control_data, control_count,
725 CONTROL_NAME, CONTROL_CONTAINER_TYPE, BOX);
727 EliminateUnused (subpanel_data, &subpanel_count, name_list,
728 SUBPANEL_CONTAINER_NAME, ANY_CONTAINER_TYPE,
730 XtFree ((char *)name_list);
732 name_list = GetNameList (subpanel_data, subpanel_count,
733 SUBPANEL_NAME, ANY_CONTAINER_TYPE, SUBPANEL);
735 EliminateUnused (control_data, &control_count, name_list,
736 CONTROL_CONTAINER_NAME, CONTROL_CONTAINER_TYPE,
739 XtFree ((char *)name_list);
742 /* The record types of CONTROL, SUBPANEL and BOX still have need */
743 /* several steps of processing. */
745 ReorderByContainerType(control_data, control_count, CONTROL_CONTAINER_TYPE);
747 ReorderByContainerName(control_data, control_count, CONTROL_CONTAINER_NAME,
748 CONTROL_CONTAINER_TYPE);
750 ReorderByName(box_data, box_count, BOX_NAME, BOX_CONTAINER_NAME);
752 ReorderByName(control_data, control_count, CONTROL_NAME,
753 CONTROL_CONTAINER_NAME);
756 for (i = 0; i < control_count; i++) {
757 printf("control %s, %d, %s\n",
758 control_data[i].element_values[CONTROL_CONTAINER_NAME].parsed_value,
759 control_data[i].element_values[CONTROL_CONTAINER_TYPE].parsed_value,
760 control_data[i].element_values[CONTROL_NAME].parsed_value);
765 /* Reprocess each of these groups to eliminate overridden */
766 /* components. If a component is locked, use the first lock */
767 /* encountered. Otherwise, use the last component read. */
769 ResolveDuplicates (box_data, &box_count, BOX_NAME,
770 ANY_CONTAINER_TYPE, BOX_CONTAINER_NAME,
772 ResolveDuplicates (subpanel_data, &subpanel_count, SUBPANEL_NAME,
773 ANY_CONTAINER_TYPE, SUBPANEL_CONTAINER_NAME,
774 SUBPANEL_LOCKED, SUBPANEL);
775 ResolveDuplicates (control_data, &control_count, CONTROL_NAME,
776 CONTROL_CONTAINER_TYPE, CONTROL_CONTAINER_NAME,
777 CONTROL_LOCKED, CONTROL);
779 /* Now that the elimination has been completed, initialize the */
780 /* remaining values for each of the components. */
782 for (i = 0; i < box_count; i++)
784 InitializeField (box_data[i].element_values,
785 BOX_POSITION_HINTS, box_parse_functions);
786 InitializeField (box_data[i].element_values,
787 BOX_HELP_STRING, box_parse_functions);
788 InitializeField (box_data[i].element_values,
789 BOX_HELP_TOPIC, box_parse_functions);
790 InitializeField (box_data[i].element_values,
791 BOX_HELP_VOLUME, box_parse_functions);
794 for (i = 0; i < subpanel_count; i++)
796 InitializeField (subpanel_data[i].element_values,
797 SUBPANEL_CONTROL_INSTALL, subpanel_parse_functions);
798 InitializeField (subpanel_data[i].element_values,
799 SUBPANEL_TITLE, subpanel_parse_functions);
800 InitializeField (subpanel_data[i].element_values,
801 SUBPANEL_HELP_STRING, subpanel_parse_functions);
802 InitializeField (subpanel_data[i].element_values,
803 SUBPANEL_HELP_TOPIC, subpanel_parse_functions);
804 InitializeField (subpanel_data[i].element_values,
805 SUBPANEL_HELP_VOLUME, subpanel_parse_functions);
808 for (i = 0; i < control_count; i++)
810 InitializeSecondaryControlFields (control_data[i].element_values);
811 InitializeFileControlFields (control_data[i].element_values, NULL);
815 for (i = 0; i < box_count; i++) {
816 printf("box %d = %s\n",
817 box_data[i].element_values[BOX_POSITION_HINTS].parsed_value,
818 box_data[i].element_values[BOX_NAME].parsed_value);
821 for (i = 0; i < subpanel_count; i++) {
822 printf("subpanel = %s\n",
823 subpanel_data[i].element_values[SUBPANEL_NAME].parsed_value);
826 for (i = 0; i < control_count; i++) {
827 printf("control %d = %s\n",
828 control_data[i].element_values[CONTROL_POSITION_HINTS].parsed_value,
829 control_data[i].element_values[CONTROL_NAME].parsed_value);
833 /* Reorder subgroups according to position hints. */
835 ReorderByPosition (box_data, box_count, BOX_POSITION_HINTS,
836 ANY_CONTAINER_TYPE, BOX_CONTAINER_NAME);
837 ReorderByPosition (control_data, control_count, CONTROL_POSITION_HINTS,
838 CONTROL_CONTAINER_TYPE, CONTROL_CONTAINER_NAME);
841 printf("**************************************************************\n\n");
843 for (i = 0; i < box_count; i++) {
844 printf("box %d = %s\n", (int)
845 box_data[i].element_values[BOX_POSITION_HINTS].parsed_value,
846 box_data[i].element_values[BOX_NAME].parsed_value);
849 for (i = 0; i < control_count; i++) {
850 printf("control %d = %s\n", (int)
851 control_data[i].element_values[CONTROL_POSITION_HINTS].parsed_value,
852 control_data[i].element_values[CONTROL_NAME].parsed_value);
857 /* Build hierarchical data structure from record sets, top-down. */
858 /* Fully parse each record as the structure is built. */
860 panel.box_data = (BoxData **) XtMalloc (sizeof (BoxData *) * box_count);
861 panel.box_data_count = box_count;
863 for (i = 0; i < box_count; i++)
867 panel.box_data[i] = (BoxData *) XtMalloc (sizeof (BoxData));
868 box = panel.box_data[i];
870 box->element_values = box_data[i].element_values;
871 box->control_data = NULL;
872 box->control_data_count = 0;
874 box->left_arrow_form = NULL;
875 box->left_control_form = NULL;
876 box->right_arrow_form = NULL;
877 box->right_control_form = NULL;
878 box->switch_data = NULL;
879 box->switch_form = NULL;
880 box->switch_edit = NULL;
881 box->subpanel_count = 0;
884 if (switch_count != 0 &&
885 strcmp ((char *) box->element_values[BOX_NAME].parsed_value,
886 (char *) switch1->element_values[SWITCH_CONTAINER_NAME].parsed_value) == 0)
888 box->switch_data = switch1;
889 switch1->box_data = box;
890 ProcessSwitch (box->switch_data);
894 /* Call a function to process each box, allocating the control */
895 /* data structures needed for them and calling functions to */
896 /* further process each control. */
901 XtFree ((char *) box_data);
902 _DtFreeDatabaseDirPaths (dir_paths);
910 /************************************************************************
913 * Allocate a structure to contain the Panel record returned by
914 * the database read code and copy the record information into the
917 ************************************************************************/
920 PanelParseCB (DtDtsDbField * fields,
926 AllocateRecordData (&panel_data,
927 sizeof (ElementValue) * PANEL_KEYWORD_COUNT,
928 &panel_data_count, &panel_count);
930 ProcessRecord (fields, (ElementValue *)
931 panel_data[panel_count - 1].element_values);
933 InitializeField (panel_data[panel_count - 1].element_values,
934 PANEL_NAME, panel_parse_functions);
935 InitializeField (panel_data[panel_count - 1].element_values,
936 PANEL_LOCKED, panel_parse_functions);
944 /************************************************************************
947 * Allocate a structure to contain the Box record returned by
948 * the database read code and copy the record information into the
951 ************************************************************************/
954 BoxParseCB (DtDtsDbField * fields,
961 AllocateRecordData (&box_data,
962 sizeof (ElementValue) * BOX_KEYWORD_COUNT,
963 &box_data_count, &box_count);
965 ProcessRecord (fields, box_data[box_count - 1].element_values);
967 InitializeField (box_data[box_count - 1].element_values,
968 BOX_NAME, box_parse_functions);
969 InitializeField (box_data[box_count - 1].element_values,
970 BOX_CONTAINER_NAME, box_parse_functions);
971 InitializeField (box_data[box_count - 1].element_values,
972 BOX_LOCKED, box_parse_functions);
973 InitializeField (box_data[box_count - 1].element_values,
974 BOX_DELETE, box_parse_functions);
976 OrderRecord (box_data, box_count, BOX_CONTAINER_NAME);
984 /************************************************************************
987 * Allocate a structure to contain the Subpanel record returned by
988 * the database read code and copy the record information into the
991 ************************************************************************/
994 SubpanelParseCB (DtDtsDbField * fields,
1000 AllocateRecordData (&subpanel_data,
1001 sizeof (ElementValue) * SUBPANEL_KEYWORD_COUNT,
1002 &subpanel_data_count, &subpanel_count);
1004 ProcessRecord (fields, subpanel_data[subpanel_count - 1].element_values);
1006 InitializeField (subpanel_data[subpanel_count - 1].element_values,
1007 SUBPANEL_NAME, subpanel_parse_functions);
1008 InitializeField (subpanel_data[subpanel_count - 1].element_values,
1009 SUBPANEL_CONTAINER_NAME, subpanel_parse_functions);
1010 InitializeField (subpanel_data[subpanel_count - 1].element_values,
1011 SUBPANEL_LOCKED, subpanel_parse_functions);
1012 InitializeField (subpanel_data[subpanel_count - 1].element_values,
1013 SUBPANEL_DELETE, subpanel_parse_functions);
1015 OrderRecord (subpanel_data, subpanel_count, SUBPANEL_CONTAINER_NAME);
1023 /************************************************************************
1026 * Allocate a structure to contain the Switch record returned by
1027 * the database read code and copy the record information into the
1030 ************************************************************************/
1033 SwitchParseCB (DtDtsDbField * fields,
1039 AllocateRecordData (&switch_data,
1040 sizeof (ElementValue) * SWITCH_KEYWORD_COUNT,
1041 &switch_data_count, &switch_count);
1043 ProcessRecord (fields, switch_data[switch_count - 1].element_values);
1045 InitializeField (switch_data[switch_count - 1].element_values,
1046 SWITCH_NAME, switch_parse_functions);
1047 InitializeField (switch_data[switch_count - 1].element_values,
1048 SWITCH_CONTAINER_NAME, switch_parse_functions);
1049 InitializeField (switch_data[switch_count - 1].element_values,
1050 SWITCH_LOCKED, switch_parse_functions);
1051 InitializeField (switch_data[switch_count - 1].element_values,
1052 SWITCH_DELETE, switch_parse_functions);
1054 OrderRecord (switch_data, switch_count, SWITCH_CONTAINER_NAME);
1061 /************************************************************************
1064 * Allocate a structure to contain the Control record returned by
1065 * the database read code and copy the record information into the
1068 ************************************************************************/
1071 ControlParseCB (DtDtsDbField * fields,
1077 AllocateRecordData (&control_data,
1078 sizeof (ElementValue) * CONTROL_KEYWORD_COUNT,
1079 &control_data_count, &control_count);
1081 ProcessRecord (fields, control_data[control_count - 1].element_values);
1083 InitializePrimaryControlFields
1084 (control_data[control_count - 1].element_values);
1086 OrderRecord (control_data, control_count, CONTROL_CONTAINER_NAME);
1094 /************************************************************************
1097 * Allocate a structure to contain the Animation records returned by
1098 * the database read code and copy the record information into the
1101 ************************************************************************/
1104 AnimationParseCB (DtDtsDbField * fields,
1110 unsigned char *string, *source, *head_ptr;
1113 int count = panel.animation_count;
1114 int field_count = 0;
1117 XrmQuark animation_quark = XrmStringToQuark(ANIMATION);
1119 panel.animation_data = (AnimationData *)
1120 XtRealloc ((char *) panel.animation_data,
1121 sizeof (AnimationData) * (count + 1));
1123 panel.animation_data[count].name = strdup(fields[0].fieldValue);
1126 for (i = 1; fields[i].fieldName != NULL; i++)
1128 if (fields[i].fieldName == animation_quark)
1132 panel.animation_data[count].item_count = field_count;
1134 panel.animation_data[count].items = (AnimationItem *)
1135 XtMalloc(sizeof(AnimationItem) * field_count);
1137 for (i = 0; i < field_count; i++)
1139 if (fields[i+1].fieldName == animation_quark)
1142 (unsigned char *) strdup((char *)fields[i+1].fieldValue);
1144 if ((string = _DtWmParseNextTokenC(&source, False)) != NULL)
1146 panel.animation_data[count].items[i].image_name =
1147 strdup((char *) string);
1148 if ((string = _DtWmParseNextTokenC(&source, False)) != NULL)
1150 StringToInt((char *)string, &val_rtn);
1151 panel.animation_data[count].items[i].delay = (int) val_rtn;
1155 panel.animation_data[count].items[i].delay = 0;
1159 free((char *)head_ptr);
1163 panel.animation_count++;
1170 /************************************************************************
1172 * ControlSingleParseCB
1173 * Allocate a structure to contain the Control record returned by
1174 * the database read code and copy the record information into the
1177 ************************************************************************/
1180 ControlSingleParseCB (DtDtsDbField * fields,
1186 if (control_element_value_found) return;
1188 control_element_values = (ElementValue *) XtMalloc (sizeof(ElementValue) *
1189 CONTROL_KEYWORD_COUNT);
1190 control_element_value_found = True;
1192 ProcessRecord (fields, control_element_values);
1194 InitializeControlFields(control_element_values, NULL);
1202 /************************************************************************
1205 * Extract the fields of a returned record and put them into an
1206 * allocated structure for latter processing.
1208 ************************************************************************/
1211 ProcessRecord (DtDtsDbField * fields,
1212 ElementValue * element_values)
1219 char ** field_keywords;
1222 /* Find the position in the record structure for the value of */
1223 /* the entry keyword contained in the first position of the */
1226 for (entry = 0; entry < TOTAL_ENTRY_COUNT; entry++)
1228 if (fields[0].fieldName == XrmStringToQuark(record_keywords[entry].record_keyword))
1230 keyword_count = record_keywords[entry].keyword_count;
1231 field_keywords = record_keywords[entry].field_keywords;
1237 /* Initialize the element_values array */
1239 for (i = 0; i < keyword_count; i++)
1241 (element_values + i)->use_default = True;
1242 (element_values + i)->string_value = NULL;
1243 (element_values + i)->parsed_value = NULL;
1247 /* Loop through each read in keyword value pair, comparing it */
1248 /* to the keywords for this record type and when found, enter */
1249 /* it into the element values array for the component. */
1251 for (i = 0; fields[i].fieldName != NULL; i++)
1253 XrmQuark field1 = fields[i].fieldName;
1254 char * field2 = fields[i].fieldValue;
1257 /* Search the field_keywords list and when the keyword is found */
1258 /* make a copy of field2 and place in its position. */
1260 for (j = 0; j < keyword_count; j++)
1262 if (field1 == XrmStringToQuark(field_keywords[j]))
1264 (element_values + j)->use_default = False;
1265 (element_values + j)->string_value = strdup (field2);
1270 if (j == keyword_count)
1271 _DtSimpleError (panel.app_name, DtWarning, NULL,
1272 "Invalid keyword -- %s", XrmQuarkToString(field1));
1279 /************************************************************************
1281 * AllocateRecordData
1282 * Allocate a structure to contain the values for a data base record
1283 * and stuff it in an array for latter processing. Do all of this
1284 * by indirection so that multiple record types can be handled.
1286 ************************************************************************/
1289 AllocateRecordData (RecordData ** record_data,
1291 int * record_data_count,
1295 if (*record_count >= *record_data_count)
1297 *record_data_count += 10;
1298 *record_data = (RecordData *)
1299 XtRealloc ((char *) *record_data,
1300 sizeof (RecordData *) * (*record_data_count));
1303 (*record_data)[*record_count].element_values =
1304 (ElementValue *) XtMalloc (record_size);
1312 /************************************************************************
1315 * Compare the value in the last element values struture referenced
1316 * by value_define to previous element values. Move the element
1317 * value structure to a new position defined by the comparison
1318 * value being equal or greater the previous position and less
1319 * than the next position
1321 * The function works on string data.
1323 ************************************************************************/
1326 OrderRecord (RecordData * record_data,
1334 char * position_value;
1335 char * compare_value;
1336 ElementValue * element_values;
1339 /* If this is the first record, it is already in position */
1341 if (record_count == 1)
1345 /* Extract the comparison value and loop backward through the */
1346 /* record_data to find the correct */
1348 element_values = record_data[record_count - 1].element_values;
1349 position_value = element_values[value_define].parsed_value;
1351 for (new_loc = record_count - 2; new_loc >= 0; new_loc--)
1354 record_data[new_loc].element_values[value_define].parsed_value;
1356 if (strcmp (position_value, compare_value) >= 0)
1359 record_data[new_loc + 1].element_values =
1360 record_data[new_loc].element_values;
1365 /* If any values have been moved, place the position value into */
1366 /* the vacated spot. */
1368 if (new_loc != record_count - 2)
1369 record_data[new_loc + 1].element_values = element_values;
1375 /************************************************************************
1378 * Swap element value records based on positions.
1380 ************************************************************************/
1383 SwapEntries (RecordData * rec_data,
1389 ElementValue * temp_value;
1391 temp_value = rec_data[i].element_values;
1392 rec_data[i].element_values = rec_data[j].element_values;
1393 rec_data[j].element_values = temp_value;
1399 /************************************************************************
1402 * Reorder the records according to element index. This routine
1403 * performs a quick sort. Positions that are equal will retain current
1406 ************************************************************************/
1410 QuickSort(RecordData * rec_data,
1421 SwapEntries(rec_data, left, (left + right)/2);
1425 if (container == BOX && elem_index == BOX_POSITION_HINTS ||
1426 (container == CONTROL && elem_index == CONTROL_POSITION_HINTS))
1428 for (i = left + 1; i <= right; i++)
1429 if (rec_data[i].element_values[elem_index].parsed_value <
1430 rec_data[left].element_values[elem_index].parsed_value)
1431 SwapEntries(rec_data, ++last, i);
1435 for (i = left + 1; i <= right; i++)
1436 if (strcmp(rec_data[i].element_values[elem_index].parsed_value,
1437 rec_data[left].element_values[elem_index].parsed_value) < 0)
1438 SwapEntries(rec_data, ++last, i);
1441 SwapEntries(rec_data, left, last);
1443 QuickSort(rec_data, left, last - 1, elem_index, container);
1444 QuickSort(rec_data, last + 1, right, elem_index, container);
1446 #endif /* NOT_DEF */
1451 /************************************************************************
1454 * Reorder the records according to element index. This routine
1455 * performs a bubble sort. Positions that are equal will retain current
1458 ************************************************************************/
1461 BubbleSort (RecordData * rec_data,
1469 Boolean is_string = False;
1474 if (elem_index == CONTROL_CONTAINER_NAME ||
1475 elem_index == CONTROL_NAME)
1481 for (j = start; j < bound; j++)
1485 str1 = (char *)rec_data[j].element_values[elem_index].parsed_value;
1486 str2 = (char *)rec_data[j+1].element_values[elem_index].parsed_value;
1487 if (strcmp(str1, str2) > 0)
1489 SwapEntries(rec_data, j, j+1);
1495 if ((int) rec_data[j].element_values[elem_index].parsed_value >
1496 (int) rec_data[j+1].element_values[elem_index].parsed_value)
1498 SwapEntries(rec_data, j, j+1);
1510 /************************************************************************
1513 * Reverse order of the records. This routine reverses the order of
1514 * the records so that user records that have the same positioning
1515 * will get a higher presidence.
1518 ************************************************************************/
1521 ReversePositions (RecordData * rec_data,
1529 for (i = start, j = end; i < j; i++, j--)
1531 SwapEntries(rec_data, i, j);
1538 /************************************************************************
1540 * ReorderByContainerName
1541 * Reorder the records according to container name. This will be done
1542 * using a quick sort. Container type order must be retained. Matchinng
1543 * names will retain current ordering.
1545 *************************************************************************/
1548 ReorderByContainerName (RecordData * rec_data,
1554 int i = 0, start = 0;
1557 while (i < rec_count)
1560 (rec_data[start].element_values[elem_type].parsed_value);
1561 while ((int)(rec_data[i].element_values[elem_type].parsed_value) ==
1565 if (rec_count == i) break;
1568 BubbleSort(rec_data, start, i - 1, name);
1576 /************************************************************************
1579 * Reorder the records according to names. This will be done
1580 * using a quick sort. Container name order must be retained.
1581 * Matching names will retain current order.
1583 *************************************************************************/
1586 ReorderByName (RecordData * rec_data,
1592 int i = 0, start = 0;
1595 while (i < rec_count)
1597 cont_name = (char *)
1598 (rec_data[start].element_values[elem_type].parsed_value);
1599 while (strcmp((char *)rec_data[i].element_values[elem_type].parsed_value,
1603 if (rec_count == i) break;
1606 BubbleSort(rec_data, start, i - 1, name);
1614 /************************************************************************
1617 * Reorder the records according to position_hints. This will be done
1618 * using a quick sort. Positions that are equal will retain current
1620 *************************************************************************/
1623 ReorderByPosition(RecordData *rec_data,
1630 int i = 0, start = 0;
1632 char *container_name;
1634 ReversePositions(rec_data, 0, rec_count - 1);
1636 while (i < rec_count)
1638 container_name = (char *)
1639 (rec_data[start].element_values[cont_name].parsed_value);
1641 if (cont_type == ANY_CONTAINER_TYPE)
1643 while (strcmp((char *)
1644 rec_data[i].element_values[cont_name].parsed_value,
1645 container_name) == 0)
1648 if (rec_count == i) break;
1653 container_type = (int)
1654 (rec_data[start].element_values[cont_type].parsed_value);
1655 while (((int)rec_data[i].element_values[cont_type].parsed_value ==
1658 rec_data[i].element_values[cont_name].parsed_value,
1659 container_name) == 0))
1662 if (rec_count == i) break;
1666 BubbleSort(rec_data, start, i - 1, pos_hints);
1675 /************************************************************************
1677 * ReorderByContainerType
1678 * Reorder the records according to container type. This will be done
1679 * using a bubble sort. Container types that are match must retain
1680 * current positioning.
1682 *************************************************************************/
1685 ReorderByContainerType (RecordData * rec_data,
1690 BubbleSort(rec_data, 0, rec_count - 1, container_type);
1696 /************************************************************************
1700 ************************************************************************/
1703 RemoveEntry (RecordData * record_data,
1710 for (i = 0; i < record_descriptor[record_type].maxFields; i++)
1712 if (record_keywords[record_type].parse_functions[i].free_function
1714 record_data->element_values[i].parsed_value != NULL &&
1715 record_data->element_values[i].use_default == False)
1717 (*(record_keywords[record_type].parse_functions[i].free_function))
1718 (&(record_data->element_values[i].parsed_value));
1721 if (record_data->element_values[i].use_default == False &&
1722 record_data->element_values[i].string_value != NULL)
1723 free(record_data->element_values[i].string_value);
1726 XtFree((char *)record_data->element_values);
1732 /************************************************************************
1735 * Given a container type and the indicies of the records to be deleted,
1736 * delete any components which are within the specified container type
1739 ************************************************************************/
1742 EliminateEntries (RecordData * record_data,
1753 if (start > end) return;
1755 for (j = start; j <= end; j++)
1757 RemoveEntry(&(record_data[j]), record_type);
1760 if (end + 1 < *record_count)
1762 memmove((void *) &record_data[start], (void *) &record_data[end+1],
1763 (size_t) ((*record_count - end) * sizeof(RecordData)));
1767 *i += (end - start) + 1;
1768 *count = *record_count -= (end - start) + 1;
1774 /************************************************************************
1777 * Reprocess each group to eliminate overridden components.
1778 * If a component is locked, use the first lock encountered.
1779 * Otherwise, use the last component read.
1781 ************************************************************************/
1784 ResolveDuplicates (RecordData * record_data,
1793 int i, start_index, lock_index, last_index;
1794 ElementValue * element_values;
1796 char *cont_name, *record_name;
1797 int count = *record_count;
1802 /* Go through the array of records */
1806 element_values = record_data[i].element_values;
1807 if (ANY_CONTAINER_TYPE != container_type)
1809 cont_type = (int) (element_values[container_type].parsed_value);
1810 cont_name = (char *) (element_values[container_name].parsed_value);
1812 record_name = (char *) (element_values[name_type].parsed_value);
1814 locked = (Boolean)(element_values[lock_type].parsed_value);
1819 start_index = last_index = i;
1820 element_values = record_data[i].element_values;
1821 if (ANY_CONTAINER_TYPE == container_type)
1823 while ((strcmp((char *) (element_values[name_type].parsed_value),
1829 element_values = record_data[i].element_values;
1834 while (((int)(element_values[container_type].parsed_value)
1836 (strcmp((char *)(element_values[container_name].parsed_value),
1838 (strcmp((char *)(element_values[name_type].parsed_value),
1844 element_values = record_data[i].element_values;
1847 if (start_index != last_index)
1848 EliminateEntries(record_data, record_count, last_index,
1849 start_index - 1, &i, &count, record_type);
1855 start_index = lock_index = last_index = i;
1857 if (i < 0) continue;
1858 element_values = record_data[i].element_values;
1859 if (ANY_CONTAINER_TYPE == container_type)
1861 while ((strcmp((char *) (element_values[name_type].parsed_value),
1864 locked = (Boolean)(element_values[lock_type].parsed_value);
1865 if (locked && start_index == lock_index)
1870 element_values = record_data[i].element_values;
1875 while (((int)(element_values[container_type].parsed_value)
1877 (strcmp((char *)(element_values[container_name].parsed_value),
1879 (strcmp((char *)(element_values[name_type].parsed_value),
1882 locked = (Boolean)(element_values[lock_type].parsed_value);
1883 if (locked && start_index == lock_index)
1888 element_values = record_data[i].element_values;
1891 if (start_index != last_index)
1893 if (start_index == lock_index)
1894 EliminateEntries(record_data, record_count, last_index + 1,
1895 start_index, &i, &count, record_type);
1898 int diff = start_index - lock_index;
1899 EliminateEntries(record_data, record_count, lock_index + 1,
1900 start_index, &i, &count, record_type);
1903 if (lock_index != last_index)
1904 EliminateEntries(record_data, record_count, last_index,
1905 lock_index - 1, &i, &count, record_type);
1916 /************************************************************************
1919 * Given a record_data array and a particular container type,
1920 * allocate an array of pointers to strings and set to the component
1921 * names of each component which matches the above criteria.
1923 ************************************************************************/
1926 GetNameList (RecordData * record_data,
1935 char ** name_list = NULL;
1936 int name_list_count = 0;
1937 int found_count = 0;
1939 for (i = 0; i < record_count; i++)
1941 if (ANY_CONTAINER_TYPE == container_type ||
1942 (int)(record_data[i].element_values[container_type].parsed_value) ==
1945 if (found_count >= name_list_count)
1947 name_list_count += 10;
1949 (char **) XtRealloc ((char *) name_list,
1950 sizeof (char **) * (name_list_count + 1));
1952 name_list [found_count] =
1953 record_data[i].element_values[name_type].parsed_value;
1958 if (name_list != NULL)
1959 name_list [found_count] = NULL;
1968 /************************************************************************
1971 * Given a record_data array, container name list and container type,
1972 * delete any components which are within the specified container type
1973 * but do not contain the container name.
1975 ************************************************************************/
1978 EliminateUnused (RecordData * record_data,
1980 char ** cont_name_list,
1987 int i, j, dummy = 0;
1988 char * container_name;
1989 int count = *record_count;
1990 Boolean name_found = False;
1991 ElementValue * element_values;
1997 element_values = record_data[i].element_values;
1998 if (cont_type == ANY_CONTAINER_TYPE ||
1999 (int)(element_values[cont_type].parsed_value) == container)
2001 if (cont_name_list != NULL)
2003 for (j = 0; cont_name_list[j] != NULL; j++)
2005 container_name = cont_name_list[j];
2006 if (strcmp((char *)element_values[cont_name].parsed_value,
2007 container_name) == 0)
2017 printf("Entry Eliminated - %s\n",
2018 (char *)element_values[cont_name].parsed_value);
2020 EliminateEntries(record_data, record_count, i, i, &dummy, &count,
2036 /************************************************************************
2039 * Given a record_data array, delete any components which have the
2040 * DELETE keyword set to True. Also delete any duplicates that match
2041 * the container name, container type, record name, and record type
2042 * but do not have the LOCKED keyword set to True.
2044 ************************************************************************/
2047 EliminateDeleted (RecordData * record_data,
2056 int i, j, start, dummy = 0;
2058 ElementValue * element_values, * other_element_values;
2059 char * container_name, * rec_name;
2060 int container_type, rec_type;
2062 count = *record_count;
2068 element_values = record_data[i].element_values;
2069 if ((Boolean)element_values[delete_type].parsed_value)
2071 Boolean delete_rest = False;
2073 if (record_type == CONTROL)
2075 rec_type = (int)element_values[CONTROL_TYPE].parsed_value;
2077 (int)element_values[CONTROL_CONTAINER_TYPE].parsed_value;
2080 XtNewString ((char *)element_values[cont_name].parsed_value);
2082 XtNewString ((char *)element_values[record_name].parsed_value);
2084 for (j = count - 1; j >= 0; j--)
2086 other_element_values = record_data[j].element_values;
2087 if ((record_type != CONTROL ||
2088 ((int)other_element_values[CONTROL_CONTAINER_TYPE].parsed_value
2089 == container_type &&
2090 (int) other_element_values[CONTROL_TYPE].parsed_value
2092 strcmp((char *)other_element_values[cont_name].parsed_value,
2093 container_name) == 0 &&
2094 strcmp((char *)other_element_values[record_name].parsed_value,
2097 if ((Boolean)other_element_values[lock_type].parsed_value)
2099 if ((Boolean)other_element_values[delete_type].parsed_value)
2101 EliminateEntries(record_data, record_count, j, j, &dummy,
2102 &count, record_type);
2105 else if (delete_rest)
2107 EliminateEntries(record_data, record_count, j, j, &dummy,
2108 &count, record_type);
2112 EliminateEntries(record_data, record_count, j, j, &dummy,
2113 &count, record_type);
2117 XtFree(container_name);
2128 /************************************************************************
2131 * Given an ElementValues array, a particular keyword that references
2132 * a single element and the parse function array for the record
2133 * type: if the element has a value string, parse it otherwise
2134 * set the parsed value to the default.
2136 ************************************************************************/
2139 InitializeField (ElementValue * element_values,
2141 ParseFunction * parse_functions)
2144 if (element_values[keyword].string_value != NULL)
2146 element_values[keyword].use_default = False;
2148 if (!parse_functions[keyword].parse_function (
2149 element_values[keyword].string_value,
2150 &(element_values[keyword].parsed_value)))
2152 XtFree(element_values[keyword].string_value);
2153 element_values[keyword].string_value = NULL;
2155 element_values[keyword].use_default = True;
2156 element_values[keyword].parsed_value =
2157 parse_functions[keyword].default_value;
2162 element_values[keyword].use_default = True;
2163 element_values[keyword].parsed_value =
2164 parse_functions[keyword].default_value;
2170 /************************************************************************
2173 * Given a record_data array, a container name and container type
2174 * count how many records match and return the value.
2176 ************************************************************************/
2179 CountElements (RecordData * record_data,
2181 char * container_name,
2189 static int found_count = 0;
2191 for (i = 0; i < record_count; i++)
2193 if (ANY_CONTAINER_TYPE == container_type ||
2194 (int)(record_data[i].element_values[container_type].parsed_value) ==
2197 if (strcmp (container_name,
2198 record_data[i].element_values[name_type].parsed_value) ==0)
2203 return (found_count);
2209 /************************************************************************
2211 * DeleteControlActionList
2213 ************************************************************************/
2217 DeleteControlActionList (ControlData * control_data)
2223 if (control_data->move_action != NULL)
2224 free(control_data->move_action);
2225 if (control_data->copy_action != NULL)
2226 free(control_data->copy_action);
2227 if (control_data->link_action != NULL)
2228 free(control_data->link_action);
2230 if (control_data->actions != NULL)
2232 for (i = 0; control_data->actions[i] != NULL; i++)
2234 free (control_data->actions[i]->action_name);
2235 if (control_data->actions[i]->action_label != NULL)
2236 free (control_data->actions[i]->action_label);
2237 XtFree ((char *) control_data->actions[i]);
2240 XtFree((char *)control_data->actions);
2247 /************************************************************************
2249 * AddControlActionList
2251 ************************************************************************/
2255 AddControlActionList (ControlData * control_data)
2259 char * data_type = NULL;
2260 char * act_list = NULL;
2261 char * file_name = NULL;
2263 char ** action_list = NULL;
2264 int num_actions = 0;
2267 Boolean is_file_control = False;
2268 PanelActionData * drop_action;
2273 if ((int)control_data->element_values[CONTROL_TYPE].parsed_value ==
2276 file_name = (char *)
2277 control_data->element_values[CONTROL_FILE_NAME].parsed_value;
2279 data_type = DtDtsFileToDataType (file_name);
2280 is_file_control = True;
2283 if (data_type != NULL)
2285 DtDtsAttribute ** attr_list;
2288 attr_list = DtDtsDataTypeToAttributeList (data_type, file_name);
2291 /* The attribute list is ordered alphabetically by name so */
2292 /* do a linear search of the atr_list array and get the values */
2293 /* as use run into them. Use the following array to get the */
2294 /* values for these attributes. */
2296 attr[0] = DtDTS_DA_ACTION_LIST;
2297 attr[1] = DtDTS_DA_COPY_TO_ACTION;
2298 attr[2] = DtDTS_DA_LINK_TO_ACTION;
2299 attr[3] = DtDTS_DA_MOVE_TO_ACTION;
2301 if (attr_list != NULL)
2303 for (i = 0; attr_list[i] != NULL; i++)
2305 for (j = 0; j < 4; j++)
2306 if (strcmp (attr_list[i]->name, attr[j]) == 0)
2310 /* If we have found a match, find the appropriate attr */
2311 /* and assign the value. */
2315 /* DtDTS_DA_ACTION_LIST */
2317 act_list = (char *) strdup(attr_list[i]->value);
2320 /* DtDTS_DA_COPY_TO_ACTION */
2322 control_data->copy_action =
2323 (char *) strdup(attr_list[i]->value);
2326 /* DtDTS_DA_LINK_TO_ACTION */
2328 control_data->link_action =
2329 (char *) strdup(attr_list[i]->value);
2332 /* DtDTS_DA_MOVE_TO_ACTION */
2334 control_data->move_action =
2335 (char *) strdup(attr_list[i]->value);
2347 action_list = _DtVectorizeInPlace (act_list, ',');
2348 for (i = 0; action_list[i] != NULL; i++)
2352 if (DtDtsDataTypeIsAction(data_type) && is_file_control)
2353 control_data->is_action = True;
2355 if (attr_list != NULL)
2356 DtDtsFreeAttributeList(attr_list);
2359 if (action_list == NULL)
2361 if (control_data->element_values[CONTROL_PUSH_ACTION].string_value != NULL)
2363 action_list = (char **) XtMalloc(sizeof(char *) * 2);
2366 control_data->element_values[CONTROL_PUSH_ACTION].string_value;
2367 action_list[1] = NULL;
2374 control_data->actions = (PanelActionData **)
2375 XtMalloc(sizeof(PanelActionData *) *
2378 for (i = 0, j = 0; j < num_actions; i++, j++)
2380 /* Remove the OpenInPlace action from the list of actions */
2381 if (strcmp(action_list[j],"OpenInPlace") == 0)
2387 control_data->actions[i] = (PanelActionData *)
2388 XtMalloc(sizeof(PanelActionData));
2390 control_data->actions[i]->action_name = strdup(action_list[j]);
2392 control_data->actions[i]->aap = NULL;
2393 control_data->actions[i]->count = 0;
2395 label = DtActionLabel (action_list[j]);
2398 control_data->actions[i]->action_label = label;
2400 control_data->actions[i]->action_label = strdup (action_list[j]);
2405 control_data->actions[i] = NULL;
2411 XtFree ((char *) action_list);
2413 if ((data_type != NULL) && is_file_control)
2414 DtDtsFreeDataType (data_type);
2420 /************************************************************************
2423 * For a box structure, find the control set that is to be contained
2424 * by it, allocate a ControlData array and reassign the element
2425 * values pointers. Further process each control.
2427 * Inputs: box_data - a pointer the BoxData structure to be initialized.
2429 ************************************************************************/
2432 ProcessBox (BoxData * box_data)
2436 ElementValue * element_values;
2438 int box_control_count = 0;
2442 /* Loop the control array and check each control to see if it belongs */
2443 /* in this box. If so, call a function to add it and then see if the */
2444 /* control has a subpanel to process. */
2446 for (i = 0; i < control_count; i++)
2448 element_values = control_data[i].element_values;
2450 if ((int) element_values[CONTROL_CONTAINER_TYPE].parsed_value == BOX &&
2451 strcmp ((char *) box_data->element_values[BOX_NAME].parsed_value,
2452 (char *) element_values[CONTROL_CONTAINER_NAME].parsed_value) == 0)
2454 ProcessControl ((XtPointer) box_data, BOX, &(box_data->control_data),
2455 &box_control_count, element_values);
2457 box_data->subpanel_count +=
2458 ProcessBoxControl (box_data->control_data[box_control_count - 1]);
2462 box_data->control_data_count = box_control_count;
2468 /************************************************************************
2471 * For each control that is created, reallocate the array of
2472 * pointer that hold the control and allocate a control structure.
2473 * Initialize the control fields. This is called for BOX, SUBPANEL
2474 * and SWITCH controls.
2476 * Inputs: parent - a pointer to the head of the structure that is to
2477 * contain this control.
2478 * parent_type - the type of parent of the control.
2479 * control_data_ptr - a pointer to the array of control pointers.
2480 * control_count - the current count of controls within the array.
2481 * element_values - the new controls database values.
2483 ************************************************************************/
2487 ProcessControl (XtPointer parent,
2489 ControlData *** control_data_ptr,
2490 int * control_count,
2491 ElementValue * element_values)
2495 ControlData * control;
2498 (ControlData **) XtRealloc ((char *) *control_data_ptr,
2499 sizeof (ControlData *) * (*control_count + 1));
2500 (*control_data_ptr)[*control_count] =
2501 (ControlData *) XtMalloc (sizeof (ControlData));
2503 control = (*control_data_ptr)[*control_count];
2505 control->element_values = element_values;
2506 control->parent_data = parent;
2507 control->parent_type = parent_type;
2508 control->subpanel_data = NULL;
2509 control->icon = NULL;
2510 control->arrow = NULL;
2511 control->arrow_separator = NULL;
2512 control->indicator = NULL;
2513 control->actions = NULL;
2514 control->is_action = False;
2515 control->move_action = NULL;
2516 control->copy_action = NULL;
2517 control->link_action = NULL;
2518 control->operation = NULL;
2520 AddControlActionList (control);
2522 *control_count = *control_count + 1;
2528 /************************************************************************
2531 * For a control structure within a box, see if there is a subpanel
2532 * attached to it and if so, process the subpanel and its controls.
2533 * Return the subpanel count to be stored as part of the box data.
2535 * Inputs: control_data - a pointer to the control to be processed
2537 ************************************************************************/
2540 ProcessBoxControl (ControlData * control_data)
2545 ElementValue * element_values;
2546 int box_subpanel_count = 0;
2547 SubpanelData * subpanel;
2550 /* Loop through the subpanel data and find one that is attached */
2551 /* to the provided control. */
2553 for (i = 0; i < subpanel_count; i++)
2555 element_values = subpanel_data[i].element_values;
2557 if (strcmp ((char *) control_data->element_values[CONTROL_NAME].parsed_value,
2558 (char *) element_values[SUBPANEL_CONTAINER_NAME].parsed_value) == 0)
2560 box_subpanel_count = 1;
2562 control_data->subpanel_data =
2563 (SubpanelData *) XtMalloc (sizeof (SubpanelData));
2565 subpanel = control_data->subpanel_data;
2566 subpanel->element_values = element_values;
2567 subpanel->control_data = NULL;
2568 subpanel->control_data_count = 0;
2569 subpanel->parent_control_data = control_data;
2570 subpanel->default_control = NULL;
2571 subpanel->shell = NULL;
2572 subpanel->form = NULL;
2573 subpanel->dropzone = NULL;
2574 subpanel->separator = NULL;
2575 subpanel->main_panel_icon_copy = NULL;
2576 subpanel->torn = False;
2578 ProcessSubpanel (subpanel);
2583 return (box_subpanel_count);
2589 /************************************************************************
2592 * For a Subpanel, find all of the controls within it an allocate
2593 * a ControlData array and move the element values for the controls.
2595 * Inputs: subpanel_data - A pointer the the subpanel structure to be
2598 ************************************************************************/
2601 ProcessSubpanel (SubpanelData * subpanel_data)
2605 ElementValue * element_values;
2607 int subpanel_control_count = 0;
2612 /* Loop the control array and check each control to see if it belongs */
2613 /* in this subpanel. If so, call a function to add it. */
2615 for (i = 0; i < control_count; i++)
2617 element_values = control_data[i].element_values;
2619 if ((int) element_values[CONTROL_CONTAINER_TYPE].parsed_value == SUBPANEL &&
2620 strcmp ((char *) subpanel_data->element_values[SUBPANEL_NAME].parsed_value,
2621 (char *) element_values[CONTROL_CONTAINER_NAME].parsed_value) == 0)
2623 ProcessControl ((XtPointer) subpanel_data, SUBPANEL,
2624 &(subpanel_data->control_data),
2625 &subpanel_control_count, element_values);
2629 subpanel_data->control_data_count = subpanel_control_count;
2635 /************************************************************************
2638 * For a Switch, find all of the controls within it an allocate
2639 * a ControlData array and move the element values for the controls.
2641 * Inputs: switch_data - a pointer to the switch data structure to be
2644 ************************************************************************/
2647 ProcessSwitch (SwitchData * switch_data)
2651 ElementValue * element_values;
2653 int switch_control_count = 0;
2657 /* Count the number of controls that are to go into this switch */
2658 /* and allocate a ControlData array to hold the controls. */
2660 for (i = 0; i < control_count; i++)
2662 element_values = control_data[i].element_values;
2664 if ((int) element_values[CONTROL_CONTAINER_TYPE].parsed_value == SWITCH &&
2665 strcmp ((char *) switch_data->element_values[SWITCH_NAME].parsed_value,
2666 (char *) element_values[CONTROL_CONTAINER_NAME].parsed_value) == 0)
2668 ProcessControl ((XtPointer) switch_data, SWITCH,
2669 &(switch_data->control_data),
2670 &switch_control_count, element_values);
2674 switch_data->control_data_count = switch_control_count;
2680 /************************************************************************
2682 * CreateComponentFileName
2683 * Create a file name in which to store a component file. This is
2684 * accomplished by using the components name with an integer value
2687 * Inputs: record_data - a pointer to the struture that contains the
2688 * components name, as well as other values.
2690 ************************************************************************/
2694 CreateComponentFileName (RecordData * record_data)
2699 char * component_name;
2700 struct stat stat_info;
2704 component_name = XtMalloc(9);
2705 strncpy (component_name, record_data->element_values[0].string_value, 8);
2706 component_name[8] = '\0';
2708 file_name = XtMalloc (strlen (HOME_DIR) + strlen (TYPES_DIR) + 14);
2710 for (i = 1; i < 1000; i++)
2712 sprintf(file_name, "%s%s%s%d.fp", HOME_DIR, TYPES_DIR, component_name, i);
2714 if (lstat (file_name, &stat_info) != 0)
2718 XtFree(component_name);
2726 /************************************************************************
2728 * WriteComponentToFile
2729 * Write a component (contained within record_data) to a .fp file.
2731 * Inputs: record_data - a pointer to the data for the component,
2732 * including its element values.
2733 * record_type - the type of component (CONTROL, SUBPANEL, ...)
2734 * keywords - the ordered array of keywords for the component
2735 * type, used to reference into the element values array.
2736 * container_name - the parent of the component.
2737 * container_type - the type of parent of the component.
2738 * delete - whether the component is be added or deleted.
2740 ************************************************************************/
2744 WriteComponentToFile (RecordData * record_data,
2747 char * container_name,
2754 char * file_name = CreateComponentFileName (record_data);
2757 if ((fd = fopen(file_name, "w")) != NULL)
2759 fprintf (fd, "%s %s\n{\n", keywords[0],
2760 record_data->element_values[0].string_value);
2764 if (record_type == CONTROL)
2766 fprintf(fd, " TYPE %s\n",
2767 record_data->element_values[CONTROL_TYPE].string_value);
2768 fprintf(fd, " CONTAINER_TYPE %s\n",
2769 record_data->element_values[CONTROL_CONTAINER_TYPE].string_value);
2772 fprintf(fd, " CONTAINER_NAME %s\n", container_name);
2773 fprintf(fd, " DELETE True\n");
2778 for (k = 1; k < record_descriptor[record_type].maxFields; k++)
2780 if (record_data->element_values[k].string_value != NULL &&
2781 record_data->element_values[k].use_default == False)
2783 if (record_type == CONTROL &&
2784 (int) record_data->element_values[CONTROL_TYPE].parsed_value == CONTROL_FILE &&
2785 (k == CONTROL_PUSH_ACTION ||
2786 k == CONTROL_LABEL || k == CONTROL_DROP_ACTION))
2789 fprintf (fd, " %s %s\n", keywords[k],
2790 record_data->element_values[k].string_value);
2800 if (record_type == CONTROL)
2801 SessionAddFileData(file_name,
2802 record_data->element_values[CONTROL_NAME].string_value,
2804 container_name, container_type, delete);
2806 SessionAddFileData(file_name,
2807 record_data->element_values[0].string_value,
2808 record_type, container_name, container_type,delete);
2811 WmFrontPanelSessionSaveData ();
2819 /************************************************************************
2821 * RemoveComponentFile
2822 * Find the dynamic .fp file name of a file in the session data and
2823 * unlink the file to remove the component. If no file name is
2824 * found or the unlink fails, Call a function to write a .fp for
2825 * the file which will have the DELETE keyword set to True.
2827 ************************************************************************/
2831 RemoveComponentFile (RecordData * record_data,
2834 char * container_name,
2842 SessionFileNameLookup (record_data->element_values[0].string_value,
2843 record_type, container_name, container_type);
2845 if (file_name == NULL || unlink (file_name) < 0)
2846 WriteComponentToFile (record_data, record_type, keywords,
2847 container_name, container_type, True);
2850 SessionDeleteFileData (file_name);
2851 WmFrontPanelSessionSaveData ();
2858 /************************************************************************
2860 * WriteControlComponentFile
2861 * Set up the parameters to call a function which will write out
2862 * to a .fp file a control description.
2864 * Inputs: control_data - a pointer to the control to be written.
2866 ************************************************************************/
2870 WriteControlComponentFile (ControlData * control_data)
2874 ElementValue * element_values;
2876 element_values = control_data->element_values;
2878 WriteComponentToFile ((RecordData *) control_data, CONTROL, control_keywords,
2879 (char *) element_values[CONTROL_CONTAINER_NAME].parsed_value,
2880 (int) element_values[CONTROL_CONTAINER_TYPE].parsed_value,
2887 /************************************************************************
2889 * WriteSubpanelComponentFile
2890 * Set up the parameters to call a function which will write out
2891 * to a .fp file a subpanel description.
2893 * Inputs: subpanel_data - a pointer to the subpanel to be written.
2895 ************************************************************************/
2898 WriteSubpanelComponentFile (SubpanelData * subpanel_data)
2902 ElementValue * element_values = subpanel_data->element_values;
2904 WriteComponentToFile ((RecordData *) subpanel_data, SUBPANEL, subpanel_keywords,
2905 (char *) element_values[SUBPANEL_CONTAINER_NAME].parsed_value,
2912 /************************************************************************
2914 * RemoveControlComponentFile
2915 * Set up the parameters to call a function which delete a control's
2918 * Inputs: control_data - a pointer to the control to be deleted.
2920 ************************************************************************/
2924 RemoveControlComponentFile (ControlData * control_data)
2928 ElementValue * element_values = control_data->element_values;
2930 RemoveComponentFile ((RecordData *) control_data, CONTROL, control_keywords,
2931 (char *) element_values[CONTROL_CONTAINER_NAME].parsed_value,
2932 (int) element_values[CONTROL_CONTAINER_TYPE].parsed_value);
2938 /************************************************************************
2940 * RemoveSubpanelComponentFile
2941 * Set up the parameters to call a function which delete a subpanel's
2944 * Inputs: subpanel_data - a pointer to the subpanel to be deleted.
2946 ************************************************************************/
2949 RemoveSubpanelComponentFile (SubpanelData * subpanel_data)
2953 ElementValue * element_values = subpanel_data->element_values;
2955 RemoveComponentFile ((RecordData *) subpanel_data, SUBPANEL, subpanel_keywords,
2956 (char *) element_values[SUBPANEL_CONTAINER_NAME].parsed_value,
2963 /************************************************************************
2965 * _WriteControlElementValues
2966 * Set up a loop which write out all of the values that define
2967 * a control. These are written as normal keyword, value pairs.
2969 * Inputs: element_values - a pointer to the array of element value
2970 * strutures each of which contain a value for a keyword.
2972 ************************************************************************/
2976 _WriteControlElementValues (ElementValue * element_values)
2982 printf("%s %s\n{\n", control_keywords[0], element_values[0].string_value);
2984 for (k = 1; k < record_descriptor[CONTROL].maxFields; k++)
2986 if (element_values[k].string_value != NULL)
2988 control_keywords[k], element_values[k].string_value);
2998 /************************************************************************
3002 ************************************************************************/
3005 InitParse (char * file_name,
3006 ElementValue ** elem_vals)
3016 DtDirPaths * dirPath;
3019 /* create directory for dir path */
3021 tmpPath = XtMalloc (strlen(HOME_DIR) + strlen(TYPES_DIR) + 34);
3022 sprintf (tmpPath, "%s%s%s%d", HOME_DIR, TYPES_DIR, "fp", (int) getpid());
3023 mkdir (tmpPath, S_IRUSR | S_IWUSR | S_IXUSR);
3026 /* create symbolic link to file_name */
3028 tmpName = XtNewString(file_name);
3029 baseName = strrchr(tmpName, '/');
3030 tmpFile = XtMalloc(strlen(tmpPath) + strlen(baseName) + 1);
3031 sprintf(tmpFile, "%s%s", tmpPath, baseName);
3032 symlink(file_name, tmpFile);
3034 hostName = XtMalloc((Cardinal)(MAXHOSTNAMELEN + 1));
3035 DtGetShortHostname (hostName, MAXHOSTNAMELEN + 1);
3037 tmpDir = XtMalloc(strlen(hostName) + strlen(tmpPath) + 2);
3038 sprintf(tmpDir, "%s:%s", hostName, tmpPath);
3040 dirPath = (DtDirPaths *) XtMalloc(sizeof(DtDirPaths));
3041 dirPath->dirs = (char **) XtMalloc(sizeof(char *) * 2);
3042 dirPath->paths = (char **) XtMalloc(sizeof(char *) * 2);
3044 dirPath->dirs[0] = tmpDir;
3045 dirPath->dirs[1] = NULL;
3046 dirPath->paths[0] = tmpPath;
3047 dirPath->paths[1] = NULL;
3049 _DtDbRead (dirPath, FILE_TYPE_SUFFIX, control_record_descriptor, 2);
3051 control_element_value_found = False;
3053 /* remove link and directory */
3058 XtFree((char *) dirPath->dirs);
3059 XtFree((char *) dirPath->paths);
3060 XtFree((char *) dirPath);
3067 *elem_vals = control_element_values;
3073 /************************************************************************
3075 * FreeFileControlField
3077 ************************************************************************/
3081 FreeFileControlField (ElementValue * element_values,
3086 if (control_parse_functions[indx].free_function != NULL &&
3087 element_values[indx].parsed_value != NULL &&
3088 element_values[indx].use_default == False)
3090 (*(control_parse_functions[indx].free_function))
3091 (&(element_values[indx].parsed_value));
3092 element_values[indx].parsed_value = NULL;
3095 if (element_values[indx].use_default == False &&
3096 element_values[indx].string_value != NULL)
3098 free(element_values[indx].string_value);
3099 element_values[indx].string_value = NULL;
3106 /************************************************************************
3108 * InitializePrimaryControlFields
3110 ************************************************************************/
3114 InitializePrimaryControlFields (ElementValue * element_values)
3118 InitializeField (element_values,
3119 CONTROL_NAME, control_parse_functions);
3120 InitializeField (element_values,
3121 CONTROL_CONTAINER_NAME, control_parse_functions);
3122 InitializeField (element_values,
3123 CONTROL_CONTAINER_TYPE, control_parse_functions);
3124 InitializeField (element_values,
3125 CONTROL_LOCKED, control_parse_functions);
3126 InitializeField (element_values,
3127 CONTROL_DELETE, control_parse_functions);
3134 /************************************************************************
3136 * InitializeSecondaryControlFields
3138 ************************************************************************/
3142 InitializeSecondaryControlFields (ElementValue * element_values)
3146 InitializeField (element_values,
3147 CONTROL_TYPE, control_parse_functions);
3148 InitializeField (element_values,
3149 CONTROL_POSITION_HINTS, control_parse_functions);
3150 InitializeField (element_values,
3151 CONTROL_ALTERNATE_ICON, control_parse_functions);
3152 InitializeField (element_values,
3153 CONTROL_PUSH_ANIMATION, control_parse_functions);
3154 InitializeField (element_values,
3155 CONTROL_DROP_ANIMATION, control_parse_functions);
3156 InitializeField (element_values,
3157 CONTROL_PUSH_RECALL, control_parse_functions);
3158 InitializeField (element_values,
3159 CONTROL_MONITOR_TYPE, control_parse_functions);
3160 InitializeField (element_values,
3161 CONTROL_CLIENT_NAME, control_parse_functions);
3162 InitializeField (element_values,
3163 CONTROL_CLIENT_GEOMETRY, control_parse_functions);
3164 InitializeField (element_values,
3165 CONTROL_FILE_NAME, control_parse_functions);
3166 InitializeField (element_values,
3167 CONTROL_DATE_FORMAT, control_parse_functions);
3168 InitializeField (element_values,
3169 CONTROL_HELP_STRING, control_parse_functions);
3170 InitializeField (element_values,
3171 CONTROL_HELP_VOLUME, control_parse_functions);
3172 InitializeField (element_values,
3173 CONTROL_HELP_TOPIC, control_parse_functions);
3180 /************************************************************************
3182 * InitializeFileControlFields
3184 ************************************************************************/
3188 InitializeFileControlFields (ElementValue * element_values,
3193 if ((int)element_values[CONTROL_TYPE].parsed_value == CONTROL_FILE)
3195 Boolean free_data_type = False;
3197 char ** action_list = NULL;
3202 char * label = NULL;
3205 struct stat stat_info;
3206 Boolean valid_file = True;
3209 file_name = (char *) element_values[CONTROL_FILE_NAME].parsed_value;
3211 if (lstat (file_name, &stat_info) != 0)
3214 if (data_type == NULL && file_name != NULL)
3216 data_type = DtDtsFileToDataType (file_name);
3217 free_data_type = True;
3220 if (data_type != NULL)
3224 icon_name = DtDtsDataTypeToAttributeValue (data_type,
3225 DtDTS_DA_ICON, NULL);
3227 if (element_values[CONTROL_NORMAL_ICON].string_value != NULL)
3229 XtFree (element_values[CONTROL_NORMAL_ICON].string_value);
3230 element_values[CONTROL_NORMAL_ICON].string_value = NULL;
3233 element_values[CONTROL_NORMAL_ICON].string_value =
3234 XtNewString (icon_name);
3236 DtDtsFreeAttributeValue(icon_name);
3240 DtDtsDataTypeToAttributeValue(data_type, DtDTS_DA_DESCRIPTION, NULL);
3242 if (element_values[CONTROL_HELP_STRING].string_value != NULL)
3244 XtFree (element_values[CONTROL_HELP_STRING].string_value);
3245 element_values[CONTROL_HELP_STRING].string_value = NULL;
3248 element_values[CONTROL_HELP_STRING].string_value = XtNewString (description);
3249 DtDtsFreeAttributeValue (description);
3252 act_list = DtDtsDataTypeToAttributeValue (data_type,
3253 DtDTS_DA_ACTION_LIST,
3256 action_list = _DtVectorizeInPlace (act_list, ',');
3258 if (action_list && action_list[0] != NULL)
3260 element_values[CONTROL_PUSH_ACTION].string_value =
3261 strdup (action_list[0]);
3262 element_values[CONTROL_DROP_ACTION].string_value =
3263 strdup (action_list[0]);
3265 if (DtDtsDataTypeIsAction (data_type))
3266 label = DtActionLabel (action_list[0]);
3269 /* try to set it to the name of the type */
3270 if (label == NULL) {
3271 label = DtDtsDataTypeToAttributeValue (data_type,
3272 DtDTS_DA_LABEL, NULL);
3274 /* copy & correctly free the memory */
3278 label = XtNewString(t);
3280 DtDtsFreeAttributeValue(t);
3285 if (label == NULL && file_name != NULL)
3287 if ((file_str = (char *)strrchr(file_name, '/')) == NULL)
3288 file_str = file_name;
3291 label = XtNewString(file_str);
3295 element_values[CONTROL_LABEL].string_value = label;
3298 if (data_type != NULL)
3302 DtDtsFreeAttributeValue (act_list);
3303 XtFree ((char *) action_list);
3307 DtDtsFreeDataType (data_type);
3312 InitializeField (element_values,
3313 CONTROL_NORMAL_ICON, control_parse_functions);
3314 InitializeField (element_values,
3315 CONTROL_HELP_STRING, control_parse_functions);
3316 InitializeField (element_values,
3317 CONTROL_LABEL, control_parse_functions);
3318 InitializeField (element_values,
3319 CONTROL_PUSH_ACTION, control_parse_functions);
3320 InitializeField (element_values,
3321 CONTROL_DROP_ACTION, control_parse_functions);
3327 /************************************************************************
3329 * InitializeControlFields
3331 ************************************************************************/
3335 InitializeControlFields (ElementValue * element_values,
3340 InitializePrimaryControlFields (element_values);
3341 InitializeSecondaryControlFields (element_values);
3342 InitializeFileControlFields (element_values, data_type);
3348 /************************************************************************
3352 ************************************************************************/
3356 UpdateFileType (ControlData * control_data)
3361 char * control_label;
3362 XmString icon_label;
3365 FreeFileControlField (control_data->element_values, CONTROL_NORMAL_ICON);
3366 FreeFileControlField (control_data->element_values, CONTROL_PUSH_ACTION);
3367 FreeFileControlField (control_data->element_values, CONTROL_DROP_ACTION);
3368 FreeFileControlField (control_data->element_values, CONTROL_LABEL);
3369 InitializeFileControlFields (control_data->element_values, NULL);
3371 DeleteControlActionList (control_data);
3372 AddControlActionList (control_data);
3375 (char *)control_data->element_values[CONTROL_NORMAL_ICON].parsed_value;
3377 if ((int)control_data->element_values[CONTROL_CONTAINER_TYPE].parsed_value ==
3380 icon_name = GetIconName (icon_name, panel.sub_icon_size);
3384 icon_name = GetIconName (icon_name, panel.main_icon_size);
3386 if (icon_name == NULL)
3387 icon_name = GetIconName (icon_name, panel.sub_icon_size);
3390 control_label = (char *)
3391 control_data->element_values[CONTROL_LABEL].parsed_value;
3393 icon_label = XmStringCreateLocalized (control_label);
3395 XtSetArg(al[0], XmNimageName, icon_name);
3396 XtSetArg(al[1], XmNstring, icon_label);
3397 XtSetValues(control_data->icon, al, 2);
3403 /************************************************************************
3405 * UpdateFileTypeControlFields
3407 ************************************************************************/
3411 UpdateFileTypeControlFields (void)
3416 ControlData * control_data;
3417 SubpanelData * subpanel_data;
3418 SwitchData * switch_data;
3421 if (panel_count == 0) return;
3423 for (i = 0; i < panel.box_data_count; i++)
3425 box_data = panel.box_data[i];
3427 for (j = 0; j < box_data->control_data_count; j++)
3429 control_data = box_data->control_data[j];
3431 if ((int)control_data->element_values[CONTROL_TYPE].parsed_value ==
3433 UpdateFileType(control_data);
3435 if (control_data->subpanel_data != NULL)
3437 subpanel_data = control_data->subpanel_data;
3439 for (k = 0; k < subpanel_data->control_data_count; k++)
3441 control_data = subpanel_data->control_data[k];
3443 if ((int)control_data->element_values[CONTROL_TYPE].parsed_value
3445 UpdateFileType(control_data);
3450 if (box_data->switch_data != NULL)
3452 switch_data = box_data->switch_data;
3453 for (j = 0; j < switch_data->control_data_count; j++)
3455 control_data = switch_data->control_data[j];
3457 if ((int)control_data->element_values[CONTROL_TYPE].parsed_value ==
3459 UpdateFileType(control_data);
3468 /************************************************************************
3470 * InitializeSubpanelFields
3472 ************************************************************************/
3476 InitializeSubpanelFields (ElementValue * element_values)
3480 InitializeField (element_values,
3481 SUBPANEL_NAME, subpanel_parse_functions);
3482 InitializeField (element_values,
3483 SUBPANEL_CONTAINER_NAME, subpanel_parse_functions);
3484 InitializeField (element_values,
3485 SUBPANEL_LOCKED, subpanel_parse_functions);
3486 InitializeField (element_values,
3487 SUBPANEL_CONTROL_INSTALL, subpanel_parse_functions);
3488 InitializeField (element_values,
3489 SUBPANEL_TITLE, subpanel_parse_functions);
3490 InitializeField (element_values,
3491 SUBPANEL_DELETE, subpanel_parse_functions);
3492 InitializeField (element_values,
3493 SUBPANEL_HELP_STRING, subpanel_parse_functions);
3494 InitializeField (element_values,
3495 SUBPANEL_HELP_TOPIC, subpanel_parse_functions);
3496 InitializeField (element_values,
3497 SUBPANEL_HELP_VOLUME, subpanel_parse_functions);