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
26 * Copyright (c) 1990, 1991, 1992, 1993 Open Software Foundation, Inc.
27 * ALL RIGHTS RESERVED (MOTIF). See the file named COPYRIGHT.MOTIF for
28 * the full copyright text.
35 static char rcsid[] = "$TOG: UilP2Out.c /main/15 1997/03/12 15:17:24 dbl $"
40 * (c) Copyright 1989, 1990, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. */
46 ** User Interface Language Compiler (UIL)
50 ** This module contain the routines for creating the UID file.
63 #include <DXm/DXmHelpB.h>
67 #include "UilSymGen.h"
71 ** DEFINE and MACRO DEFINITIONS
81 #define initial_context_size 2048
83 the original define makes some assumptions on the sizes of the
84 structures when calculating this value. I 'think' I have devined
85 the intent of this and have replaced it with a more generic
88 #define out_k_last_offset \
89 (((src_k_max_source_line_length +1) / sizeof(sym_entry_type *)))
91 /* #define out_k_last_offset ((sizeof( src_source_buffer_type )>>_shift)-2) */
93 typedef struct _out_queue_type
95 struct _out_queue_type *az_prior_queue;
96 sym_entry_type *entry[out_k_last_offset + 1];
102 ** EXTERNAL VARIABLE DECLARATIONS
111 ** GLOBAL VARIABLE DECLARATIONS
118 ** OWN VARIABLE DECLARATIONS
122 externaldef(uil_comp_glbl) IDBFile out_az_idbfile_id;
124 static URMResourceContext *out_az_context;
125 static out_queue_type *out_az_queue;
126 static int out_l_next_offset;
127 static UidCompressionTable *extern_arg_compr;
128 static UidCompressionTable *extern_class_compr;
134 ** FUNCTIONAL DESCRIPTION:
136 ** This function begins the process of creating the UID file. It
138 ** 1) creating the UID file and closing it
139 ** 2) initializing the queue of other objects to be processed
140 ** 3) creating the module widget
141 ** 4) emitting exported literals and procedures
142 ** 5) creating the compression code table for this UID file
144 ** FORMAL PARAMETERS:
150 ** sym_az_external_def_chain list of exported object
151 ** src_az_avail_source_buffer use source buffers for queue of objects
152 ** requiring further attention
156 ** src_az_avail_source_buffer
164 ** UID file is created
169 void sem_output_uid_file()
172 sym_external_def_entry_type *ext_entry;
173 char *module_version;
176 sym_entry_type *symbol_entry;
177 int topmost_widget_count;
180 { MrmOsOpenParam os_param;
181 char result_file[256];
186 ** No UID file is created if any error severity message has
190 if (uil_l_compile_status >= uil_k_error_status)
192 diag_issue_diagnostic(
201 ** Request URM hold error message and report via status rather
202 ** that sending them to stdout. This permits the compiler to
203 ** deal with the messages as it does with others.
207 Urm__UT_SetErrorReport( URMErrOutMemory );
208 if( urm_status != MrmSUCCESS)
209 issue_urm_error( "allocating context" );
214 uid_fcb.os_param.version = MrmOsOpenParamVersion;
217 /* clobber flag lets a.uid replace an existing a.uid */
218 uid_fcb.os_param.nam_flg.clobber_flg = TRUE;
221 module_name = sym_az_module_entry->obj_header.az_name->c_text;
223 if (sym_az_module_entry->az_version != NULL)
224 module_version = sym_az_module_entry->az_version->value.c_value;
226 urm_status = UrmIdbOpenFileWrite
227 ( Uil_cmd_z_command.ac_resource_file,
234 uid_fcb.result_file );
236 if (urm_status != MrmSUCCESS)
238 diag_issue_diagnostic(
242 uid_fcb.result_file );
249 ** Set the name of the file we are accessing as the current file and call
250 ** the Status callback routine to report our progress.
252 Uil_current_file = uid_fcb.result_file;
253 if (Uil_cmd_z_command.status_cb != (Uil_continue_type(*)())NULL)
254 diag_report_status();
262 UrmGetResourceContext ( _get_memory, _free_memory,
263 initial_context_size, &out_az_context );
264 if( urm_status != MrmSUCCESS)
265 issue_urm_error( "allocating context" );
268 ** Initialize queue of objects to be processed.
271 out_l_next_offset = 0;
272 out_az_queue = (out_queue_type *)src_az_avail_source_buffer;
273 out_az_queue->az_prior_queue = NULL;
274 src_az_avail_source_buffer =
275 src_az_avail_source_buffer->az_prior_source_buffer;
278 ** Count the number of topmost widgets by scanning the external list.
279 ** A topmost widget is one that is not referenced.
282 topmost_widget_count = 0;
284 for (ext_entry = sym_az_external_def_chain;
286 ext_entry = ext_entry->az_next_object)
288 symbol_entry = ext_entry->az_name->az_object;
290 if (symbol_entry->header.b_tag == sym_k_widget_entry)
291 if ((((sym_widget_entry_type *)symbol_entry)->
292 obj_header.az_name->b_flags & sym_m_referenced) == 0)
293 topmost_widget_count++;
298 ** Initialize the context to build the interface module.
303 ( out_az_context, topmost_widget_count, URMaPublic, FALSE );
304 if( urm_status != MrmSUCCESS)
305 issue_urm_error( "initializing module" );
308 ** Create the compression code table for use with this UID file.
311 create_int_compression_codes();
314 ** Exported objects are on a chain that we will now walk.
315 ** They can be of 3 types: widgets, gadgets and values.
316 ** Values, gadgets and widgets are pushed on LIFO queue and processed
318 ** Each widget on the list is top most if it is not referenced. Topmost
319 ** widgets are added to the current context for the interface module.
324 for (ext_entry = sym_az_external_def_chain;
326 ext_entry = ext_entry->az_next_object)
329 ** Call the Status callback routine to report our progress.
332 Uil_percent_complete=CEIL(
333 80+ (.20 *((float)topmost_index/(float)(topmost_widget_count+.5)))*100, 80);
335 if (Uil_cmd_z_command.status_cb != (Uil_continue_type(*)())NULL)
336 diag_report_status();
338 symbol_entry = ext_entry->az_name->az_object;
340 switch (symbol_entry->header.b_tag)
343 case sym_k_value_entry:
345 sym_value_entry_type *value_entry;
347 value_entry = (sym_value_entry_type *)symbol_entry;
349 value_entry->output_state = sym_k_queued;
351 push( (sym_entry_type *)value_entry );
356 case sym_k_gadget_entry:
357 case sym_k_widget_entry:
359 sym_widget_entry_type *widget_entry;
361 widget_entry = (sym_widget_entry_type *)symbol_entry;
363 if ((widget_entry->obj_header.az_name->b_flags & sym_m_referenced)
366 widget_entry->output_state = sym_k_queued;
368 push((sym_entry_type *) widget_entry );
374 widget_entry->obj_header.az_name->c_text );
375 if( urm_status != MrmSUCCESS)
376 issue_urm_error( "adding topmost widget" );
385 _assert( FALSE, "unexpected entry on external chain");
391 ** Emit the Interface Module
396 ( out_az_idbfile_id, module_name, out_az_context );
397 if( urm_status != MrmSUCCESS)
399 if (urm_status == MrmEOF)
400 diag_issue_diagnostic ( d_uid_write, diag_k_no_source,
401 diag_k_no_column, Uil_current_file );
403 issue_urm_error( "emitting module" );
406 if (Uil_cmd_z_command.v_show_machine_code) {
407 save_module_machine_code
408 ( src_az_module_source_record, out_az_context );
412 ** Start to process the widgets that have been pushed on
416 for (symbol_entry = pop(); symbol_entry != NULL; symbol_entry = pop() )
419 ** Call the Status callback routine to report our progress.
421 if (Uil_cmd_z_command.status_cb != (Uil_continue_type(*)())NULL)
422 diag_report_status();
424 switch (symbol_entry->header.b_tag)
427 case sym_k_value_entry:
428 out_emit_value(( sym_value_entry_type *) symbol_entry );
431 case sym_k_widget_entry:
432 case sym_k_gadget_entry:
433 case sym_k_child_entry:
434 out_emit_widget(( sym_widget_entry_type *) symbol_entry );
438 _assert( FALSE, "unexpected entry popped during output");
443 create_ext_compression_codes ();
446 ** Close the UID file - if there are errors don't keep the file
449 urm_status = (uil_l_compile_status < uil_k_error_status);
453 diag_issue_diagnostic
454 ( d_no_uid, diag_k_no_source, diag_k_no_column );
458 UrmIdbCloseFile( out_az_idbfile_id, urm_status );
459 out_az_idbfile_id = NULL;
460 if( urm_status != MrmSUCCESS)
461 diag_issue_diagnostic
462 ( d_uid_write, diag_k_no_source, diag_k_no_column, Uil_current_file );
470 UrmFreeResourceContext( out_az_context );
471 if( urm_status != MrmSUCCESS)
472 issue_urm_error( "freeing context" );
478 ** FUNCTIONAL DESCRIPTION:
480 ** This function pushes a symbol table entry into a LIFO queue.
482 ** FORMAL PARAMETERS:
484 ** sym_entry pointer to symbol table to push
488 ** out_l_next_offset next offset in current queue
489 ** out_az_queue current queue
490 ** src_az_avail_source_buffer
491 ** next available queue buffer
503 ** argument is placed on a queue
510 sym_entry_type *sym_entry;
514 out_queue_type *next_queue;
517 ** We reuse source buffers for the output queues.
520 if (out_l_next_offset > out_k_last_offset)
522 if (src_az_avail_source_buffer == NULL)
524 src_az_avail_source_buffer =
525 (src_source_buffer_type *)
526 _get_memory( sizeof( src_source_buffer_type ) );
527 src_az_avail_source_buffer->az_prior_source_buffer = NULL;
530 next_queue = (out_queue_type *)src_az_avail_source_buffer;
531 src_az_avail_source_buffer =
532 src_az_avail_source_buffer->az_prior_source_buffer;
534 next_queue->az_prior_queue = out_az_queue;
535 out_az_queue = next_queue;
536 out_l_next_offset = 0;
539 out_az_queue->entry[out_l_next_offset] = sym_entry;
547 ** FUNCTIONAL DESCRIPTION:
549 ** This function pops a symbol table entry from a LIFO queue.
551 ** FORMAL PARAMETERS:
557 ** out_l_next_offset next offset in current queue
558 ** out_az_queue current queue
559 ** src_az_avail_source_buffer
560 ** next available queue buffer
568 ** sym_entry pointer to symbol table popped
569 ** NULL when no more to pop
578 sym_entry_type *pop()
582 src_source_buffer_type *avail_buffer;
586 if (out_l_next_offset < 0)
588 avail_buffer = (src_source_buffer_type *)out_az_queue;
589 out_az_queue = out_az_queue->az_prior_queue;
590 avail_buffer->az_prior_source_buffer = src_az_avail_source_buffer;
591 src_az_avail_source_buffer = avail_buffer;
593 if (out_az_queue == NULL)
596 out_l_next_offset = out_k_last_offset;
599 return out_az_queue->entry[out_l_next_offset];
605 ** FUNCTIONAL DESCRIPTION:
607 ** This function builds the URM record for a widget.
609 ** FORMAL PARAMETERS:
611 ** widget_entry symbol table pointer for a widget
627 ** write a widget record to UID file
628 ** push other objects on the queue to be processed
633 void out_emit_widget( widget_entry )
635 sym_widget_entry_type *widget_entry;
641 char *widget_class_name;
642 unsigned int widget_class;
643 unsigned long widget_variety;
645 int related_arg_count;
647 sym_list_entry_type *list_entry;
650 MrmCode subtree_code;
651 sym_control_entry_type *subtree_control;
654 _assert( (widget_entry->header.b_tag == sym_k_widget_entry) ||
655 (widget_entry->header.b_tag == sym_k_gadget_entry) ||
656 (widget_entry->header.b_tag == sym_k_child_entry),
657 "object to be emitted is not an object" );
659 _assert( (widget_entry->obj_header.b_flags &
660 (sym_m_exported | sym_m_private)),
661 "object being emitted is not exported or private" );
663 if (widget_entry->header.b_tag == sym_k_child_entry)
664 widget_variety = UilMrmAutoChildVariety;
665 else widget_variety = UilMrmWidgetVariety;
668 * Each real widget needs a name. Automatic children just get an
669 * empty string since the name is stored in the compression tables.
670 * For real widgets, we use the user provided name
671 * if there is one; otherwise widgetfile#-line#-col#
672 * For example, widget-1-341-111 was defined in file=1, line=341
675 if (widget_variety == UilMrmAutoChildVariety)
677 else if (widget_entry->obj_header.az_name == NULL)
679 sprintf(buffer, "widget-%d-%d-%d",
680 widget_entry->header.az_src_rec->b_file_number,
681 widget_entry->header.az_src_rec->w_line_number,
682 widget_entry->header.b_src_pos);
683 widget_name = buffer;
686 widget_name = widget_entry->obj_header.az_name->c_text;
688 access_code = URMaPublic;
689 if (widget_entry->obj_header.b_flags & sym_m_private)
690 access_code = URMaPrivate;
692 urm_status = UrmCWRInit (out_az_context, widget_name, access_code, FALSE);
693 if( urm_status != MrmSUCCESS)
694 issue_urm_error( "initializing context" );
697 ** Set the class of the widget.
700 widget_class_name = NULL;
703 related_arg_count = 0;
704 subtree_control = NULL;
707 ** Special processing 1: User defined widgets have the class as
710 if ( widget_entry->header.b_type == uil_sym_user_defined_object )
713 widget_entry->az_create_proc->az_proc_def->obj_header.az_name->c_text;
717 ** Special processing 2. Widgets which map their (single) control to
718 ** a (subtree) resource. This handles the convention (originally invented
719 ** for the pulldown menu which is the child of a cascade button) that
720 ** subtrees which must be instantiated to serve as a resource value are
721 ** treated as children rather than as widget references. Multiple
722 ** children issue a diagnostic.
724 subtree_code = uil_urm_subtree_resource[widget_entry->header.b_type];
725 if ( subtree_code != 0 )
729 list_entry = widget_entry->az_controls;
731 extract_subtree_control (list_entry, &subtree_control, &count);
741 diag_issue_diagnostic
743 _sar_source_pos2(subtree_control),
744 diag_object_text(widget_entry->header.b_type));
751 * Set the class in the widget record
753 if (widget_variety == UilMrmAutoChildVariety)
754 widget_class = uil_child_compr[widget_entry->header.b_type];
755 else widget_class = uil_widget_compr[widget_entry->header.b_type];
759 * User defined widgets don't get compressed.
762 if (widget_entry->header.b_type == uil_sym_user_defined_object)
763 widget_class = MrmwcUnknown;
766 UrmCWRSetClass( out_az_context,
770 if( urm_status != MrmSUCCESS)
771 issue_urm_error( "setting class" );
774 ** Check the callback list for the creation reason and process it.
775 ** Do this first since it affects arg_count.
777 list_entry = widget_entry->az_callbacks;
778 if (list_entry != NULL)
780 sym_callback_entry_type *callback_entry;
782 arg_count += compute_list_size (list_entry, sym_k_callback_entry);
783 callback_entry = NULL;
784 extract_create_callback (list_entry, &callback_entry);
785 if ( callback_entry != NULL )
788 emit_callback (callback_entry, &arglist_index, TRUE);
794 ** Output the list of arguments. Arguments are either callbacks
798 if (widget_entry->az_arguments != NULL)
799 arg_count += compute_list_size
800 (widget_entry->az_arguments, sym_k_argument_entry);
805 UrmCWRInitArglist( out_az_context, arg_count );
806 if( urm_status != MrmSUCCESS)
807 issue_urm_error( "initializing arglist" );
808 arglist_index = arg_count - 1;
811 ** Process the callbacks, then the arguments
813 process_all_callbacks
814 (widget_entry->az_callbacks, &arglist_index);
815 process_all_arguments
816 (widget_entry->az_arguments, &arglist_index, &related_arg_count);
819 ** Process a control which is to be entered as a subtree resource. Mark
820 ** the control so it won't be processed again.
822 if (subtree_control != NULL)
824 MrmCode widget_access;
827 MrmResource_id widget_id;
830 UrmCWRSetCompressedArgTag
831 (out_az_context, arglist_index,
832 uil_arg_compr[subtree_code], 0);
833 if( urm_status != MrmSUCCESS)
834 issue_urm_error( "setting compressed arg" );
837 ref_control( subtree_control,
838 &widget_access, &widget_index, &widget_id );
840 UrmCWRSetArgResourceRef
849 if( urm_status != MrmSUCCESS)
850 issue_urm_error( "setting arg reference" );
851 subtree_control->header.b_tag = sym_k_error_entry;
862 list_entry = widget_entry->az_controls;
864 if (list_entry != NULL)
869 ** The list of controls is in reverse order. To correct for
870 ** this, controls are placed in the list from bottom to top.
871 ** Thus widget_index represent the last slot in the list used.
874 widget_index = compute_list_size (list_entry, sym_k_control_entry);
875 if (widget_index > 0)
878 UrmCWRInitChildren (out_az_context, widget_index );
879 if ( urm_status != MrmSUCCESS)
880 issue_urm_error( "initializing children" );
881 process_all_controls (list_entry, &widget_index);
886 ** If we have any related arguments, report the number.
889 if (related_arg_count > 0)
890 UrmCWRSetExtraArgs( out_az_context, related_arg_count );
893 ** Emit the widget record to UID file
894 ** All widgets are indexed as long as they are named. This is so
895 ** they can be included in module interface structure.
898 if (widget_entry->obj_header.az_name == NULL)
900 if (widget_entry->resource_id == 0 )
904 ( out_az_idbfile_id, &(widget_entry->resource_id) );
905 if( urm_status != MrmSUCCESS)
906 issue_urm_error( "obtaining resource id" );
912 widget_entry->resource_id,
922 if( urm_status != MrmSUCCESS)
924 if (urm_status == MrmEOF)
925 diag_issue_diagnostic ( d_uid_write, diag_k_no_source,
926 diag_k_no_column, Uil_current_file );
928 issue_urm_error( "emitting widget" );
931 if (Uil_cmd_z_command.v_show_machine_code)
933 save_widget_machine_code (widget_entry, out_az_context);
936 widget_entry->output_state = sym_k_emitted;
943 ** FUNCTIONAL DESCRIPTION:
945 ** This routine extracts the controlled widget (top-level) from
946 ** a controls list for subtree resources (those whose subtree must
947 ** be instantiated as part of parent creation, but which are
948 ** implemented as resources, not children). It returns the count of
949 ** the number of such entries found, and a pointer to the last one
952 ** FORMAL PARAMETERS:
954 ** list_entry the list to be (recursively) searched
955 ** menu_entry to return a ponter to the pulldown menu
956 ** count counts the number of entries found
971 void extract_subtree_control (list_entry, menu_entry, count)
972 sym_list_entry_type *list_entry;
973 sym_control_entry_type **menu_entry;
981 sym_obj_entry_type *list_member;
982 sym_nested_list_entry_type *nested_list_entry;
983 sym_control_entry_type *control_entry;
987 * Process the list elements, recursing on nested lists. Ignore error entries.
989 if ( list_entry == NULL ) return;
990 for (list_member=(sym_obj_entry_type *)list_entry->obj_header.az_next;
992 list_member=(sym_obj_entry_type *)list_member->obj_header.az_next)
993 switch ( list_member->header.b_tag )
995 case sym_k_nested_list_entry:
996 nested_list_entry = (sym_nested_list_entry_type *) list_member;
997 extract_subtree_control
998 (nested_list_entry->az_list, menu_entry, count);
1000 case sym_k_control_entry:
1001 control_entry = (sym_control_entry_type *) list_member;
1003 *menu_entry = control_entry;
1013 ** FUNCTIONAL DESCRIPTION:
1015 ** This routine searches a callbacks list (and any nested lists)
1016 ** for the create callback.
1018 ** FORMAL PARAMETERS:
1020 ** list_entry the list to be (recursively) searched
1021 ** create_entry to return a pointer to the create entry
1025 ** IMPLICIT OUTPUTS:
1036 void extract_create_callback (list_entry, create_entry)
1037 sym_list_entry_type *list_entry;
1038 sym_callback_entry_type **create_entry;
1045 sym_obj_entry_type *list_member;
1046 sym_nested_list_entry_type *nested_list_entry;
1047 sym_callback_entry_type *callback_entry;
1048 sym_value_entry_type *value_entry;
1049 key_keytable_entry_type *key_entry;
1053 * Process the list elements, recursing on nested lists. Ignore error entries.
1055 if ( list_entry == NULL ) return;
1056 for (list_member=(sym_obj_entry_type *)list_entry->obj_header.az_next;
1058 list_member=(sym_obj_entry_type *)list_member->obj_header.az_next)
1059 switch ( list_member->header.b_tag )
1061 case sym_k_nested_list_entry:
1062 nested_list_entry = (sym_nested_list_entry_type *) list_member;
1063 extract_create_callback
1064 (nested_list_entry->az_list, create_entry);
1066 case sym_k_callback_entry:
1067 callback_entry = (sym_callback_entry_type *) list_member;
1068 value_entry = callback_entry->az_call_reason_name;
1069 if (value_entry->obj_header.b_flags & sym_m_builtin)
1072 (key_keytable_entry_type *)value_entry->value.l_integer;
1073 if ( strcmp(uil_reason_toolkit_names[key_entry->b_subclass],
1074 MrmNcreateCallback) == 0 )
1076 *create_entry = callback_entry;
1089 ** FUNCTIONAL DESCRIPTION:
1091 ** This routine processes all valid callbacks in an callbacks list,
1092 ** recursing on nested lists. Each valid callback is emitted to
1095 ** FORMAL PARAMETERS:
1097 ** list_entry the list to be (recursively) processed
1098 ** arglist_index the modifiable index of arguments in the
1103 ** IMPLICIT OUTPUTS:
1114 void process_all_callbacks (list_entry, arglist_index)
1115 sym_list_entry_type *list_entry;
1123 sym_obj_entry_type *list_member;
1124 sym_nested_list_entry_type *nested_list_entry;
1125 sym_callback_entry_type *callback_entry;
1129 * Process the list elements, recursing on nested lists. Ignore error entries.
1131 if ( list_entry == NULL ) return;
1132 for (list_member=(sym_obj_entry_type *)list_entry->obj_header.az_next;
1134 list_member=(sym_obj_entry_type *)list_member->obj_header.az_next)
1135 switch ( list_member->header.b_tag )
1137 case sym_k_nested_list_entry:
1138 nested_list_entry = (sym_nested_list_entry_type *) list_member;
1139 process_all_callbacks (nested_list_entry->az_list, arglist_index);
1141 case sym_k_callback_entry:
1142 callback_entry = (sym_callback_entry_type *) list_member;
1143 emit_callback (callback_entry, arglist_index, FALSE);
1145 case sym_k_error_entry:
1148 _assert (FALSE, "unknown entry in callback list");
1158 ** FUNCTIONAL DESCRIPTION:
1160 ** This routine processes all valid arguments in an arguments list,
1161 ** recursing on nested lists. Each valid argument is emitted to
1164 ** FORMAL PARAMETERS:
1166 ** list_entry the list to be (recursively) processed
1167 ** arglist_index the modifiable index of arguments in the
1169 ** related_count the modifiable count of related args
1173 ** IMPLICIT OUTPUTS:
1184 void process_all_arguments (list_entry, arglist_index, related_count)
1185 sym_list_entry_type *list_entry;
1194 sym_obj_entry_type *list_member;
1195 sym_nested_list_entry_type *nested_list_entry;
1196 sym_argument_entry_type *argument_entry;
1200 * Process the list elements, recursing on nested lists. Ignore error entries.
1202 if ( list_entry == NULL ) return;
1203 for (list_member=(sym_obj_entry_type *)list_entry->obj_header.az_next;
1205 list_member=(sym_obj_entry_type *)list_member->obj_header.az_next)
1206 switch ( list_member->header.b_tag )
1208 case sym_k_nested_list_entry:
1209 nested_list_entry = (sym_nested_list_entry_type *) list_member;
1210 process_all_arguments
1211 (nested_list_entry->az_list, arglist_index, related_count);
1213 case sym_k_argument_entry:
1214 argument_entry = (sym_argument_entry_type *) list_member;
1215 emit_argument (argument_entry, *arglist_index, related_count);
1216 *arglist_index -= 1;
1218 case sym_k_error_entry:
1221 _assert (FALSE, "unknown entry in argument list");
1231 ** FUNCTIONAL DESCRIPTION:
1233 ** This routine processes all valid controls in an controls list,
1234 ** recursing on nested lists. Each valid control is emitted to
1237 ** FORMAL PARAMETERS:
1239 ** list_entry the list to be (recursively) processed
1240 ** widget_index the modifiable index of children
1244 ** IMPLICIT OUTPUTS:
1255 void process_all_controls (list_entry, widget_index)
1256 sym_list_entry_type *list_entry;
1264 sym_obj_entry_type *list_member;
1265 sym_nested_list_entry_type *nested_list_entry;
1266 sym_control_entry_type *control_entry;
1270 * Process the list elements, recursing on nested lists. Ignore error entries.
1272 if ( list_entry == NULL ) return;
1273 for (list_member=(sym_obj_entry_type *)list_entry->obj_header.az_next;
1275 list_member=(sym_obj_entry_type *)list_member->obj_header.az_next)
1276 switch ( list_member->header.b_tag )
1278 case sym_k_nested_list_entry:
1279 nested_list_entry = (sym_nested_list_entry_type *) list_member;
1280 process_all_controls (nested_list_entry->az_list, widget_index);
1282 case sym_k_control_entry:
1283 control_entry = (sym_control_entry_type *) list_member;
1285 emit_control (control_entry, *widget_index);
1287 case sym_k_error_entry:
1290 _assert (FALSE, "unknown entry in control list");
1300 ** FUNCTIONAL DESCRIPTION:
1302 ** This function builds the URM record for a value.
1304 ** FORMAL PARAMETERS:
1306 ** value_entry symbol table pointer for a value
1312 ** IMPLICIT OUTPUTS:
1322 ** write a value record to UID file
1327 void out_emit_value( value_entry )
1329 sym_value_entry_type *value_entry;
1340 _assert( value_entry->header.b_tag == sym_k_value_entry,
1341 "object to be emitted is not a value" );
1343 _assert( (value_entry->obj_header.b_flags & (sym_m_exported | sym_m_private)),
1344 "value being emitted is not exported or private" );
1346 access = URMaPublic;
1348 if (value_entry->obj_header.b_flags & sym_m_private)
1350 if (value_entry->resource_id == 0 )
1354 ( out_az_idbfile_id, &(value_entry->resource_id) );
1355 if( urm_status != MrmSUCCESS)
1356 issue_urm_error( "obtaining resource id" );
1359 access = URMaPrivate;
1363 ** Case on the type of literal.
1366 value_type = Urm_code_from_uil_type( value_entry->b_type );
1367 switch (value_entry->b_type)
1369 case sym_k_bool_value:
1370 case sym_k_integer_value:
1371 _assert(access == URMaPublic,
1372 "private value should not get resource ids");
1373 value_size = sizeof(long);
1376 case sym_k_horizontal_integer_value:
1377 case sym_k_vertical_integer_value:
1378 value_size = sizeof(RGMUnitsInteger);
1381 case sym_k_float_value:
1382 _assert(access == URMaPublic,
1383 "private floats should not get resource ids");
1384 value_size = sizeof (double);
1387 case sym_k_horizontal_float_value:
1388 case sym_k_vertical_float_value:
1389 value_size = sizeof(RGMUnitsFloat);
1392 case sym_k_single_float_value:
1393 _assert(access == URMaPublic,
1394 "private single floats should not get resource ids");
1395 value_size = sizeof(float);
1398 case sym_k_compound_string_value:
1399 tmp_str = value_entry->value.xms_value;
1401 XmCvtXmStringToByteStream(tmp_str,
1402 (unsigned char **)&(value_entry->value.c_value));
1403 XmStringFree(tmp_str);
1406 case sym_k_font_value:
1407 case sym_k_fontset_value:
1410 * Size is FontItem plus size of charset name string and
1411 * size of font name string.
1413 value_size = sizeof(RGMFontItem)
1414 + strlen(sem_charset_name(value_entry->b_charset,
1415 value_entry->az_charset_value))
1416 + 1 + strlen(value_entry->value.c_value) + 1;
1419 case sym_k_color_value:
1420 /* null on end of color name accounted for in RGMColorDesc */
1421 value_size = sizeof( RGMColorDesc ) + value_entry->w_length;
1424 case sym_k_rgb_value:
1426 sym_value_entry_type *value_segment;
1428 value_size = sizeof( RGMIntegerVector );
1430 for (value_segment = value_entry->az_first_table_value;
1431 value_segment != NULL;
1432 value_segment = value_segment->az_next_table_value)
1434 value_size += sizeof(long);
1440 case sym_k_color_table_value:
1441 value_size = compute_color_table_size( value_entry );
1444 case sym_k_icon_value:
1445 value_size = compute_icon_size( value_entry );
1448 case sym_k_char_8_value:
1449 case sym_k_reason_value:
1450 case sym_k_argument_value:
1451 case sym_k_class_rec_name_value:
1452 case sym_k_xbitmapfile_value:
1453 case sym_k_keysym_value:
1454 case sym_k_localized_string_value:
1455 /* BEGIN OSF Fix CR 4859 */
1456 /* END OSF Fix CR 4859 */
1457 value_size = value_entry->w_length + 1; /* +1 for the null */
1460 /* BEGIN OSF Fix CR 4859 */
1461 case sym_k_wchar_string_value:
1462 value_size = sizeof(RGMWCharEntry) +
1463 value_entry->az_first_table_value->w_length;
1465 /* END OSF Fix CR 4859 */
1466 case sym_k_identifier_value:
1467 value_size = value_entry->w_length; /* includes the null */
1470 case sym_k_string_table_value:
1472 sym_value_entry_type *value_segment;
1474 /* value_size accounts for header and null at end of the index */
1475 value_size = sizeof( RGMTextVector );
1479 ** Determine the size of the string table by adding together
1480 ** the lengths of component strings. Before the string is a
1481 ** table of words. The first word is the number of component
1482 ** string. Next comes the word offsets of each of the strings
1483 ** from the start of the buffer.
1485 for (value_segment=value_entry->az_first_table_value;
1486 value_segment != NULL;
1487 value_segment = value_segment->az_next_table_value)
1492 XmCvtXmStringToByteStream(value_segment->value.xms_value, NULL) +
1493 sizeof( RGMTextEntry );
1499 case sym_k_asciz_table_value:
1501 sym_value_entry_type *value_segment;
1503 /* value_size accounts for header and null at end of the index */
1504 value_size = sizeof( RGMTextVector );
1508 ** Determine the size of the string table by adding together
1509 ** the lengths of component strings. Before the string is a
1510 ** table of words. The first word is the number of component
1511 ** string. Next comes the word offsets of each of the strings
1512 ** from the start of the buffer.
1515 for (value_segment=value_entry->az_first_table_value;
1516 value_segment != NULL;
1517 value_segment = value_segment->az_next_table_value)
1521 value_segment->w_length + sizeof(RGMTextEntry) + 1;
1526 case sym_k_integer_table_value:
1528 sym_value_entry_type *value_segment;
1531 ** The size needed for the vector is the size of the header
1532 ** information followed by the the list of integers. Add in
1533 ** the header size here.
1535 value_size = sizeof( RGMIntegerVector );
1539 ** Determine the size of the integer table by adding together
1540 ** the lengths of component integers to the header.
1543 for (value_segment = value_entry->az_first_table_value;
1544 value_segment != NULL;
1545 value_segment = value_segment->az_next_table_value)
1547 value_size += sizeof(long);
1554 case sym_k_font_table_value:
1556 sym_value_entry_type *font_value;
1559 * Size is size of basic table, plus strings for all FontItems.
1560 * We allocate one fewer FontItems than specified in the structure
1563 /* value_size accounts for header and null at end of the index */
1564 value_size = sizeof(RGMFontList) - sizeof(RGMFontItem);
1568 ** Determine the size of the font list by adding together
1569 ** the lengths of component fonts. Each component is a FontItem
1570 ** in the list, plus space for the charset name and font name.
1572 for (font_value = value_entry->az_first_table_value;
1574 font_value = font_value->az_next_table_value)
1576 /* Fix for CR 5266 Part 2a -- Pull az_charset_value off of
1577 * font_value, rather than value_entry.
1580 value_size += sizeof(RGMFontItem)
1581 + strlen(sem_charset_name(font_value->b_charset,
1582 font_value->az_charset_value))
1583 + 1 + strlen(font_value->value.c_value) + 1;
1588 case sym_k_trans_table_value:
1590 sym_value_entry_type *value_segment;
1595 ** Determine the length of the translation table by adding
1596 ** together the length of the component strings.
1598 for (value_segment = value_entry->az_first_table_value;
1599 value_segment != NULL;
1600 value_segment = value_segment->az_next_table_value)
1601 value_size += value_segment->w_length + 1;
1606 _assert( FALSE, "unexpected value type" );
1610 ** Check that the context is large enough to hold the value
1613 if ((int)(UrmRCSize( out_az_context ) ) < value_size)
1616 UrmResizeResourceContext( out_az_context, value_size ))
1617 issue_urm_error( "allocating context" );
1618 urm_status = UrmResizeResourceContext( out_az_context, value_size );
1619 if ( urm_status != MrmSUCCESS)
1621 if (urm_status == MrmTOO_MANY)
1623 diag_issue_diagnostic
1624 ( d_value_too_large,
1625 (src_source_record_type *)value_entry->header.az_src_rec,
1627 value_entry->obj_header.az_name->c_text );
1630 issue_urm_error( "allocating context" );
1636 ** Move the literal to the context.
1639 UrmRCSetGroup( out_az_context, URMgLiteral );
1640 UrmRCSetType( out_az_context, value_type );
1641 UrmRCSetAccess( out_az_context, access );
1642 UrmRCSetLock( out_az_context, FALSE );
1643 UrmRCSetSize( out_az_context, value_size );
1645 buffer = (char *) UrmRCBuffer( out_az_context );
1647 bzero( buffer, value_size );
1649 switch (value_entry->b_type)
1651 case sym_k_bool_value:
1652 case sym_k_integer_value:
1653 case sym_k_float_value:
1654 case sym_k_reason_value:
1655 case sym_k_argument_value:
1656 _move( buffer, &value_entry->value.l_integer, value_size );
1659 case sym_k_single_float_value:
1660 _move( buffer, &value_entry->value.single_float, value_size);
1663 case sym_k_char_8_value:
1664 case sym_k_localized_string_value:
1665 case sym_k_identifier_value:
1666 case sym_k_class_rec_name_value:
1667 case sym_k_xbitmapfile_value:
1668 case sym_k_keysym_value:
1669 case sym_k_compound_string_value:
1670 _move( buffer, value_entry->value.c_value, value_size );
1673 /* BEGIN OSF Fix CR 4859 */
1674 case sym_k_wchar_string_value:
1676 RGMWCharEntryPtr wcharentry;
1678 wcharentry = (RGMWCharEntryPtr)buffer;
1680 wcharentry->wchar_item.count = value_size;
1682 _move(wcharentry->wchar_item.bytes,
1683 value_entry->az_first_table_value->value.c_value, value_size);
1686 /* END OSF Fix CR 4859 */
1688 case sym_k_font_value:
1689 case sym_k_fontset_value:
1691 RGMFontItemPtr fontitem;
1697 fontitem = (RGMFontItemPtr) buffer;
1698 textoffs = (MrmOffset) sizeof(RGMFontItem);
1699 textptr = (char *)fontitem+textoffs;
1701 charset_name = sem_charset_name (value_entry->b_charset,
1702 value_entry->az_charset_value);
1703 text_len = strlen(charset_name) + 1;
1705 fontitem->type = Urm_code_from_uil_type(value_entry->b_type);
1706 fontitem->cset.cs_offs = textoffs;
1707 strcpy (textptr, charset_name);
1708 textoffs += text_len;
1709 textptr += text_len;
1710 fontitem->font.font_offs = textoffs;
1711 strcpy (textptr, value_entry->value.c_value);
1716 case sym_k_color_value:
1718 RGMColorDesc *color_buffer;
1720 color_buffer = (RGMColorDesc *)buffer;
1722 switch (value_entry->b_arg_type)
1724 case sym_k_unspecified_color:
1725 color_buffer->mono_state = URMColorMonochromeUnspecified;
1727 case sym_k_foreground_color:
1728 color_buffer->mono_state = URMColorMonochromeForeground;
1730 case sym_k_background_color:
1731 color_buffer->mono_state = URMColorMonochromeBackground;
1735 color_buffer->desc_type = URMColorDescTypeName;
1737 _move( color_buffer->desc.name,
1738 value_entry->value.c_value,
1739 value_entry->w_length + 1 );
1744 case sym_k_rgb_value:
1746 sym_value_entry_type *value_segment;
1747 RGMColorDesc *color_buffer;
1748 int color_vector[3];
1751 color_buffer = (RGMColorDesc *)buffer;
1752 index = value_count;
1755 for (value_segment=value_entry->az_first_table_value;
1756 value_segment != NULL;
1757 value_segment = value_segment->az_next_table_value)
1759 color_vector[index] = (long) value_segment->value.l_integer;
1763 color_buffer->desc_type = URMColorDescTypeRGB;
1764 color_buffer->desc.rgb.red = color_vector[0];
1765 color_buffer->desc.rgb.green = color_vector[1];
1766 color_buffer->desc.rgb.blue = color_vector[2];
1767 color_buffer->mono_state = URMColorMonochromeUnspecified;
1773 case sym_k_color_table_value:
1774 create_color_table( value_entry, buffer );
1777 case sym_k_icon_value:
1778 create_icon( value_entry, buffer );
1781 case sym_k_string_table_value:
1783 sym_value_entry_type *value_segment;
1787 RGMTextVector *string_vector;
1790 ** Value entries are reversed. Need to fill the buffer
1791 ** from the end to front.
1793 text_offset = value_size;
1794 string_vector = (RGMTextVector *)buffer;
1795 string_vector->validation = URMTextVectorValid;
1796 string_vector->count = value_count;
1797 index = value_count;
1798 string_vector->item[index].pointer = NULL;
1800 for (value_segment=value_entry->az_first_table_value;
1801 value_segment != NULL;
1802 value_segment = value_segment->az_next_table_value)
1804 tmp_str = value_segment->value.xms_value;
1806 XmCvtXmStringToByteStream(tmp_str,
1807 (unsigned char **)&(value_segment->value.c_value));
1808 XmStringFree(tmp_str);
1809 text_offset -= segment_size;
1810 _move(&(buffer[text_offset]),
1811 value_segment->value.c_value, segment_size);
1813 string_vector->item[index].text_item.offset = text_offset;
1814 string_vector->item[index].text_item.rep_type =
1820 case sym_k_asciz_table_value:
1822 sym_value_entry_type *value_segment;
1826 RGMTextVector *string_vector;
1829 ** Value entries are reversed. Need to fill the buffer
1830 ** from the end to front.
1832 text_offset = value_size;
1833 string_vector = (RGMTextVector *)buffer;
1834 string_vector->validation = URMTextVectorValid;
1835 string_vector->count = value_count;
1836 index = value_count;
1837 string_vector->item[index].pointer = NULL;
1839 for (value_segment=value_entry->az_first_table_value;
1840 value_segment != NULL;
1841 value_segment = value_segment->az_next_table_value)
1843 segment_size = value_segment->w_length + 1;
1844 buffer[text_offset-1] = '\0';
1845 text_offset -= segment_size;
1846 _move( &(buffer[text_offset]),
1847 value_segment->value.c_value, segment_size - 1);
1849 string_vector->item[index].text_item.offset = text_offset;
1850 string_vector->item[index].text_item.rep_type = MrmRtypeChar8;
1855 case sym_k_integer_table_value:
1857 sym_value_entry_type *value_segment;
1859 RGMIntegerVector *integer_vector;
1862 ** Fill in the header information
1864 integer_vector = (RGMIntegerVector *)buffer;
1865 integer_vector->validation = URMIntegerVectorValid;
1866 integer_vector->count = value_count;
1869 ** Value entries are reversed. Need to fill the buffer
1870 ** from the end to front.
1872 index = value_count - 1;
1873 for (value_segment=value_entry->az_first_table_value;
1874 value_segment != NULL;
1875 value_segment = value_segment->az_next_table_value)
1877 integer_vector->item [index] =
1878 (long) value_segment->value.l_integer;
1884 case sym_k_font_table_value:
1886 RGMFontListPtr fontlist;
1887 RGMFontItemPtr fontitem;
1888 sym_value_entry_type *font_value;
1896 ** Font items are in correct order.
1898 fontlist = (RGMFontList *)buffer;
1899 fontlist->validation = URMFontListValid;
1900 fontlist->count = value_count;
1903 ** textoffs need to be the offset just beyond the last
1904 ** FontItem in the list. One FontItem is already allocated,
1905 ** so account for it in sizing.
1907 textoffs = sizeof (RGMFontList) +
1908 sizeof(RGMFontItem)*(value_count-1);
1909 textptr = (char *)fontlist+textoffs;
1912 font_value = value_entry->az_first_table_value;
1914 index++, font_value = font_value->az_next_table_value)
1916 fontitem = &fontlist->item[index];
1918 * Fix for CR 5266 Part 2b -- Pull az_charset_value off of
1919 * font_value, rather than value_entry.
1922 sem_charset_name (font_value->b_charset,
1923 font_value->az_charset_value);
1925 fontitem->type = Urm_code_from_uil_type(font_value->b_type);
1926 fontitem->cset.cs_offs = textoffs;
1927 strcpy (textptr, charset_name);
1928 text_len = strlen(charset_name) + 1;
1929 textoffs += text_len;
1930 textptr += text_len;
1931 fontitem->font.font_offs = textoffs;
1932 strcpy (textptr, font_value->value.c_value);
1933 text_len = strlen(font_value->value.c_value) + 1;
1934 textoffs += text_len;
1935 textptr += text_len;
1940 case sym_k_trans_table_value:
1942 sym_value_entry_type *value_segment;
1947 ** Value entries are reversed. Need to fill the buffer
1948 ** from the end to front.
1951 offset = value_size;
1952 for (value_segment = value_entry->az_first_table_value;
1953 value_segment != NULL;
1954 value_segment = value_segment->az_next_table_value)
1956 buffer[offset - 1] = '\n';
1957 segment_size = value_segment->w_length + 1;
1958 offset -= segment_size;
1959 _move( &(buffer[offset]),
1960 value_segment->value.c_value, segment_size-1 );
1962 buffer[value_size - 1] = 0;
1966 case sym_k_horizontal_integer_value:
1967 case sym_k_vertical_integer_value:
1969 RGMUnitsIntegerPtr uiptr;
1971 uiptr = (RGMUnitsIntegerPtr) buffer;
1972 uiptr->value = value_entry->value.l_integer;
1973 uiptr->units = value_entry->b_arg_type;
1977 case sym_k_horizontal_float_value:
1978 case sym_k_vertical_float_value:
1980 RGMUnitsFloatPtr ufptr;
1982 ufptr = (RGMUnitsFloatPtr) buffer;
1983 *((double *)(&ufptr->value[0])) = value_entry->value.d_real;
1984 ufptr->units = value_entry->b_arg_type;
1990 ** Output the literal
1992 if (access == URMaPublic)
1993 urm_status = UrmPutIndexedLiteral
1995 value_entry->obj_header.az_name->c_text,
1998 urm_status = UrmPutRIDLiteral
1999 (out_az_idbfile_id, value_entry->resource_id, out_az_context);
2001 if( urm_status != MrmSUCCESS)
2003 if (urm_status == MrmEOF)
2004 diag_issue_diagnostic ( d_uid_write, diag_k_no_source,
2005 diag_k_no_column, Uil_current_file );
2007 issue_urm_error( "emitting literal" );
2010 if (Uil_cmd_z_command.v_show_machine_code)
2011 save_value_machine_code (value_entry, out_az_context);
2013 value_entry->output_state = sym_k_emitted;
2020 ** FUNCTIONAL DESCRIPTION:
2022 ** This function builds the callback argument for a widget record
2024 ** FORMAL PARAMETERS:
2026 ** callback_entry symbol table pointer for the callback
2027 ** arglist_index index in arglist to place callback
2028 ** (this is an in/out argument)
2029 ** emit_create true: emit a create reason
2030 ** false: skip create reason
2036 ** IMPLICIT OUTPUTS:
2046 ** callback data is added to out_az_context
2053 (sym_callback_entry_type *callback_entry,
2055 boolean emit_create)
2058 sym_value_entry_type *reason_entry;
2059 sym_proc_ref_entry_type *proc_ref_entry_next;
2062 boolean qcreate = FALSE;
2063 MrmOffset callback_offset;
2067 * Count number of entries in callback list
2069 if ( callback_entry->az_call_proc_ref != 0 )
2072 proc_count = count_proc (callback_entry->az_call_proc_ref_list, 0);
2075 ** Reasons can take several forms:
2076 ** 1) create reason: value is builtin - keyword Urm value is "created"
2077 ** this need special handling
2078 ** 2) builtin reasons: value is builtin - keyword Urm value as URM
2079 ** compressed equivalent argument
2080 ** 3) non-builtin private: value is not builtin but private -
2081 ** use an uncompressed argument tag
2082 ** 4) non-builtin public: value is not builtin and public -
2083 ** not supported yet
2086 reason_entry = callback_entry->az_call_reason_name;
2087 if ( reason_entry->obj_header.b_flags & sym_m_builtin )
2089 key_keytable_entry_type *key_entry;
2091 key_entry = (key_keytable_entry_type *) reason_entry->value.l_integer;
2093 (strcmp(uil_reason_toolkit_names[key_entry->b_subclass],
2094 MrmNcreateCallback) == 0);
2098 ** case 1: create reason - return if we are not to emit
2099 ** otherwise use special routine to describe
2101 if ( !emit_create ) return;
2102 urm_status = UrmCWRSetCreationCallback
2106 if( urm_status != MrmSUCCESS)
2108 if (urm_status == MrmEOF)
2109 diag_issue_diagnostic ( d_uid_write, diag_k_no_source,
2110 diag_k_no_column, Uil_current_file );
2112 issue_urm_error ("emitting creation callback");
2119 ** case 2: builtin case - use a compressed argument
2121 urm_status = UrmCWRSetCompressedArgTag
2124 uil_reas_compr[key_entry->b_subclass],
2126 if( urm_status != MrmSUCCESS)
2127 issue_urm_error( "setting compressed arg" );
2133 ** Non private reasons and arguments are not supported
2135 if ( reason_entry->obj_header.b_flags & (sym_m_imported|sym_m_exported) )
2137 diag_issue_diagnostic
2138 (d_not_impl, diag_k_no_source, diag_k_no_column,
2139 "EXPORTED and IMPORTED arguments and reasons" );
2144 ** case 3: private, non-builtin case - use an uncompressed argument
2146 urm_status = UrmCWRSetUncompressedArgTag
2149 reason_entry->value.c_value);
2150 if( urm_status != MrmSUCCESS)
2151 issue_urm_error( "setting uncompressed arg" );
2155 * Create the callback value (this is not done for the create callback)
2159 urm_status = UrmCWRSetArgCallback
2160 (out_az_context, *arglist_index, proc_count, &callback_offset);
2161 if( urm_status != MrmSUCCESS)
2162 issue_urm_error ("setting callback arg");
2166 * Create the callback procedures
2168 if (callback_entry->az_call_proc_ref != 0)
2171 proc_ref_entry_next = callback_entry->az_call_proc_ref;
2175 proc_ref_index = proc_count - 1;
2176 proc_ref_entry_next =
2177 (sym_proc_ref_entry_type *) callback_entry->
2178 az_call_proc_ref_list->obj_header.az_next;
2180 emit_callback_procedures
2181 (proc_ref_entry_next, &proc_ref_index, callback_offset);
2182 *arglist_index = *arglist_index - 1;
2189 ** FUNCTIONAL DESCRIPTION:
2191 ** This function counts the number of procedures in a procedure list
2192 ** including nested procedure lists.
2194 ** FORMAL PARAMETERS:
2196 ** proc_list list of procedures (and nested list entries)
2197 ** count count of procedures encountered so far
2203 ** IMPLICIT OUTPUTS:
2209 ** count of procedures in procedure list
2218 int count_proc(proc_list, count)
2219 sym_list_entry_type *proc_list;
2223 sym_obj_entry_type *proc_list_next;
2225 for (proc_list_next = (sym_obj_entry_type *)proc_list->obj_header.az_next;
2226 proc_list_next != 0;
2227 proc_list_next = (sym_obj_entry_type *)
2228 proc_list_next->obj_header.az_next)
2230 switch (proc_list_next->header.b_tag)
2232 case sym_k_nested_list_entry:
2233 count = count_proc(((sym_nested_list_entry_type *)
2238 case sym_k_proc_ref_entry:
2242 _assert(FALSE, "unknown entry in procedures list");
2251 ** FUNCTIONAL DESCRIPTION:
2253 ** This function output a procedure list referenced by a callback entry
2255 ** FORMAL PARAMETERS:
2257 ** proc_ref_entry_next next procedure reference entry
2258 ** proc_ref_index index of procedure in procedure list (for Mrm)
2259 ** callback_offset offset of callback (for Mrm)
2265 ** IMPLICIT OUTPUTS:
2281 * Fix for CR 4772 - Change the proc_ref_index entry from an integer to an
2282 * integer pointer to allow for proper construction of
2283 * internal callback arrays.
2285 void emit_callback_procedures
2287 (sym_proc_ref_entry_type *proc_ref_entry_next,
2288 int *proc_ref_index,
2289 MrmOffset callback_offset)
2292 sym_proc_def_entry_type *proc_def_entry;
2293 sym_value_entry_type *proc_arg_entry;
2297 MrmResource_id arg_id;
2298 MrmCode arg_type, arg_group;
2300 sym_nested_list_entry_type *nested_proc_list_entry;
2301 sym_list_entry_type *proc_list_entry;
2306 proc_ref_entry_next != 0;
2307 proc_ref_entry_next =
2308 (sym_proc_ref_entry_type *) proc_ref_entry_next->
2312 switch (proc_ref_entry_next->header.b_tag)
2314 case sym_k_nested_list_entry:
2315 nested_proc_list_entry = (sym_nested_list_entry_type *)
2316 proc_ref_entry_next;
2317 proc_list_entry = nested_proc_list_entry->az_list;
2318 emit_callback_procedures (( sym_proc_ref_entry_type *)proc_list_entry->obj_header.az_next,
2322 case sym_k_proc_ref_entry:
2323 proc_def_entry = proc_ref_entry_next->az_proc_def;
2324 proc_arg_entry = proc_ref_entry_next->az_arg_value;
2326 if (proc_arg_entry == NULL)
2328 arg_type = MrmRtypeNull;
2330 arg_form = URMrImmediate;
2334 arg_form = ref_value
2336 &arg_type, &arg_value, &arg_access, &arg_index,
2337 &arg_id, &arg_group );
2340 if (arg_form == URMrImmediate)
2342 UrmCWRSetCallbackItem
2343 ( out_az_context, callback_offset, *proc_ref_index,
2344 proc_def_entry->obj_header.az_name->c_text,
2349 UrmCWRSetCallbackItemRes
2350 ( out_az_context, callback_offset, *proc_ref_index,
2351 proc_def_entry->obj_header.az_name->c_text,
2359 if( urm_status != MrmSUCCESS)
2360 issue_urm_error( "setting callback proc" );
2361 *proc_ref_index = *proc_ref_index - 1;
2364 case sym_k_error_entry:
2367 _assert (FALSE, "unknown entry in procedures list");
2375 ** FUNCTIONAL DESCRIPTION:
2377 ** This function builds an argument for a widget record
2379 ** FORMAL PARAMETERS:
2381 ** argument_entry symbol table pointer for the argument
2382 ** arglist_index index in arglist to place argument
2388 ** IMPLICIT OUTPUTS:
2398 ** argument data is added to out_az_context
2403 void emit_argument( argument_entry, arglist_index, related_arg_count )
2405 sym_argument_entry_type *argument_entry;
2407 int *related_arg_count;
2410 sym_value_entry_type *arg_name_entry;
2411 sym_value_entry_type *arg_value_entry;
2415 MrmResource_id arg_id;
2416 MrmCode arg_type, arg_group;
2418 unsigned char expected_type;
2423 * For an argument, we must:
2424 * 1) create the argument
2425 * 2) create the argument value
2428 arg_name_entry = argument_entry->az_arg_name;
2429 if (arg_name_entry->obj_header.b_flags & sym_m_builtin)
2431 key_keytable_entry_type *key_entry;
2433 key_entry = (key_keytable_entry_type *)arg_name_entry->value.l_integer;
2435 urm_status = UrmCWRSetCompressedArgTag
2438 uil_arg_compr[key_entry->b_subclass],
2439 uil_arg_compr[related_argument_table[key_entry->b_subclass]]);
2440 if ( related_argument_table[key_entry->b_subclass] != 0 )
2441 *related_arg_count += 1;
2442 if( urm_status != MrmSUCCESS)
2443 issue_urm_error( "setting compressed arg" );
2448 ** Non private reasons and arguments are not supported
2451 if ( arg_name_entry->obj_header.b_flags & (sym_m_imported|sym_m_exported) )
2453 diag_issue_diagnostic
2454 (d_not_impl, diag_k_no_source, diag_k_no_column,
2455 "EXPORTED and IMPORTED arguments and reasons" );
2460 ** case 3: private, non-builtin case - use an uncompressed argument
2462 urm_status = UrmCWRSetUncompressedArgTag
2465 arg_name_entry->value.c_value);
2466 if( urm_status != MrmSUCCESS)
2467 issue_urm_error( "setting uncompressed arg" );
2471 * Acquire the argument parameters. If it is an immediate value, set it.
2472 * Else set it up as a literal or widget reference. For literal references,
2473 * the expected type must be set up in order to enable coercion in Mrm.
2475 arg_value_entry = argument_entry->az_arg_value;
2476 arg_form = ref_value
2484 if (arg_form == URMrImmediate)
2485 urm_status = UrmCWRSetArgValue
2492 switch ( arg_group )
2495 if ( argument_entry->az_arg_name->obj_header.b_flags &
2498 key_keytable_entry_type * keytable_entry;
2500 keytable_entry = (key_keytable_entry_type *)
2501 argument_entry->az_arg_name->value.l_integer;
2502 _assert (keytable_entry->b_class == tkn_k_class_argument,
2503 "name is not an argument");
2505 argument_type_table[keytable_entry->b_subclass];
2508 expected_type = argument_entry->az_arg_name->b_arg_type;
2509 urm_status = UrmCWRSetArgResourceRef
2514 Urm_code_from_uil_type(expected_type),
2520 urm_status = UrmCWRSetArgResourceRef
2533 if( urm_status != MrmSUCCESS)
2534 issue_urm_error ("setting arg value");
2540 ** FUNCTIONAL DESCRIPTION:
2542 ** This function builds a control for a widget record
2544 ** FORMAL PARAMETERS:
2546 ** control_entry symbol table pointer for the control
2547 ** control_offset offset of object in the control list
2553 ** IMPLICIT OUTPUTS:
2563 ** control data is added to out_az_context
2568 void emit_control( control_entry, control_offset )
2570 sym_control_entry_type *control_entry;
2579 sym_widget_entry_type *widget_entry;
2583 ** 1) Process the object reference
2584 ** 2) set object as a child of current context
2587 form = ref_control( control_entry, &access, &index, &id );
2589 /* Truly gross hack. Fix in WML before beta */
2590 #ifndef sym_k_XmRenderTable_object
2591 #define sym_k_XmRenderTable_object 0
2593 #ifndef sym_k_XmRendition_object
2594 #define sym_k_XmRendition_object 0
2596 #ifndef sym_k_XmTabList_object
2597 #define sym_k_XmTabList_object 0
2599 widget_entry = control_entry->az_con_obj;
2601 while (widget_entry->obj_header.az_reference != NULL)
2603 (sym_widget_entry_type *)widget_entry->obj_header.az_reference;
2605 managed = ((widget_entry->header.b_type != sym_k_XmRenderTable_object) &&
2606 (widget_entry->header.b_type != sym_k_XmRendition_object) &&
2607 (widget_entry->header.b_type != sym_k_XmTabList_object) &&
2608 ((control_entry->obj_header.b_flags & sym_m_managed) != 0));
2611 ** Add the object as a child.
2624 if( urm_status != MrmSUCCESS)
2625 issue_urm_error( "setting child" );
2631 ** FUNCTIONAL DESCRIPTION:
2633 ** This function process a reference to a value.
2635 ** FORMAL PARAMETERS:
2637 ** arg_value_entry (in) value entry to process
2638 ** arg_type (out) URM argument type
2639 ** arg_value (out) argument value if immediate
2640 ** arg_access (out) private or public
2641 ** arg_index (out) index if value is an index
2642 ** arg_id (out) resource id if value is a resource id
2643 ** arg_group (out) URM group (widget or literal)
2649 ** IMPLICIT OUTPUTS:
2655 ** URMrIndex, URMrRID, URMrImmediate (class of value)
2656 ** defines which of the output parameters have meaning
2665 MrmCode ref_value(value_entry,
2666 arg_type, arg_value, arg_access, arg_index, arg_id, arg_group)
2668 sym_value_entry_type *value_entry;
2671 MrmCode *arg_access;
2673 MrmResource_id *arg_id;
2683 *arg_group = URMgLiteral;
2685 /* This value may actually be a widget reference, so check for this
2688 if (value_entry->header.b_tag == sym_k_widget_entry)
2691 /* Set up a dummy control entry, and process the widget reference. */
2693 sym_control_entry_type control_entry;
2694 sym_widget_entry_type * widget_entry;
2696 widget_entry = (sym_widget_entry_type *)value_entry;
2697 control_entry.header.b_tag = sym_k_control_entry;
2698 control_entry.az_con_obj = widget_entry;
2700 *arg_group = URMgWidget;
2701 *arg_type = RGMwrTypeReference;
2703 return ref_control (&control_entry, arg_access, arg_index, arg_id);
2706 *arg_type = Urm_code_from_uil_type( value_entry->b_type );
2708 if (value_entry->obj_header.b_flags & sym_m_private)
2710 *arg_access = URMaPrivate;
2712 switch (value_entry->b_type)
2714 case sym_k_bool_value:
2715 case sym_k_integer_value:
2716 *arg_value = value_entry->value.l_integer;
2717 return URMrImmediate;
2719 case sym_k_float_value:
2720 *arg_value = (long)(&(value_entry->value.d_real));
2721 return URMrImmediate;
2723 case sym_k_single_float_value:
2724 *arg_value = (long)(value_entry->value.single_float);
2725 return URMrImmediate;
2727 case sym_k_char_8_value:
2728 case sym_k_font_value:
2729 case sym_k_fontset_value:
2730 case sym_k_color_value:
2731 case sym_k_reason_value:
2732 case sym_k_argument_value:
2733 case sym_k_trans_table_value:
2734 case sym_k_asciz_table_value:
2735 case sym_k_integer_table_value:
2736 case sym_k_string_table_value:
2737 case sym_k_color_table_value:
2738 case sym_k_icon_value:
2739 case sym_k_font_table_value:
2740 case sym_k_compound_string_value:
2741 case sym_k_identifier_value:
2742 case sym_k_class_rec_name_value:
2743 case sym_k_xbitmapfile_value:
2744 case sym_k_keysym_value:
2745 case sym_k_rgb_value:
2746 case sym_k_wchar_string_value:
2747 case sym_k_localized_string_value:
2748 case sym_k_horizontal_integer_value:
2749 case sym_k_vertical_integer_value:
2750 case sym_k_horizontal_float_value:
2751 case sym_k_vertical_float_value:
2752 if (value_entry->resource_id == 0 )
2756 (out_az_idbfile_id, &(value_entry->resource_id) );
2757 if ( urm_status != MrmSUCCESS )
2758 issue_urm_error( "obtaining resource id" );
2761 if (value_entry->output_state == sym_k_not_processed)
2763 value_entry->output_state = sym_k_queued;
2764 push((sym_entry_type *) value_entry );
2767 *arg_id = value_entry->resource_id;
2771 _assert( FALSE, "unexpected value type" );
2772 return URMrImmediate;
2778 ** Only Imported and Exported Values reach this point
2781 *arg_access = URMaPublic;
2782 *arg_index = (char *)(value_entry->obj_header.az_name->c_text);
2784 if ((value_entry->obj_header.b_flags & sym_m_exported) &&
2785 (value_entry->output_state == sym_k_not_processed))
2787 value_entry->output_state = sym_k_queued;
2788 push((sym_entry_type *) value_entry );
2797 ** FUNCTIONAL DESCRIPTION:
2799 ** This function process a reference to a control (widget or gadget)
2801 ** FORMAL PARAMETERS:
2803 ** control_entry (in) control entry for widget reference
2804 ** access (out) private or public
2805 ** index (out) index if widget is an index
2806 ** id (out) resource id if widget is a resource id
2812 ** IMPLICIT OUTPUTS:
2818 ** URMrIndex, URMrRID (class of control)
2819 ** defines which of the output parameters have meaning
2828 MrmCode ref_control(control_entry, access, index, id)
2830 sym_control_entry_type *control_entry;
2837 sym_widget_entry_type *widget_entry;
2841 _assert( control_entry->header.b_tag == sym_k_control_entry,
2842 "expecting a control entry" );
2845 ** For a control, we must:
2846 ** 1) determine if this is a definition or a reference
2847 ** 2) queue the widget to be created if it isn't yet
2848 ** 3) get a resource id for the control if unnamed
2851 widget_entry = control_entry->az_con_obj;
2854 ** If the reference field is set, this is a reference to a control
2855 ** defined elsewhere. Otherwise it is an inline definition.
2858 while (widget_entry->obj_header.az_reference != NULL)
2860 (sym_widget_entry_type *)widget_entry->obj_header.az_reference;
2863 ** Queue the control to be processed if it has not already been
2864 ** emitted or queued for processing.
2867 if ((widget_entry->obj_header.b_flags & (sym_m_exported | sym_m_private))
2869 (widget_entry->output_state == sym_k_not_processed)
2872 widget_entry->output_state = sym_k_queued;
2874 push((sym_entry_type *) widget_entry );
2877 if (widget_entry->obj_header.az_name == NULL)
2880 ** Need a resource id.
2883 if (widget_entry->resource_id == 0 )
2887 ( out_az_idbfile_id, &(widget_entry->resource_id) );
2888 if( urm_status != MrmSUCCESS)
2889 issue_urm_error( "obtaining resource id" );
2893 *id = widget_entry->resource_id;
2903 *index = widget_entry->obj_header.az_name->c_text;
2907 *access = URMaPublic;
2909 if (widget_entry->obj_header.b_flags & sym_m_private)
2910 *access = URMaPrivate;
2919 ** FUNCTIONAL DESCRIPTION:
2921 ** This function issue a diagnostic for an error detected by URM.
2923 ** FORMAL PARAMETERS:
2925 ** problem string indicating what p2_output was trying to do
2929 ** out_az_context context in error (hold further info about error)
2931 ** IMPLICIT OUTPUTS:
2941 ** diagnostic is issued - compilation stops
2946 void issue_urm_error( problem )
2953 sprintf(buffer, "while %s encountered %s",
2955 Urm__UT_LatestErrorMessage());
2957 diag_issue_internal_error( buffer );
2963 * PROCEDURE DESCRIPTION:
2965 * This procedure maps uil literal type to Urm equivalent types
2967 * FORMAL PARAMETERS:
2969 * uil_type uil types sym_k_..._value
2981 * corresponding RGMrType... code
2990 MrmCode Urm_code_from_uil_type( uil_type )
2998 case sym_k_integer_value: return MrmRtypeInteger;
2999 case sym_k_horizontal_integer_value: return MrmRtypeHorizontalInteger;
3000 case sym_k_vertical_integer_value: return MrmRtypeVerticalInteger;
3001 case sym_k_bool_value: return MrmRtypeBoolean;
3002 case sym_k_char_8_value: return MrmRtypeChar8;
3003 case sym_k_localized_string_value: return MrmRtypeChar8;
3004 case sym_k_argument_value: return MrmRtypeChar8;
3005 case sym_k_reason_value: return MrmRtypeChar8;
3006 case sym_k_trans_table_value: return MrmRtypeTransTable;
3007 case sym_k_asciz_table_value: return MrmRtypeChar8Vector;
3008 case sym_k_string_table_value: return MrmRtypeCStringVector;
3009 case sym_k_compound_string_value: return MrmRtypeCString;
3010 case sym_k_wchar_string_value: return MrmRtypeWideCharacter;
3011 case sym_k_integer_table_value: return MrmRtypeIntegerVector;
3012 case sym_k_color_value: return MrmRtypeColor;
3013 case sym_k_color_table_value: return MrmRtypeColorTable;
3014 case sym_k_icon_value: return MrmRtypeIconImage;
3015 case sym_k_float_value: return MrmRtypeFloat;
3016 case sym_k_horizontal_float_value: return MrmRtypeHorizontalFloat;
3017 case sym_k_vertical_float_value: return MrmRtypeVerticalFloat;
3018 case sym_k_font_value: return MrmRtypeFont;
3019 case sym_k_fontset_value: return MrmRtypeFontSet;
3020 case sym_k_font_table_value: return MrmRtypeFontList;
3021 case sym_k_identifier_value: return MrmRtypeAddrName;
3022 case sym_k_class_rec_name_value: return MrmRtypeClassRecName;
3023 case sym_k_xbitmapfile_value: return MrmRtypeXBitmapFile;
3024 case sym_k_widget_ref_value: return MrmRtypeAny;
3025 case sym_k_pixmap_value: return MrmRtypeIconImage;
3026 case sym_k_any_value: return MrmRtypeAny;
3027 case sym_k_keysym_value: return MrmRtypeKeysym;
3028 case sym_k_single_float_value: return MrmRtypeSingleFloat;
3029 case sym_k_rgb_value: return MrmRtypeColor;
3032 _assert( FALSE, "unknown value type" );
3042 ** FUNCTIONAL DESCRIPTION:
3044 ** This function computes the size of a color table.
3046 ** FORMAL PARAMETERS:
3048 ** table_entry value entry for the color table
3054 ** IMPLICIT OUTPUTS:
3060 ** size of the color table
3064 ** colors within the color table may be allocated
3069 int compute_color_table_size(table_entry)
3071 sym_value_entry_type *table_entry;
3074 sym_value_entry_type *color_entry;
3081 MrmResource_id arg_id;
3085 ** Compute the size of the ColorTable plus the size of the Color
3086 ** table entries (one per color including fore and back ground).
3087 ** Multiply entry size by max_index rather than max_index + 1
3088 ** since RGMColorTable includes 1 entry. Note that descriptors
3089 ** are sized to consume fullword-aligned blocks of memory in
3090 ** to preserve alignment for processors requiring such alignment.
3093 size = sizeof(RGMColorTable) +
3094 sizeof(RGMColorTableEntry)*table_entry->b_max_index;
3095 size = _FULLWORD (size);
3098 ** Compute space needed for resource descriptors for the colors.
3101 for (i = 0; i < (int)table_entry->b_table_count; i++)
3103 color_entry = table_entry->value.z_color[i].az_color;
3106 ** Default colors have az_color set to 0=back and 1=fore.
3107 ** These require ColorTableEntries but no resource descriptors.
3110 if ((long)color_entry > 1)
3113 ** Call ref_value for each of the colors in the color table.
3114 ** This will cause them to be created if necessary and also
3115 ** classify the type of resource needed.
3118 table_entry->value.z_color[i].w_desc_offset = size;
3120 switch (ref_value( color_entry,
3121 & arg_type, & arg_value, & arg_access,
3122 & arg_index, & arg_id, & arg_group ) )
3125 size += sizeof (RGMResourceDesc);
3126 size = _FULLWORD (size);
3129 size += sizeof(RGMResourceDesc) - sizeof(MrmResource_id) +
3130 strlen(arg_index)+1;
3131 size = _FULLWORD (size);
3134 _assert( FALSE, "immediate color values not supported" );
3139 table_entry->w_length = size;
3147 ** FUNCTIONAL DESCRIPTION:
3149 ** This function creates a color table in a context.
3151 ** FORMAL PARAMETERS:
3153 ** table_entry value entry for the color table
3154 ** buffer pointer to a context buffer
3160 ** IMPLICIT OUTPUTS:
3175 void create_color_table(table_entry, buffer)
3177 sym_value_entry_type *table_entry;
3181 RGMColorTable *table;
3182 RGMColorTableEntry *item;
3183 RGMResourceDesc *desc;
3190 MrmResource_id arg_id;
3194 ** Fill in the Color Table fields
3197 table = (RGMColorTable *)buffer;
3199 table->validation = URMColorTableValid;
3200 table->count = table_entry->b_max_index + 1;
3203 ** Loop thru the colors in the table setting up both the index
3204 ** of offset for the colors and their resource descriptors.
3209 for (i = 0; i < (int)table_entry->b_table_count; i++)
3213 index = table_entry->value.z_color[i].b_index;
3214 table->item[index].color_item.coffs =
3215 table_entry->value.z_color[i].w_desc_offset;
3216 desc = (RGMResourceDesc *)
3217 (buffer + table_entry->value.z_color[i].w_desc_offset);
3220 ** Default colors have b_index set to 0=back and 1=fore.
3221 ** These require ColorTableEntries but no resource descriptors.
3226 table->item[index].type = MrmRtypeResource;
3229 ** Call ref_value for each of the colors in the color table.
3230 ** This provide the necessary info to fill in the resource
3234 arg_form = ref_value( table_entry->value.z_color[i].az_color,
3235 & arg_type, & arg_value, & arg_access,
3236 & arg_index, & arg_id, & arg_group );
3238 desc->access = arg_access;
3239 desc->type = arg_form;
3240 desc->res_group = arg_group;
3241 desc->cvt_type = arg_type;
3246 desc->size = sizeof( RGMResourceDesc );
3247 desc->key.id = arg_id;
3250 desc->size = strlen( arg_index ) + 1;
3251 _move( desc->key.index, arg_index, desc->size );
3252 desc->size += sizeof( RGMResourceDesc ) -
3253 sizeof( MrmResource_id );
3256 _assert( FALSE, "immediate color values not supported" );
3265 ** FUNCTIONAL DESCRIPTION:
3267 ** This function computes the size of an icon.
3269 ** FORMAL PARAMETERS:
3271 ** icon_entry value entry for the icon
3277 ** IMPLICIT OUTPUTS:
3287 ** color table within the icon may be allocated
3292 int compute_icon_size(icon_entry)
3294 sym_value_entry_type *icon_entry;
3303 MrmResource_id arg_id;
3307 ** The size of the icon consist of the size of the RGMIconImage
3308 ** structure + the size of the color table resource descriptor
3309 ** + the actual data.
3312 size = sizeof( RGMIconImage );
3315 ** Compute space needed for the color table resource descriptor
3318 ** This will cause the table to be created if necessary and also
3319 ** classify the type of resource needed.
3322 switch (ref_value( icon_entry->value.z_icon->az_color_table,
3323 & arg_type, & arg_value, & arg_access,
3324 & arg_index, & arg_id, & arg_group ) )
3327 size += sizeof( RGMResourceDesc );
3330 size += sizeof( RGMResourceDesc ) - sizeof( MrmResource_id ) +
3331 strlen( arg_index ) + 1;
3334 _assert( FALSE, "immediate color table values not supported" );
3338 ** Save the offset of the data for later.
3341 icon_entry->b_data_offset = size;
3344 ** Bits per pixel is based on the number of colors used.
3346 ** 0 for 1 bit pixels
3347 ** 1 for 2 bit pixels
3348 ** 2 for 4 bit pixels
3349 ** 3 for 8 bit pixels
3350 ** URM's pixels size encoding is pixel_type + 1
3351 ** Pixel_size = 1 << pixel_type
3354 pixel_type = icon_entry->value.z_icon->az_color_table->b_max_index;
3358 else if (pixel_type < 4)
3360 else if (pixel_type < 16)
3365 icon_entry->b_pixel_type = pixel_type;
3368 ** Size is width * height - each row must be an even number of bytes
3371 size += ((int)((icon_entry->value.z_icon->w_width << pixel_type) + 7) / 8)
3372 * icon_entry->value.z_icon->w_height;
3374 icon_entry->w_length = size;
3382 ** FUNCTIONAL DESCRIPTION:
3384 ** This function creates an icon in a context buffer
3386 ** FORMAL PARAMETERS:
3388 ** icon_entry value entry for the icon
3389 ** buffer pointer to context buffer
3395 ** IMPLICIT OUTPUTS:
3405 ** buffer is filled in
3410 void create_icon(icon_entry,buffer)
3412 sym_value_entry_type *icon_entry;
3416 sym_value_entry_type *row_entry;
3418 RGMResourceDesc *desc;
3424 MrmResource_id arg_id;
3427 unsigned char *sbyte;
3428 unsigned char *tbyte;
3435 char pixel_per_byte;
3438 ** Fill in the fixed location fields of the IconImage.
3441 icon = (RGMIconImage *)buffer;
3443 icon->validation = URMIconImageValid;
3444 pixel_type = icon_entry->b_pixel_type;
3445 icon->pixel_size = pixel_type + 1;
3446 icon->width = icon_entry->value.z_icon->w_width;
3447 icon->height = icon_entry->value.z_icon->w_height;
3448 icon->ct_type = MrmRtypeResource;
3449 icon->color_table.ctoff = sizeof( RGMIconImage );
3450 icon->pixel_data.pdoff = icon_entry->b_data_offset;
3453 ** Place color table resource descriptor in the context.
3455 ** Call ref_value which will return all info need to complete
3459 arg_form = ref_value( icon_entry->value.z_icon->az_color_table,
3460 & arg_type, & arg_value, & arg_access,
3461 & arg_index, & arg_id, & arg_group );
3463 desc = (RGMResourceDesc *)(buffer + sizeof( RGMIconImage ));
3465 desc->access = arg_access;
3466 desc->type = arg_form;
3467 desc->res_group = arg_group;
3468 desc->cvt_type = MrmRtypeResource;
3473 desc->size = sizeof( RGMResourceDesc );
3474 desc->key.id = arg_id;
3477 desc->size = strlen( arg_index ) + 1;
3478 _move( desc->key.index, arg_index, desc->size );
3479 desc->size += sizeof( RGMResourceDesc ) -
3480 sizeof( MrmResource_id );
3483 _assert( FALSE, "immediate color values not supported" );
3487 ** Now move the pixels into the buffer
3489 ** sbyte: base of source byte stream
3490 ** tbyte: current position in target byte stream
3491 ** w_len: # of pixels that will go into integral # of bytes
3492 ** p_len: # of pixels that will go into final byte
3495 pixel_per_byte = 8 >> pixel_type;
3496 pixel_size = 1 << pixel_type;
3498 tbyte = (unsigned char *)(buffer + icon_entry->b_data_offset);
3500 for (row_entry = icon_entry->value.z_icon->az_rows,
3501 w_len = ((int)row_entry->w_length / (int)pixel_per_byte) * pixel_per_byte,
3502 p_len = row_entry->w_length - w_len;
3506 row_entry = row_entry->az_next_table_value)
3508 sbyte = (unsigned char *)row_entry->value.c_value;
3510 for (i = 0; i < w_len; tbyte++)
3512 for (*tbyte = 0, j = 0;
3518 t = sbyte[i++] << j;
3525 for ( *tbyte = 0, j = 0;
3526 j < (p_len * pixel_size);
3531 t = sbyte[i++] << j;
3543 ** FUNCTIONAL DESCRIPTION:
3545 ** This function counts the number of valid, usable entries in a
3546 ** list. It simply accumulates all the nodes in the list (recursively)
3547 ** which match the given node type.
3549 ** FORMAL PARAMETERS:
3551 ** list_entry the list to be counted
3552 ** type the node type to match
3556 ** IMPLICIT OUTPUTS:
3560 ** the number of nodes which matched the type
3567 int compute_list_size (list_entry, type)
3568 sym_list_entry_type *list_entry;
3576 sym_obj_entry_type *list_member;
3577 sym_nested_list_entry_type *nested_list_entry;
3581 * loop down the list
3583 if ( list_entry == NULL ) return 0;
3584 for (list_member=(sym_obj_entry_type *)list_entry->obj_header.az_next;
3586 list_member=(sym_obj_entry_type *)list_member->obj_header.az_next)
3587 switch ( list_member->header.b_tag )
3589 case sym_k_nested_list_entry:
3590 nested_list_entry = (sym_nested_list_entry_type *) list_member;
3591 count += compute_list_size (nested_list_entry->az_list, type);
3594 if ( list_member->header.b_tag == (char)type )
3605 ** FUNCTIONAL DESCRIPTION:
3607 ** This routine creates the internal compression code tables.
3609 ** Upon calling this routine, the internal compression code tables
3610 ** (uil_arg_compr, uil_reas_compr, and uil_widget_compr) have zero
3611 ** entries for resources which have not been referenced in this UIL
3612 ** module and have one entries for resrources which have been referenced.
3614 ** This routine assigns increasing integers to each non-zero entry in the
3615 ** internal compression code tables.
3617 ** The internal compression code tables are indexed by subclass to yield
3618 ** the external compression code values which are written to the UID file.
3620 ** FORMAL PARAMETERS:
3630 ** IMPLICIT OUTPUTS:
3645 void create_int_compression_codes ()
3652 int compression_code = 2;
3655 ** Request compression codes for all subtree resources.
3658 for ( i=0 ; i<uil_max_object ; i++ )
3659 if ( uil_urm_subtree_resource[i] != 0 )
3660 uil_arg_compr[uil_urm_subtree_resource[i]] = 1;
3663 ** Create compression code tables for object classes. This include
3664 ** both widgets and gadgets, since both have class literals.
3668 for (i = 0 ; i <= uil_max_object; i++)
3670 if (uil_widget_compr[i] == 1)
3671 uil_widget_compr[i] = compression_code++;
3675 ** Create compression code tables for arguments
3679 compression_code = 2;
3680 for (i = 0 ; i <= uil_max_arg ; i++)
3682 if (uil_arg_compr[i] == 1)
3683 uil_arg_compr[i] = compression_code++;
3687 ** Create compression code tables for reasons.
3688 ** Note that the numbering continues from where we left off with args.
3692 i <= uil_max_reason;
3695 if (uil_reas_compr[i] == 1)
3696 uil_reas_compr[i] = compression_code++;
3700 ** Create compression code tables for automatic children.
3701 ** Note that numbering continues where we left off with reasons.
3703 for (i = 0; i <= uil_max_child; i++)
3705 if (uil_child_compr[i] == 1)
3706 uil_child_compr[i] = compression_code++;
3714 ** FUNCTIONAL DESCRIPTION:
3716 ** This routine creates the external compression code tables.
3719 ** This routine writes the corresponding toolkit name to the external
3720 ** compression code table for each non-zero entry in the internal
3721 ** compression code table.
3723 ** The internal compression code tables are indexed by subclass to yield
3724 ** the external compression code values which are written to the UID file.
3725 ** The external compression codes are used as an index to the external
3726 ** compression code tables so that MRM can map the compression code into
3727 ** the corresponding toolkit name.
3729 ** FORMAL PARAMETERS:
3739 ** IMPLICIT OUTPUTS:
3741 ** extern_args_compr
3742 ** extern_widget_compr
3743 ** %ArgCmpr (index for argument compression table in UID file)
3744 ** %ReasCmpr (index for reason compression table in UID file)
3745 ** %ClassCmpr (index for class compression table in UID file)
3756 void create_ext_compression_codes ()
3766 int arg_value_count;
3769 int class_value_count;
3770 int class_value_size;
3775 ** Create compression code tables for arguments
3777 ** Determine number of elements in external compression table
3778 ** ( extern_arg_compr[] ) and size of external compression table.
3781 arg_value_size = sizeof (UidCompressionTable);
3782 arg_value_count = UilMrmReservedCodeCount;
3783 next_code = UilMrmMinValidCode;
3788 if (uil_arg_compr[i] != 0)
3792 if (uil_argument_toolkit_names[i] == NULL)
3794 _assert (FALSE, "unknown argument")
3797 arg_value_size += strlen(uil_argument_toolkit_names[i]) + 1;
3802 ** Add compression codes for reasons
3806 i <= uil_max_reason;
3809 if (uil_reas_compr[i] != 0)
3813 if (uil_reason_toolkit_names[i] == NULL)
3815 _assert (FALSE, "unknown argument")
3818 arg_value_size += strlen(uil_reason_toolkit_names[i]) + 1;
3823 ** Add compression codes for automatic children
3826 for (i = 0; i <= uil_max_child; i++)
3828 if (uil_child_compr[i] != 0)
3832 arg_value_size += strlen(uil_child_names[i]) + 1;
3837 ** Add the space for the table's vector entries (the next code counts
3838 ** one more space than we need, but as a zero-based code has the
3839 ** correct number in it).
3841 arg_value_size += sizeof(UidCTableEntry) * next_code;
3845 ** Check that the resource context is large enough to hold the value
3848 if ( (int)(UrmRCSize( out_az_context )) < arg_value_size )
3851 UrmResizeResourceContext( out_az_context, arg_value_size ))
3852 issue_urm_error( "allocating context" );
3856 ** Set up the resource context and point extern_arg_compr to the resource
3860 UrmRCSetGroup( out_az_context, URMgLiteral );
3861 UrmRCSetType( out_az_context, sym_k_asciz_table_value );
3862 UrmRCSetAccess( out_az_context, URMaPublic );
3863 UrmRCSetLock( out_az_context, FALSE );
3864 UrmRCSetSize( out_az_context, arg_value_size );
3866 arg_buffer = (char *) UrmRCBuffer( out_az_context );
3868 extern_arg_compr = (UidCompressionTable *)arg_buffer;
3869 bzero (arg_buffer, arg_value_size);
3872 ** Now fill in the actual value of the external compresion code
3873 ** table ( extern_arg_compr[] ).
3876 extern_arg_compr->validation = UidCompressionTableValid;
3877 extern_arg_compr->num_entries = arg_value_count;
3879 text_offset = ((int)&extern_arg_compr->entry[arg_value_count]
3880 - (int)extern_arg_compr) * sizeof(int);
3882 text_offset = (long)&extern_arg_compr->entry[arg_value_count]
3883 - (long)extern_arg_compr;
3885 comp_code = UilMrmMinValidCode;
3886 for ( i = 0 ; i<=uil_max_arg ; i++ )
3888 if (uil_arg_compr[i] != 0)
3890 _move( &(arg_buffer[text_offset]),
3891 uil_argument_toolkit_names[i],
3892 strlen(uil_argument_toolkit_names[i]) + 1);
3893 extern_arg_compr->entry[comp_code].stoffset = text_offset;
3894 text_offset += (strlen(uil_argument_toolkit_names[i]) + 1);
3899 for ( i = 0 ; i<=uil_max_reason ; i++ )
3901 if (uil_reas_compr[i] != 0)
3903 _move( &(arg_buffer[text_offset]),
3904 uil_reason_toolkit_names[i],
3905 strlen(uil_reason_toolkit_names[i]) + 1);
3906 extern_arg_compr->entry[comp_code].stoffset =
3908 text_offset += (strlen(uil_reason_toolkit_names[i]) + 1);
3913 for ( i = 0 ; i<=uil_max_child ; i++ )
3915 if (uil_child_compr[i] != 0)
3919 if (strncmp(uil_child_names[i], AUTO_CHILD_PREFIX,
3920 strlen(AUTO_CHILD_PREFIX)) == 0)
3921 name = (uil_child_names[i] + strlen(AUTO_CHILD_PREFIX));
3922 else name = uil_child_names[i];
3924 _move( &(arg_buffer[text_offset]), name, strlen(name) + 1);
3925 extern_arg_compr->entry[comp_code].stoffset = text_offset;
3926 text_offset += (strlen(name) + 1);
3932 ** Finally write the argument compression code table out to the UID file
3935 UrmPutIndexedLiteral (out_az_idbfile_id,
3936 UilMrmResourceTableIndex, out_az_context);
3937 if (urm_status != MrmSUCCESS)
3939 if (urm_status == MrmEOF)
3940 diag_issue_diagnostic ( d_uid_write, diag_k_no_source,
3941 diag_k_no_column, Uil_current_file );
3943 issue_urm_error("emitting literal");
3948 ** Create compression code tables for classes
3950 ** Determine number of elements in external compression table
3951 ** ( extern_class_compr[] ) and size of external
3952 ** compression table.
3953 ** PROBABL ERROR: WHAT ABOUT GADGETS???
3956 class_value_size = sizeof (UidCompressionTable);
3957 class_value_count = UilMrmReservedCodeCount;
3958 next_code = UilMrmMinValidCode;
3960 i <= uil_max_object;
3962 if (uil_widget_compr[i] != 0)
3964 class_value_count++;
3966 if (uil_widget_funcs[i] == NULL)
3968 _assert (FALSE, "unknown class")
3971 class_value_size += strlen(uil_widget_funcs[i]) + 1;
3975 ** Again, compute the additional size for the vector.
3978 class_value_size += sizeof(UidCTableEntry) * next_code;
3981 ** Check that the resource context is large enough to hold the value
3984 if ( (int)(UrmRCSize(out_az_context)) < class_value_size )
3987 UrmResizeResourceContext( out_az_context, class_value_size ))
3988 issue_urm_error( "allocating context" );
3992 ** Set up the resource context and point extern_class_compr to the resource
3996 UrmRCSetGroup( out_az_context, URMgLiteral );
3997 UrmRCSetType( out_az_context, sym_k_asciz_table_value );
3998 UrmRCSetAccess( out_az_context, URMaPublic );
3999 UrmRCSetLock( out_az_context, FALSE );
4000 UrmRCSetSize( out_az_context, class_value_size );
4002 class_buffer = (char *) UrmRCBuffer( out_az_context );
4004 extern_class_compr = (UidCompressionTable *)class_buffer;
4005 bzero (class_buffer, class_value_size);
4008 ** Now fill in the actual value of the external compresion code
4009 ** table ( extern_class_compr[] ).
4012 extern_class_compr->validation = UidCompressionTableValid;
4013 extern_class_compr->num_entries = class_value_count;
4015 text_offset = ((int)&extern_class_compr->entry[class_value_count]
4016 - (int)extern_class_compr) * sizeof(int);
4018 text_offset = (long)&extern_class_compr->entry[class_value_count]
4019 - (long)extern_class_compr;
4021 comp_code = UilMrmMinValidCode;
4023 i <= uil_max_object;
4026 if (uil_widget_compr[i] != 0)
4028 _move( &(class_buffer[text_offset]),
4029 uil_widget_funcs[i],
4030 strlen(uil_widget_funcs[i]) + 1);
4031 extern_class_compr->entry[comp_code].stoffset =
4033 text_offset += (strlen(uil_widget_funcs[i]) + 1);
4039 ** Finally write the class compression code table out to the UID file
4042 UrmPutIndexedLiteral (out_az_idbfile_id, UilMrmClassTableIndex,
4044 if (urm_status != MrmSUCCESS)
4046 if (urm_status == MrmEOF)
4047 diag_issue_diagnostic ( d_uid_write, diag_k_no_source,
4048 diag_k_no_column, Uil_current_file );
4050 issue_urm_error("emitting literal");