4 # gtk-doc - GTK DocBook documentation generator.
5 # Copyright (C) 1998 Damon Chaplin
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 # This gets information about object heirarchies and signals
24 # by compiling a small C program. CFLAGS and LDFLAGS must be
25 # set appropriately before running this script.
27 # NOTE: the lookup_signal_arg_names() function contains the argument names of
28 # standard GTK signal handlers. This may need to be updated for new
29 # GTK signals or Gnome widget signals.
33 unshift @INC, '/usr/share/gtk-doc/data';
34 require "gtkdoc-common.pl";
38 # name of documentation module
43 my $TYPE_INIT_FUNC="g_type_init ()";
45 # --nogtkinit is deprecated, as it is the default now anyway.
46 %optctl = (module => \$MODULE,
47 types => \$TYPES_FILE,
48 nogtkinit => \$NO_GTK_INIT,
49 'type-init-func' => \$TYPE_INIT_FUNC,
50 'output-dir' => \$OUTPUT_DIR,
51 'version' => \$PRINT_VERSION,
52 'help' => \$PRINT_HELP);
54 GetOptions(\%optctl, "module=s", "types:s", "output-dir:s", "nogtkinit", "type-init-func:s", "version", "help");
57 # Do nothing. This just avoids a warning.
70 print "gtkdoc-scangobj version 1.3\n";
71 print "\n--module=MODULE_NAME Name of the doc module being parsed";
72 print "\n--types=FILE The name of the file to store the types in";
73 print "\n--type-init-func=FUNC The init function to call instead of g_type_init ()";
74 print "\n--output-dir=DIRNAME The directory where the results are stored";
75 print "\n--version Print the version of this program";
76 print "\n--help Print this help\n";
80 $OUTPUT_DIR = $OUTPUT_DIR ? $OUTPUT_DIR : ".";
82 # THOMAS: dynamic types; only use types file for headers
83 $TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$OUTPUT_DIR/$MODULE.types";
85 open TYPES, $TYPES_FILE || die "Cannot open $TYPES_FILE: $!\n";
86 open OUTPUT, ">$MODULE-scan.c" || die "Cannot open $MODULE-scan.c: $!\n";
88 my $old_signals_filename = "$OUTPUT_DIR/$MODULE.signals";
89 my $new_signals_filename = "$OUTPUT_DIR/$MODULE.signals.new";
90 my $old_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy";
91 my $new_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy.new";
92 my $old_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces";
93 my $new_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces.new";
94 my $old_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites";
95 my $new_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites.new";
96 my $old_args_filename = "$OUTPUT_DIR/$MODULE.args";
97 my $new_args_filename = "$OUTPUT_DIR/$MODULE.args.new";
99 # write a C program to scan the types
109 # } elsif (/^\s*$/) {
117 #$ntypes = @types + 1;
125 #ifdef GTK_IS_WIDGET_CLASS
126 #include <gtk/gtkversion.h>
128 gint num_object_types = 0;
129 GType *object_types = NULL;
132 get_object_types (void)
134 GList *plugins = NULL;
135 GList *factories = NULL;
137 GstElementFactory *factory = NULL;
141 /* get the number of types from the registry */
142 plugins = gst_registry_pool_plugin_list ();
148 plugin = (GstPlugin *) (plugins->data);
149 plugins = g_list_next (plugins);
151 features = gst_plugin_get_feature_list (plugin);
153 GstPluginFeature *feature;
154 feature = GST_PLUGIN_FEATURE (features->data);
155 if (!gst_plugin_feature_ensure_loaded (feature)) {
156 g_warning ("Could not load plugin feature %s",
157 gst_plugin_feature_get_name (feature));
160 if (GST_IS_ELEMENT_FACTORY (feature)) {
161 factory = GST_ELEMENT_FACTORY (feature);
162 factories = g_list_append (factories, factory);
164 features = g_list_next (features);
168 num_object_types = g_list_length (factories);
169 g_debug ("number of element factories: %d", g_list_length (factories));
171 /* allocate the object_types array to hold them */
172 object_types = g_new0 (GType, g_list_length (factories));
180 factory = GST_ELEMENT_FACTORY (l->data);
181 g_debug ("adding type for factory %s", gst_element_factory_get_longname (factory));
182 type = gst_element_factory_get_element_type (factory);
183 g_debug ("adding type %p", (void *) type);
184 object_types[i] = type;
192 /* Need to make sure all the types are loaded in and initialize
193 * their signals and properties.
195 g_debug ("class reffing");
197 for (i=0; i < num_object_types; i++) {
198 if (G_TYPE_IS_CLASSED (object_types[i]))
199 g_type_class_ref (object_types[i]);
206 * This uses GTK type functions to output signal prototypes and the widget
210 /* The output files */
211 gchar *signals_filename = "$new_signals_filename";
212 gchar *hierarchy_filename = "$new_hierarchy_filename";
213 gchar *interfaces_filename = "$new_interfaces_filename";
214 gchar *prerequisites_filename = "$new_prerequisites_filename";
215 gchar *args_filename = "$new_args_filename";
218 static void output_signals (void);
219 static void output_widget_signals (FILE *fp,
221 static void output_widget_signal (FILE *fp,
223 const gchar *object_class_name,
225 static const gchar * get_type_name (GType type,
226 gboolean * is_pointer);
227 static gchar * get_gdk_event (const gchar * signal_name);
228 static gchar ** lookup_signal_arg_names (const gchar * type,
229 const gchar * signal_name);
231 static void output_widget_hierarchy (void);
232 static void output_hierarchy (FILE *fp,
236 static void output_widget_interfaces (void);
237 static void output_interfaces (FILE *fp,
240 static void output_interface_prerequisites (void);
241 static void output_prerequisites (FILE *fp,
244 static void output_args (void);
245 static void output_widget_args (FILE *fp, GType object_type);
248 main (int argc, char *argv[])
254 g_debug ("output signals");
256 g_debug ("output widget hierarchy");
257 output_widget_hierarchy ();
258 output_widget_interfaces ();
259 output_interface_prerequisites ();
260 g_debug ("output args");
268 output_signals (void)
273 fp = fopen (signals_filename, "w");
276 g_warning ("Couldn't open output file: %s", signals_filename);
280 for (i = 0; i < num_object_types; i++)
281 output_widget_signals (fp, object_types[i]);
287 compare_signals (const void *a, const void *b)
289 const guint *signal_a = a;
290 const guint *signal_b = b;
292 return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b));
295 /* This outputs all the signals of one widget. */
297 output_widget_signals (FILE *fp, GType object_type)
299 const gchar *object_class_name;
300 guint *signals, n_signals;
303 if (G_TYPE_IS_INSTANTIATABLE (object_type) ||
304 G_TYPE_IS_INTERFACE (object_type))
307 object_class_name = g_type_name (object_type);
309 signals = g_signal_list_ids (object_type, &n_signals);
310 qsort (signals, n_signals, sizeof (guint), compare_signals);
312 for (sig = 0; sig < n_signals; sig++)
314 output_widget_signal (fp, object_type, object_class_name,
322 /* This outputs one signal. */
324 output_widget_signal (FILE *fp,
326 const gchar *object_name,
329 GSignalQuery query_info;
330 const gchar *type_name, *ret_type, *object_arg;
331 gchar *pos, *arg_name, *object_arg_lower;
333 gchar ret_type_buffer[1024], buffer[1024];
336 gint param_num, widget_num, event_num, callback_num;
338 gchar signal_name[128];
341 /* g_print ("Object: %s Type: %i Signal: %u\\n", object_name, object_type,
345 widget_num = event_num = callback_num = 0;
347 g_signal_query (signal_id, &query_info);
349 /* Output the return type and function name. */
350 ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
351 sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
353 /* Output the signal object type and the argument name. We assume the
354 type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
355 convert to lower case for the argument name. */
357 sprintf (pos, "%s ", object_name);
360 if (!strncmp (object_name, "Gtk", 3))
361 object_arg = object_name + 3;
362 else if (!strncmp (object_name, "Gnome", 5))
363 object_arg = object_name + 5;
365 object_arg = object_name;
367 object_arg_lower = g_ascii_strdown (object_arg, -1);
368 sprintf (pos, "*%s\\n", object_arg_lower);
370 if (!strncmp (object_arg_lower, "widget", 6))
372 g_free(object_arg_lower);
374 /* Convert signal name to use underscores rather than dashes '-'. */
375 strcpy (signal_name, query_info.signal_name);
376 for (i = 0; signal_name[i]; i++)
378 if (signal_name[i] == '-')
379 signal_name[i] = '_';
382 /* Output the signal parameters. */
383 arg_names = lookup_signal_arg_names (object_name, signal_name);
385 for (param = 0; param < query_info.n_params; param++)
389 sprintf (pos, "%s\\n", arg_names[param]);
394 type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
396 /* Most arguments to the callback are called "arg1", "arg2", etc.
397 GdkWidgets are called "widget", "widget2", ...
398 GdkEvents are called "event", "event2", ...
399 GtkCallbacks are called "callback", "callback2", ... */
400 if (!strcmp (type_name, "GtkWidget"))
403 arg_num = &widget_num;
405 else if (!strcmp (type_name, "GdkEvent"))
407 type_name = get_gdk_event (signal_name);
409 arg_num = &event_num;
412 else if (!strcmp (type_name, "GtkCallback")
413 || !strcmp (type_name, "GtkCCallback"))
415 arg_name = "callback";
416 arg_num = &callback_num;
421 arg_num = ¶m_num;
423 sprintf (pos, "%s ", type_name);
426 if (!arg_num || *arg_num == 0)
427 sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
429 sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
444 "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n%s</SIGNAL>\\n\\n",
445 object_name, query_info.signal_name, ret_type_buffer, buffer);
449 /* Returns the type name to use for a signal argument or return value, given
450 the GtkType from the signal info. It also sets is_pointer to TRUE if the
451 argument needs a '*' since it is a pointer. */
453 get_type_name (GType type, gboolean * is_pointer)
455 const gchar *type_name;
458 type_name = g_type_name (type);
472 /* These all have normal C type names so they are OK. */
476 /* A GtkString is really a gchar*. */
482 /* We use a gint for both of these. Hopefully a subtype with a decent
483 name will be registered and used instead, as GTK+ does itself. */
487 /* The boxed type shouldn't be used itself, only subtypes. Though we
488 return 'gpointer' just in case. */
492 /* A GParam is really a GParamSpec*. */
500 /* For all GtkObject subclasses we can use the class name with a "*",
501 e.g. 'GtkWidget *'. */
502 if (g_type_is_a (type, G_TYPE_OBJECT))
505 /* All boxed subtypes will be pointers as well. */
506 if (g_type_is_a (type, G_TYPE_BOXED))
509 /* All pointer subtypes will be pointers as well. */
510 if (g_type_is_a (type, G_TYPE_POINTER))
518 get_gdk_event (const gchar * signal_name)
520 static gchar *GbGDKEvents[] =
522 "button_press_event", "GdkEventButton",
523 "button_release_event", "GdkEventButton",
524 "motion_notify_event", "GdkEventMotion",
525 "delete_event", "GdkEvent",
526 "destroy_event", "GdkEvent",
527 "expose_event", "GdkEventExpose",
528 "key_press_event", "GdkEventKey",
529 "key_release_event", "GdkEventKey",
530 "enter_notify_event", "GdkEventCrossing",
531 "leave_notify_event", "GdkEventCrossing",
532 "configure_event", "GdkEventConfigure",
533 "focus_in_event", "GdkEventFocus",
534 "focus_out_event", "GdkEventFocus",
535 "map_event", "GdkEvent",
536 "unmap_event", "GdkEvent",
537 "property_notify_event", "GdkEventProperty",
538 "selection_clear_event", "GdkEventSelection",
539 "selection_request_event", "GdkEventSelection",
540 "selection_notify_event", "GdkEventSelection",
541 "proximity_in_event", "GdkEventProximity",
542 "proximity_out_event", "GdkEventProximity",
543 "drag_begin_event", "GdkEventDragBegin",
544 "drag_request_event", "GdkEventDragRequest",
545 "drag_end_event", "GdkEventDragRequest",
546 "drop_enter_event", "GdkEventDropEnter",
547 "drop_leave_event", "GdkEventDropLeave",
548 "drop_data_available_event", "GdkEventDropDataAvailable",
549 "other_event", "GdkEventOther",
550 "client_event", "GdkEventClient",
551 "no_expose_event", "GdkEventNoExpose",
552 "visibility_notify_event", "GdkEventVisibility",
553 "window_state_event", "GdkEventWindowState",
554 "scroll_event", "GdkEventScroll",
560 for (i = 0; GbGDKEvents[i]; i += 2)
562 if (!strcmp (signal_name, GbGDKEvents[i]))
563 return GbGDKEvents[i + 1];
569 /* This returns argument names to use for some known GTK signals.
570 It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
571 'select_row' and it returns a pointer to an array of argument types and
574 lookup_signal_arg_names (const gchar * type, const gchar * signal_name)
576 /* Each arg array starts with the object type name and the signal name,
577 and then signal arguments follow. */
578 static gchar *GbArgTable[][16] =
580 {"GtkCList", "select_row",
583 "GdkEventButton *event"},
584 {"GtkCList", "unselect_row",
587 "GdkEventButton *event"},
588 {"GtkCList", "click_column",
591 {"GtkCList", "resize_column",
595 {"GtkCList", "extend_selection",
596 "GtkScrollType scroll_type",
598 "gboolean auto_start_selection"},
599 {"GtkCList", "scroll_vertical",
600 "GtkScrollType scroll_type",
602 {"GtkCList", "scroll_horizontal",
603 "GtkScrollType scroll_type",
606 {"GtkCTree", "tree_select_row",
607 "GtkCTreeNode *node",
609 {"GtkCTree", "tree_unselect_row",
610 "GtkCTreeNode *node",
612 {"GtkCTree", "tree_expand",
613 "GtkCTreeNode *node"},
614 {"GtkCTree", "tree_collapse",
615 "GtkCTreeNode *node"},
616 {"GtkCTree", "tree_move",
617 "GtkCTreeNode *node",
618 "GtkCTreeNode *new_parent",
619 "GtkCTreeNode *new_sibling"},
620 {"GtkCTree", "change_focus_row_expansion",
621 "GtkCTreeExpansionType expansion"},
623 {"GtkEditable", "insert_text",
625 "gint new_text_length",
627 {"GtkEditable", "delete_text",
630 {"GtkEditable", "set_editable",
631 "gboolean is_editable"},
632 {"GtkEditable", "move_cursor",
635 {"GtkEditable", "move_word",
637 {"GtkEditable", "move_page",
640 {"GtkEditable", "move_to_row",
642 {"GtkEditable", "move_to_column",
645 {"GtkEditable", "kill_char",
647 {"GtkEditable", "kill_word",
649 {"GtkEditable", "kill_line",
653 {"GtkInputDialog", "enable_device",
654 "GdkDevice *deviceid"},
655 {"GtkInputDialog", "disable_device",
656 "GdkDevice *deviceid"},
658 {"GtkListItem", "extend_selection",
659 "GtkScrollType scroll_type",
661 "gboolean auto_start_selection"},
662 {"GtkListItem", "scroll_vertical",
663 "GtkScrollType scroll_type",
665 {"GtkListItem", "scroll_horizontal",
666 "GtkScrollType scroll_type",
669 {"GtkMenuShell", "move_current",
670 "GtkMenuDirectionType direction"},
671 {"GtkMenuShell", "activate_current",
672 "gboolean force_hide"},
675 {"GtkNotebook", "switch_page",
676 "GtkNotebookPage *page",
678 {"GtkStatusbar", "text_pushed",
681 {"GtkStatusbar", "text_popped",
684 {"GtkTipsQuery", "widget_entered",
687 "gchar *tip_private"},
688 {"GtkTipsQuery", "widget_selected",
691 "gchar *tip_private",
692 "GdkEventButton *event"},
693 {"GtkToolbar", "orientation_changed",
694 "GtkOrientation orientation"},
695 {"GtkToolbar", "style_changed",
696 "GtkToolbarStyle style"},
697 {"GtkWidget", "draw",
698 "GdkRectangle *area"},
699 {"GtkWidget", "size_request",
700 "GtkRequisition *requisition"},
701 {"GtkWidget", "size_allocate",
702 "GtkAllocation *allocation"},
703 {"GtkWidget", "state_changed",
704 "GtkStateType state"},
705 {"GtkWidget", "style_set",
706 "GtkStyle *previous_style"},
708 {"GtkWidget", "install_accelerator",
709 "gchar *signal_name",
713 {"GtkWidget", "add_accelerator",
714 "guint accel_signal_id",
715 "GtkAccelGroup *accel_group",
717 "GdkModifierType accel_mods",
718 "GtkAccelFlags accel_flags"},
720 {"GtkWidget", "parent_set",
721 "GtkObject *old_parent"},
723 {"GtkWidget", "remove_accelerator",
724 "GtkAccelGroup *accel_group",
726 "GdkModifierType accel_mods"},
727 {"GtkWidget", "debug_msg",
729 {"GtkWindow", "move_resize",
734 {"GtkWindow", "set_focus",
735 "GtkWidget *widget"},
737 {"GtkWidget", "selection_get",
738 "GtkSelectionData *data",
741 {"GtkWidget", "selection_received",
742 "GtkSelectionData *data",
745 {"GtkWidget", "drag_begin",
746 "GdkDragContext *drag_context"},
747 {"GtkWidget", "drag_end",
748 "GdkDragContext *drag_context"},
749 {"GtkWidget", "drag_data_delete",
750 "GdkDragContext *drag_context"},
751 {"GtkWidget", "drag_leave",
752 "GdkDragContext *drag_context",
754 {"GtkWidget", "drag_motion",
755 "GdkDragContext *drag_context",
759 {"GtkWidget", "drag_drop",
760 "GdkDragContext *drag_context",
764 {"GtkWidget", "drag_data_get",
765 "GdkDragContext *drag_context",
766 "GtkSelectionData *data",
769 {"GtkWidget", "drag_data_received",
770 "GdkDragContext *drag_context",
773 "GtkSelectionData *data",
782 for (i = 0; GbArgTable[i][0]; i++)
785 if (!strcmp (type, GbArgTable[i][0])
786 && !strcmp (signal_name, GbArgTable[i][1]))
787 return &GbArgTable[i][2];
793 /* This outputs the hierarchy of all widgets which have been initialized,
794 i.e. by calling their XXX_get_type() initialization function. */
796 output_widget_hierarchy (void)
800 fp = fopen (hierarchy_filename, "w");
803 g_warning ("Couldn't open output file: %s", hierarchy_filename);
806 output_hierarchy (fp, G_TYPE_OBJECT, 0);
807 output_hierarchy (fp, G_TYPE_INTERFACE, 0);
811 /* This is called recursively to output the hierarchy of a widget. */
813 output_hierarchy (FILE *fp,
824 for (i = 0; i < level; i++)
826 fprintf (fp, g_type_name (type));
829 children = g_type_children (type, &n_children);
831 for (i=0; i < n_children; i++)
832 output_hierarchy (fp, children[i], level + 1);
837 static void output_widget_interfaces (void)
841 fp = fopen (interfaces_filename, "w");
844 g_warning ("Couldn't open output file: %s", interfaces_filename);
847 output_interfaces (fp, G_TYPE_OBJECT);
852 output_interfaces (FILE *fp,
856 GType *children, *interfaces;
857 guint n_children, n_interfaces;
862 interfaces = g_type_interfaces (type, &n_interfaces);
864 if (n_interfaces > 0)
866 fprintf (fp, g_type_name (type));
867 for (i=0; i < n_interfaces; i++)
868 fprintf (fp, " %s", g_type_name (interfaces[i]));
873 children = g_type_children (type, &n_children);
875 for (i=0; i < n_children; i++)
876 output_interfaces (fp, children[i]);
881 static void output_interface_prerequisites (void)
885 fp = fopen (prerequisites_filename, "w");
888 g_warning ("Couldn't open output file: %s", prerequisites_filename);
891 output_prerequisites (fp, G_TYPE_INTERFACE);
896 output_prerequisites (FILE *fp,
899 #if GLIB_CHECK_VERSION(2,1,0)
901 GType *children, *prerequisites;
902 guint n_children, n_prerequisites;
907 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
909 if (n_prerequisites > 0)
911 fprintf (fp, g_type_name (type));
912 for (i=0; i < n_prerequisites; i++)
913 fprintf (fp, " %s", g_type_name (prerequisites[i]));
916 g_free (prerequisites);
918 children = g_type_children (type, &n_children);
920 for (i=0; i < n_children; i++)
921 output_prerequisites (fp, children[i]);
933 fp = fopen (args_filename, "w");
936 g_warning ("Couldn't open output file: %s", args_filename);
940 for (i = 0; i < num_object_types; i++)
941 output_widget_args (fp, object_types[i]);
947 compare_param_specs (const void *a, const void *b)
949 GParamSpec *spec_a = *(GParamSpec **)a;
950 GParamSpec *spec_b = *(GParamSpec **)b;
952 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
955 /* Its common to have unsigned properties restricted
956 * to the signed range. Therefore we make this look
957 * a bit nicer by spelling out the max constants.
961 describe_double_constant (gdouble value)
965 if (value == G_MAXDOUBLE)
966 desc = g_strdup ("G_MAXDOUBLE");
967 else if (value == G_MINDOUBLE)
968 desc = g_strdup ("G_MINDOUBLE");
969 else if (value == -G_MAXDOUBLE)
970 desc = g_strdup ("-G_MAXDOUBLE");
971 else if (value == G_MAXFLOAT)
972 desc = g_strdup ("G_MAXFLOAT");
973 else if (value == G_MINFLOAT)
974 desc = g_strdup ("G_MINFLOAT");
975 else if (value == -G_MAXFLOAT)
976 desc = g_strdup ("-G_MAXFLOAT");
978 desc = g_strdup_printf ("%lg", value);
984 describe_signed_constant (gint64 value)
988 if (value == G_MAXINT)
989 desc = g_strdup ("G_MAXINT");
990 else if (value == G_MININT)
991 desc = g_strdup ("G_MININT");
992 else if (value == G_MAXUINT)
993 desc = g_strdup ("G_MAXUINT");
994 else if (value == G_MAXLONG)
995 desc = g_strdup ("G_MAXLONG");
996 else if (value == G_MINLONG)
997 desc = g_strdup ("G_MINLONG");
998 else if (value == G_MAXULONG)
999 desc = g_strdup ("G_MAXULONG");
1000 else if (value == G_MAXINT64)
1001 desc = g_strdup ("G_MAXINT64");
1002 else if (value == G_MININT64)
1003 desc = g_strdup ("G_MININT64");
1005 desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
1011 describe_unsigned_constant (guint64 value)
1015 if (value == G_MAXINT)
1016 desc = g_strdup ("G_MAXINT");
1017 else if (value == G_MININT)
1018 desc = g_strdup ("G_MININT");
1019 else if (value == G_MAXUINT)
1020 desc = g_strdup ("G_MAXUINT");
1021 else if (value == G_MAXLONG)
1022 desc = g_strdup ("G_MAXLONG");
1023 else if (value == G_MINLONG)
1024 desc = g_strdup ("G_MINLONG");
1025 else if (value == G_MAXULONG)
1026 desc = g_strdup ("G_MAXULONG");
1027 else if (value == G_MAXINT64)
1028 desc = g_strdup ("G_MAXINT64");
1029 else if (value == G_MININT64)
1030 desc = g_strdup ("G_MININT64");
1031 else if (value == G_MAXUINT64)
1032 desc = g_strdup ("G_MAXUINT64");
1034 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
1040 describe_type (GParamSpec *spec)
1046 if (G_IS_PARAM_SPEC_CHAR (spec))
1048 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1050 lower = describe_signed_constant (pspec->minimum);
1051 upper = describe_signed_constant (pspec->maximum);
1052 if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
1053 desc = g_strdup ("");
1054 else if (pspec->minimum == G_MININT8)
1055 desc = g_strdup_printf ("<= %s", upper);
1056 else if (pspec->maximum == G_MAXINT8)
1057 desc = g_strdup_printf (">= %s", lower);
1059 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1063 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1065 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1067 lower = describe_unsigned_constant (pspec->minimum);
1068 upper = describe_unsigned_constant (pspec->maximum);
1069 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
1070 desc = g_strdup ("");
1071 else if (pspec->minimum == 0)
1072 desc = g_strdup_printf ("<= %s", upper);
1073 else if (pspec->maximum == G_MAXUINT8)
1074 desc = g_strdup_printf (">= %s", lower);
1076 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1080 else if (G_IS_PARAM_SPEC_INT (spec))
1082 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1084 lower = describe_signed_constant (pspec->minimum);
1085 upper = describe_signed_constant (pspec->maximum);
1086 if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
1087 desc = g_strdup ("");
1088 else if (pspec->minimum == G_MININT)
1089 desc = g_strdup_printf ("<= %s", upper);
1090 else if (pspec->maximum == G_MAXINT)
1091 desc = g_strdup_printf (">= %s", lower);
1093 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1097 else if (G_IS_PARAM_SPEC_UINT (spec))
1099 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1101 lower = describe_unsigned_constant (pspec->minimum);
1102 upper = describe_unsigned_constant (pspec->maximum);
1103 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
1104 desc = g_strdup ("");
1105 else if (pspec->minimum == 0)
1106 desc = g_strdup_printf ("<= %s", upper);
1107 else if (pspec->maximum == G_MAXUINT)
1108 desc = g_strdup_printf (">= %s", lower);
1110 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1114 else if (G_IS_PARAM_SPEC_LONG (spec))
1116 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1118 lower = describe_signed_constant (pspec->minimum);
1119 upper = describe_signed_constant (pspec->maximum);
1120 if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
1121 desc = g_strdup ("");
1122 else if (pspec->minimum == G_MINLONG)
1123 desc = g_strdup_printf ("<= %s", upper);
1124 else if (pspec->maximum == G_MAXLONG)
1125 desc = g_strdup_printf (">= %s", lower);
1127 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1131 else if (G_IS_PARAM_SPEC_ULONG (spec))
1133 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1136 lower = describe_unsigned_constant (pspec->minimum);
1137 upper = describe_unsigned_constant (pspec->maximum);
1138 if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
1139 desc = g_strdup ("");
1140 else if (pspec->minimum == 0)
1141 desc = g_strdup_printf ("<= %s", upper);
1142 else if (pspec->maximum == G_MAXULONG)
1143 desc = g_strdup_printf (">= %s", lower);
1145 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1149 else if (G_IS_PARAM_SPEC_INT64 (spec))
1151 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1153 lower = describe_signed_constant (pspec->minimum);
1154 upper = describe_signed_constant (pspec->maximum);
1155 if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
1156 desc = g_strdup ("");
1157 else if (pspec->minimum == G_MININT64)
1158 desc = g_strdup_printf ("<= %s", upper);
1159 else if (pspec->maximum == G_MAXINT64)
1160 desc = g_strdup_printf (">= %s", lower);
1162 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1166 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1168 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1170 lower = describe_unsigned_constant (pspec->minimum);
1171 upper = describe_unsigned_constant (pspec->maximum);
1172 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
1173 desc = g_strdup ("");
1174 else if (pspec->minimum == 0)
1175 desc = g_strdup_printf ("<= %s", upper);
1176 else if (pspec->maximum == G_MAXUINT64)
1177 desc = g_strdup_printf (">= %s", lower);
1179 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1183 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1185 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1187 lower = describe_double_constant (pspec->minimum);
1188 upper = describe_double_constant (pspec->maximum);
1189 if (pspec->minimum == -G_MAXFLOAT && pspec->maximum == G_MAXFLOAT)
1190 desc = g_strdup ("");
1191 else if (pspec->minimum == -G_MAXFLOAT)
1192 desc = g_strdup_printf ("<= %s", upper);
1193 else if (pspec->maximum == G_MAXFLOAT)
1194 desc = g_strdup_printf (">= %s", lower);
1196 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1200 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1202 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1204 lower = describe_double_constant (pspec->minimum);
1205 upper = describe_double_constant (pspec->maximum);
1206 if (pspec->minimum == -G_MAXDOUBLE && pspec->maximum == G_MAXDOUBLE)
1207 desc = g_strdup ("");
1208 else if (pspec->minimum == -G_MAXDOUBLE)
1209 desc = g_strdup_printf ("<= %s", upper);
1210 else if (pspec->maximum == G_MAXDOUBLE)
1211 desc = g_strdup_printf (">= %s", lower);
1213 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1219 desc = g_strdup ("");
1226 describe_default (GParamSpec *spec)
1230 if (G_IS_PARAM_SPEC_CHAR (spec))
1232 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1234 desc = g_strdup_printf ("%d", pspec->default_value);
1236 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1238 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1240 desc = g_strdup_printf ("%u", pspec->default_value);
1242 else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
1244 GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
1246 desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
1248 else if (G_IS_PARAM_SPEC_INT (spec))
1250 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1252 desc = g_strdup_printf ("%d", pspec->default_value);
1254 else if (G_IS_PARAM_SPEC_UINT (spec))
1256 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1258 desc = g_strdup_printf ("%u", pspec->default_value);
1260 else if (G_IS_PARAM_SPEC_LONG (spec))
1262 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1264 desc = g_strdup_printf ("%ld", pspec->default_value);
1266 else if (G_IS_PARAM_SPEC_LONG (spec))
1268 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1270 desc = g_strdup_printf ("%lu", pspec->default_value);
1272 else if (G_IS_PARAM_SPEC_INT64 (spec))
1274 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1276 desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
1278 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1280 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1282 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
1284 else if (G_IS_PARAM_SPEC_UNICHAR (spec))
1286 GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
1288 if (g_unichar_isprint (pspec->default_value))
1289 desc = g_strdup_printf ("'%c'", pspec->default_value);
1291 desc = g_strdup_printf ("%u", pspec->default_value);
1293 else if (G_IS_PARAM_SPEC_ENUM (spec))
1295 GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
1297 GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
1299 desc = g_strdup_printf ("%s", value->value_name);
1301 desc = g_strdup_printf ("%d", pspec->default_value);
1303 else if (G_IS_PARAM_SPEC_FLAGS (spec))
1305 GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
1306 guint default_value;
1309 default_value = pspec->default_value;
1310 acc = g_string_new ("");
1312 while (default_value)
1314 GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
1320 g_string_append (acc, "|");
1321 g_string_append (acc, value->value_name);
1323 default_value &= ~value->value;
1326 if (default_value == 0)
1327 desc = g_string_free (acc, FALSE);
1330 desc = g_strdup_printf ("%d", pspec->default_value);
1331 g_string_free (acc, TRUE);
1334 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1336 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1338 desc = g_strdup_printf ("%g", pspec->default_value);
1340 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1342 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1344 desc = g_strdup_printf ("%lg", pspec->default_value);
1346 else if (G_IS_PARAM_SPEC_STRING (spec))
1348 GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
1350 if (pspec->default_value)
1352 gchar *esc = g_strescape (pspec->default_value, NULL);
1354 desc = g_strdup_printf ("\\"%s\\"", esc);
1359 desc = g_strdup_printf ("NULL");
1363 desc = g_strdup ("");
1371 output_widget_args (FILE *fp, GType object_type)
1374 const gchar *object_class_name;
1376 gchar flags[16], *pos;
1377 GParamSpec **properties;
1379 gboolean child_prop;
1380 gboolean style_prop;
1382 gchar *default_value;
1384 if (G_TYPE_IS_CLASSED (object_type))
1386 class = g_type_class_peek (object_type);
1390 properties = g_object_class_list_properties (class, &n_properties);
1392 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
1393 else if (G_TYPE_IS_INTERFACE (object_type))
1395 class = g_type_default_interface_ref (object_type);
1400 properties = g_object_interface_list_properties (class, &n_properties);
1406 object_class_name = g_type_name (object_type);
1412 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
1413 for (arg = 0; arg < n_properties; arg++)
1415 GParamSpec *spec = properties[arg];
1416 const gchar *nick, *blurb, *dot;
1418 if (spec->owner_type != object_type)
1422 /* We use one-character flags for simplicity. */
1423 if (child_prop && !style_prop)
1427 if (spec->flags & G_PARAM_READABLE)
1429 if (spec->flags & G_PARAM_WRITABLE)
1431 if (spec->flags & G_PARAM_CONSTRUCT)
1433 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
1437 nick = g_param_spec_get_nick (spec);
1438 blurb = g_param_spec_get_blurb (spec);
1442 int str_len = strlen (blurb);
1443 if (str_len > 0 && blurb[str_len - 1] != '.')
1447 type_desc = describe_type (spec);
1448 default_value = describe_default (spec);
1449 fprintf (fp, "<ARG>\\n<NAME>%s::%s</NAME>\\n<TYPE>%s</TYPE>\\n<RANGE>%s</RANGE>\\n<FLAGS>%s</FLAGS>\\n<NICK>%s</NICK>\\n<BLURB>%s%s</BLURB>\\n<DEFAULT>%s</DEFAULT>\\n</ARG>\\n\\n",
1450 object_class_name, g_param_spec_get_name (spec), g_type_name (spec->value_type), type_desc, flags, nick ? nick : "(null)", blurb ? blurb : "(null)", dot, default_value);
1452 g_free (default_value);
1455 g_free (properties);
1457 #ifdef GTK_IS_CONTAINER_CLASS
1458 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
1459 properties = gtk_container_class_list_child_properties (class, &n_properties);
1465 #ifdef GTK_IS_WIDGET_CLASS
1466 #if GTK_CHECK_VERSION(2,1,0)
1467 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
1468 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1482 # Compile and run our file
1484 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
1485 $LD = $ENV{LD} ? $ENV{LD} : $CC;
1486 $CFLAGS = $ENV{CFLAGS} ? $ENV{CFLAGS} : "";
1487 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
1490 if ($CC =~ /libtool/) {
1491 $o_file = "$MODULE-scan.lo"
1493 $o_file = "$MODULE-scan.o"
1496 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c && $LD -o $MODULE-scan $o_file $LDFLAGS";
1498 system($command) == 0 or die "Compilation of scanner failed\n";
1500 system("./$MODULE-scan") == 0 or die "Scan failed\n";
1502 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
1504 &UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
1505 &UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
1506 &UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
1507 &UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
1508 &UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);