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,
48 types => \$TYPES_FILE,
49 nogtkinit => \$NO_GTK_INIT,
50 'type-init-func' => \$TYPE_INIT_FUNC,
51 'output-dir' => \$OUTPUT_DIR,
52 'version' => \$PRINT_VERSION,
53 'help' => \$PRINT_HELP);
55 GetOptions(\%optctl, "module=s", "source=s", "types:s", "output-dir:s", "nogtkinit", "type-init-func:s", "version", "help");
58 # Do nothing. This just avoids a warning.
71 print "gstdoc-scangobj version 1.5\n";
72 print "\n--module=MODULE_NAME Name of the doc module being parsed";
73 print "\n--source=SOURCE_NAME Name of the source module for plugins";
74 print "\n--types=FILE The name of the file to store the types in";
75 print "\n--type-init-func=FUNC The init function to call instead of g_type_init ()";
76 print "\n--output-dir=DIRNAME The directory where the results are stored";
77 print "\n--version Print the version of this program";
78 print "\n--help Print this help\n";
82 $OUTPUT_DIR = $OUTPUT_DIR ? $OUTPUT_DIR : ".";
84 $TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$OUTPUT_DIR/$MODULE.types";
86 open (TYPES, $TYPES_FILE) || die "Cannot open $TYPES_FILE: $!\n";
87 open (OUTPUT, ">$MODULE-scan.c") || die "Cannot open $MODULE-scan.c: $!\n";
89 my $old_signals_filename = "$OUTPUT_DIR/$MODULE.signals";
90 my $new_signals_filename = "$OUTPUT_DIR/$MODULE.signals.new";
91 my $old_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy";
92 my $new_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy.new";
93 my $old_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces";
94 my $new_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces.new";
95 my $old_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites";
96 my $new_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites.new";
97 my $old_args_filename = "$OUTPUT_DIR/$MODULE.args";
98 my $new_args_filename = "$OUTPUT_DIR/$MODULE.args.new";
100 # write a C program to scan the types
113 } elsif (/^type:(.*)$/) {
116 push @impl_types, $t;
123 $ntypes = @types + @impl_types;
133 #ifdef GTK_IS_WIDGET_CLASS
134 #include <gtk/gtkversion.h>
136 GType *object_types = NULL;
139 get_object_types (void)
141 GList *plugins = NULL;
142 GList *factories = NULL;
144 GstElementFactory *factory = NULL;
148 /* get a list of features from plugins in our source module */
149 plugins = gst_registry_get_plugin_list (gst_registry_get_default());
156 plugin = (GstPlugin *) (plugins->data);
157 plugins = g_list_next (plugins);
158 source = gst_plugin_get_source (plugin);
159 /*g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);*/
160 if (!source || strcmp (source, "$SOURCE") != 0) {
163 g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);
166 gst_registry_get_feature_list_by_plugin (gst_registry_get_default (),
169 GstPluginFeature *feature;
170 feature = GST_PLUGIN_FEATURE (features->data);
171 feature = gst_plugin_feature_load (feature);
173 g_warning ("Could not load plugin feature %s",
174 gst_plugin_feature_get_name (feature));
177 if (GST_IS_ELEMENT_FACTORY (feature)) {
178 factory = GST_ELEMENT_FACTORY (feature);
179 factories = g_list_prepend (factories, factory);
181 features = g_list_next (features);
185 g_message ("number of element factories: %d", g_list_length (factories));
187 /* allocate the object_types array to hold them */
188 object_types = g_new0 (GType, g_list_length (factories)+$ntypes+1);
196 factory = GST_ELEMENT_FACTORY (l->data);
197 type = gst_element_factory_get_element_type (factory);
198 g_message ("adding type %p for factory %s", (void *) type, gst_element_factory_get_longname (factory));
199 object_types[i++] = type;
205 # get_type functions:
207 print OUTPUT " object_types[i++] = $_ ();\n";
210 # Implicit types retrieved from GLib:
212 print OUTPUT " object_types[i++] = g_type_from_name (\"$_\");\n";
219 /* Need to make sure all the types are loaded in and initialize
220 * their signals and properties.
222 for (i=0; object_types[i]; i++) {
223 if (G_TYPE_IS_CLASSED (object_types[i]))
224 g_type_class_ref (object_types[i]);
226 g_warning ("not reffing type: %s", g_type_name (object_types[i]));
234 * This uses GObject type functions to output signal prototypes and the object
238 /* The output files */
239 const gchar *signals_filename = "$new_signals_filename";
240 const gchar *hierarchy_filename = "$new_hierarchy_filename";
241 const gchar *interfaces_filename = "$new_interfaces_filename";
242 const gchar *prerequisites_filename = "$new_prerequisites_filename";
243 const gchar *args_filename = "$new_args_filename";
246 static void output_signals (void);
247 static void output_object_signals (FILE *fp,
249 static void output_object_signal (FILE *fp,
250 const gchar *object_class_name,
252 static const gchar * get_type_name (GType type,
253 gboolean * is_pointer);
254 static const gchar * get_gdk_event (const gchar * signal_name);
255 static const gchar ** lookup_signal_arg_names (const gchar * type,
256 const gchar * signal_name);
258 static void output_object_hierarchy (void);
259 static void output_hierarchy (FILE *fp,
263 static void output_object_interfaces (void);
264 static void output_interfaces (FILE *fp,
267 static void output_interface_prerequisites (void);
268 static void output_prerequisites (FILE *fp,
271 static void output_args (void);
272 static void output_object_args (FILE *fp, GType object_type);
275 main (int argc, char *argv[])
277 /* Silence the compiler: */
278 if (argv != argv) argc = argc;
285 output_object_hierarchy ();
286 output_object_interfaces ();
287 output_interface_prerequisites ();
295 output_signals (void)
300 fp = fopen (signals_filename, "w");
303 g_warning ("Couldn't open output file: %s : %s", signals_filename, strerror(errno));
307 for (i = 0; object_types[i]; i++)
308 output_object_signals (fp, object_types[i]);
314 compare_signals (const void *a, const void *b)
316 const guint *signal_a = a;
317 const guint *signal_b = b;
319 return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b));
322 /* This outputs all the signals of one object. */
324 output_object_signals (FILE *fp, GType object_type)
326 const gchar *object_class_name;
327 guint *signals, n_signals;
330 if (G_TYPE_IS_INSTANTIATABLE (object_type) ||
331 G_TYPE_IS_INTERFACE (object_type))
334 object_class_name = g_type_name (object_type);
336 signals = g_signal_list_ids (object_type, &n_signals);
337 qsort (signals, n_signals, sizeof (guint), compare_signals);
339 for (sig = 0; sig < n_signals; sig++)
341 output_object_signal (fp, object_class_name, signals[sig]);
348 /* This outputs one signal. */
350 output_object_signal (FILE *fp,
351 const gchar *object_name,
354 GSignalQuery query_info;
355 const gchar *type_name, *ret_type, *object_arg, *arg_name;
356 gchar *pos, *object_arg_lower;
358 gchar ret_type_buffer[1024], buffer[1024];
360 const gchar **arg_names;
361 gint param_num, widget_num, event_num, callback_num;
363 gchar signal_name[128];
366 /* g_print ("Object: %s Signal: %u\\n", object_name, signal_id);*/
369 widget_num = event_num = callback_num = 0;
371 g_signal_query (signal_id, &query_info);
373 /* Output the return type and function name. */
374 ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
375 sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
377 /* Output the signal object type and the argument name. We assume the
378 type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
379 convert to lower case for the argument name. */
381 sprintf (pos, "%s ", object_name);
384 if (!strncmp (object_name, "Gtk", 3))
385 object_arg = object_name + 3;
386 else if (!strncmp (object_name, "Gnome", 5))
387 object_arg = object_name + 5;
389 object_arg = object_name;
391 object_arg_lower = g_ascii_strdown (object_arg, -1);
392 sprintf (pos, "*%s\\n", object_arg_lower);
394 if (!strncmp (object_arg_lower, "widget", 6))
396 g_free(object_arg_lower);
398 /* Convert signal name to use underscores rather than dashes '-'. */
399 strcpy (signal_name, query_info.signal_name);
400 for (i = 0; signal_name[i]; i++)
402 if (signal_name[i] == '-')
403 signal_name[i] = '_';
406 /* Output the signal parameters. */
407 arg_names = lookup_signal_arg_names (object_name, signal_name);
409 for (param = 0; param < query_info.n_params; param++)
413 sprintf (pos, "%s\\n", arg_names[param]);
418 type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
420 /* Most arguments to the callback are called "arg1", "arg2", etc.
421 GdkWidgets are called "widget", "widget2", ...
422 GdkEvents are called "event", "event2", ...
423 GtkCallbacks are called "callback", "callback2", ... */
424 if (!strcmp (type_name, "GtkWidget"))
427 arg_num = &widget_num;
429 else if (!strcmp (type_name, "GdkEvent"))
431 type_name = get_gdk_event (signal_name);
433 arg_num = &event_num;
436 else if (!strcmp (type_name, "GtkCallback")
437 || !strcmp (type_name, "GtkCCallback"))
439 arg_name = "callback";
440 arg_num = &callback_num;
445 arg_num = ¶m_num;
447 sprintf (pos, "%s ", type_name);
450 if (!arg_num || *arg_num == 0)
451 sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
453 sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
468 /* We use one-character flags for simplicity. */
469 if (query_info.signal_flags & G_SIGNAL_RUN_FIRST)
471 if (query_info.signal_flags & G_SIGNAL_RUN_LAST)
473 if (query_info.signal_flags & G_SIGNAL_RUN_CLEANUP)
475 if (query_info.signal_flags & G_SIGNAL_NO_RECURSE)
477 if (query_info.signal_flags & G_SIGNAL_DETAILED)
479 if (query_info.signal_flags & G_SIGNAL_ACTION)
481 if (query_info.signal_flags & G_SIGNAL_NO_HOOKS)
486 "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n<FLAGS>%s</FLAGS>\\n%s</SIGNAL>\\n\\n",
487 object_name, query_info.signal_name, ret_type_buffer, flags, buffer);
491 /* Returns the type name to use for a signal argument or return value, given
492 the GtkType from the signal info. It also sets is_pointer to TRUE if the
493 argument needs a '*' since it is a pointer. */
495 get_type_name (GType type, gboolean * is_pointer)
497 const gchar *type_name;
500 type_name = g_type_name (type);
514 /* These all have normal C type names so they are OK. */
518 /* A GtkString is really a gchar*. */
524 /* We use a gint for both of these. Hopefully a subtype with a decent
525 name will be registered and used instead, as GTK+ does itself. */
529 /* The boxed type shouldn't be used itself, only subtypes. Though we
530 return 'gpointer' just in case. */
534 /* A GParam is really a GParamSpec*. */
542 /* For all GObject subclasses we can use the class name with a "*",
543 e.g. 'GtkWidget *'. */
544 if (g_type_is_a (type, G_TYPE_OBJECT))
547 if (G_TYPE_IS_CLASSED (type))
550 /* All boxed subtypes will be pointers as well. */
551 if (g_type_is_a (type, G_TYPE_BOXED))
554 /* All pointer subtypes will be pointers as well. */
555 if (g_type_is_a (type, G_TYPE_POINTER))
558 /* But enums are not */
559 if (g_type_is_a (type, G_TYPE_ENUM) ||
560 g_type_is_a (type, G_TYPE_FLAGS))
568 get_gdk_event (const gchar * signal_name)
570 static const gchar *GbGDKEvents[] =
572 "button_press_event", "GdkEventButton",
573 "button_release_event", "GdkEventButton",
574 "motion_notify_event", "GdkEventMotion",
575 "delete_event", "GdkEvent",
576 "destroy_event", "GdkEvent",
577 "expose_event", "GdkEventExpose",
578 "key_press_event", "GdkEventKey",
579 "key_release_event", "GdkEventKey",
580 "enter_notify_event", "GdkEventCrossing",
581 "leave_notify_event", "GdkEventCrossing",
582 "configure_event", "GdkEventConfigure",
583 "focus_in_event", "GdkEventFocus",
584 "focus_out_event", "GdkEventFocus",
585 "map_event", "GdkEvent",
586 "unmap_event", "GdkEvent",
587 "property_notify_event", "GdkEventProperty",
588 "selection_clear_event", "GdkEventSelection",
589 "selection_request_event", "GdkEventSelection",
590 "selection_notify_event", "GdkEventSelection",
591 "proximity_in_event", "GdkEventProximity",
592 "proximity_out_event", "GdkEventProximity",
593 "drag_begin_event", "GdkEventDragBegin",
594 "drag_request_event", "GdkEventDragRequest",
595 "drag_end_event", "GdkEventDragRequest",
596 "drop_enter_event", "GdkEventDropEnter",
597 "drop_leave_event", "GdkEventDropLeave",
598 "drop_data_available_event", "GdkEventDropDataAvailable",
599 "other_event", "GdkEventOther",
600 "client_event", "GdkEventClient",
601 "no_expose_event", "GdkEventNoExpose",
602 "visibility_notify_event", "GdkEventVisibility",
603 "window_state_event", "GdkEventWindowState",
604 "scroll_event", "GdkEventScroll",
610 for (i = 0; GbGDKEvents[i]; i += 2)
612 if (!strcmp (signal_name, GbGDKEvents[i]))
613 return GbGDKEvents[i + 1];
619 /* This returns argument names to use for some known GTK signals.
620 It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
621 'select_row' and it returns a pointer to an array of argument types and
623 static const gchar **
624 lookup_signal_arg_names (const gchar * type, const gchar * signal_name)
626 /* Each arg array starts with the object type name and the signal name,
627 and then signal arguments follow. */
628 static const gchar *GbArgTable[][16] =
630 {"GtkCList", "select_row",
633 "GdkEventButton *event"},
634 {"GtkCList", "unselect_row",
637 "GdkEventButton *event"},
638 {"GtkCList", "click_column",
641 {"GtkCList", "resize_column",
645 {"GtkCList", "extend_selection",
646 "GtkScrollType scroll_type",
648 "gboolean auto_start_selection"},
649 {"GtkCList", "scroll_vertical",
650 "GtkScrollType scroll_type",
652 {"GtkCList", "scroll_horizontal",
653 "GtkScrollType scroll_type",
656 {"GtkCTree", "tree_select_row",
657 "GtkCTreeNode *node",
659 {"GtkCTree", "tree_unselect_row",
660 "GtkCTreeNode *node",
662 {"GtkCTree", "tree_expand",
663 "GtkCTreeNode *node"},
664 {"GtkCTree", "tree_collapse",
665 "GtkCTreeNode *node"},
666 {"GtkCTree", "tree_move",
667 "GtkCTreeNode *node",
668 "GtkCTreeNode *new_parent",
669 "GtkCTreeNode *new_sibling"},
670 {"GtkCTree", "change_focus_row_expansion",
671 "GtkCTreeExpansionType expansion"},
673 {"GtkEditable", "insert_text",
675 "gint new_text_length",
677 {"GtkEditable", "delete_text",
680 {"GtkEditable", "set_editable",
681 "gboolean is_editable"},
682 {"GtkEditable", "move_cursor",
685 {"GtkEditable", "move_word",
687 {"GtkEditable", "move_page",
690 {"GtkEditable", "move_to_row",
692 {"GtkEditable", "move_to_column",
695 {"GtkEditable", "kill_char",
697 {"GtkEditable", "kill_word",
699 {"GtkEditable", "kill_line",
703 {"GtkInputDialog", "enable_device",
704 "GdkDevice *deviceid"},
705 {"GtkInputDialog", "disable_device",
706 "GdkDevice *deviceid"},
708 {"GtkListItem", "extend_selection",
709 "GtkScrollType scroll_type",
711 "gboolean auto_start_selection"},
712 {"GtkListItem", "scroll_vertical",
713 "GtkScrollType scroll_type",
715 {"GtkListItem", "scroll_horizontal",
716 "GtkScrollType scroll_type",
719 {"GtkMenuShell", "move_current",
720 "GtkMenuDirectionType direction"},
721 {"GtkMenuShell", "activate_current",
722 "gboolean force_hide"},
725 {"GtkNotebook", "switch_page",
726 "GtkNotebookPage *page",
728 {"GtkStatusbar", "text_pushed",
731 {"GtkStatusbar", "text_popped",
734 {"GtkTipsQuery", "widget_entered",
737 "gchar *tip_private"},
738 {"GtkTipsQuery", "widget_selected",
741 "gchar *tip_private",
742 "GdkEventButton *event"},
743 {"GtkToolbar", "orientation_changed",
744 "GtkOrientation orientation"},
745 {"GtkToolbar", "style_changed",
746 "GtkToolbarStyle style"},
747 {"GtkWidget", "draw",
748 "GdkRectangle *area"},
749 {"GtkWidget", "size_request",
750 "GtkRequisition *requisition"},
751 {"GtkWidget", "size_allocate",
752 "GtkAllocation *allocation"},
753 {"GtkWidget", "state_changed",
754 "GtkStateType state"},
755 {"GtkWidget", "style_set",
756 "GtkStyle *previous_style"},
758 {"GtkWidget", "install_accelerator",
759 "gchar *signal_name",
763 {"GtkWidget", "add_accelerator",
764 "guint accel_signal_id",
765 "GtkAccelGroup *accel_group",
767 "GdkModifierType accel_mods",
768 "GtkAccelFlags accel_flags"},
770 {"GtkWidget", "parent_set",
771 "GtkObject *old_parent"},
773 {"GtkWidget", "remove_accelerator",
774 "GtkAccelGroup *accel_group",
776 "GdkModifierType accel_mods"},
777 {"GtkWidget", "debug_msg",
779 {"GtkWindow", "move_resize",
784 {"GtkWindow", "set_focus",
785 "GtkWidget *widget"},
787 {"GtkWidget", "selection_get",
788 "GtkSelectionData *data",
791 {"GtkWidget", "selection_received",
792 "GtkSelectionData *data",
795 {"GtkWidget", "drag_begin",
796 "GdkDragContext *drag_context"},
797 {"GtkWidget", "drag_end",
798 "GdkDragContext *drag_context"},
799 {"GtkWidget", "drag_data_delete",
800 "GdkDragContext *drag_context"},
801 {"GtkWidget", "drag_leave",
802 "GdkDragContext *drag_context",
804 {"GtkWidget", "drag_motion",
805 "GdkDragContext *drag_context",
809 {"GtkWidget", "drag_drop",
810 "GdkDragContext *drag_context",
814 {"GtkWidget", "drag_data_get",
815 "GdkDragContext *drag_context",
816 "GtkSelectionData *data",
819 {"GtkWidget", "drag_data_received",
820 "GdkDragContext *drag_context",
823 "GtkSelectionData *data",
832 for (i = 0; GbArgTable[i][0]; i++)
835 if (!strcmp (type, GbArgTable[i][0])
836 && !strcmp (signal_name, GbArgTable[i][1]))
837 return &GbArgTable[i][2];
843 /* This outputs the hierarchy of all objects which have been initialized,
844 i.e. by calling their XXX_get_type() initialization function. */
846 output_object_hierarchy (void)
851 fp = fopen (hierarchy_filename, "w");
854 g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, strerror(errno));
857 output_hierarchy (fp, G_TYPE_OBJECT, 0);
858 output_hierarchy (fp, G_TYPE_INTERFACE, 0);
860 for (i=0; object_types[i]; i++) {
861 if (!g_type_parent (object_types[i]) &&
862 (object_types[i] != G_TYPE_NONE) &&
863 (object_types[i] != G_TYPE_OBJECT) &&
864 (object_types[i] != G_TYPE_INTERFACE)
866 g_warning ("printing hierarchy for root type: %s",
867 g_type_name (object_types[i]));
868 output_hierarchy (fp, object_types[i], 0);
872 for (i=0; object_types[i]; i++) {
873 if(object_types[i] != G_TYPE_NONE) {
874 g_print ("type has not been added to hierarchy: %s\\n",
875 g_type_name (object_types[i]));
883 /* This is called recursively to output the hierarchy of a widget. */
885 output_hierarchy (FILE *fp,
897 for (i=0; object_types[i]; i++) {
898 if(object_types[i] == type) {
899 g_print ("added type to hierarchy (level %d): %s\\n",
900 level, g_type_name (type));
901 object_types[i] = G_TYPE_NONE;
907 for (i = 0; i < level; i++)
909 fprintf (fp, g_type_name (type));
912 children = g_type_children (type, &n_children);
914 for (i=0; i < n_children; i++) {
915 output_hierarchy (fp, children[i], level + 1);
921 static void output_object_interfaces (void)
926 fp = fopen (interfaces_filename, "w");
929 g_warning ("Couldn't open output file: %s : %s", interfaces_filename, strerror(errno));
932 output_interfaces (fp, G_TYPE_OBJECT);
934 for (i = 0; object_types[i]; i++)
936 if (!g_type_parent (object_types[i]) &&
937 (object_types[i] != G_TYPE_OBJECT) &&
938 G_TYPE_IS_INSTANTIATABLE (object_types[i]))
940 output_interfaces (fp, object_types[i]);
947 output_interfaces (FILE *fp,
951 GType *children, *interfaces;
952 guint n_children, n_interfaces;
957 interfaces = g_type_interfaces (type, &n_interfaces);
959 if (n_interfaces > 0)
961 fprintf (fp, g_type_name (type));
962 for (i=0; i < n_interfaces; i++)
963 fprintf (fp, " %s", g_type_name (interfaces[i]));
968 children = g_type_children (type, &n_children);
970 for (i=0; i < n_children; i++)
971 output_interfaces (fp, children[i]);
976 static void output_interface_prerequisites (void)
980 fp = fopen (prerequisites_filename, "w");
983 g_warning ("Couldn't open output file: %s : %s", prerequisites_filename, strerror(errno));
986 output_prerequisites (fp, G_TYPE_INTERFACE);
991 output_prerequisites (FILE *fp,
994 #if GLIB_CHECK_VERSION(2,1,0)
996 GType *children, *prerequisites;
997 guint n_children, n_prerequisites;
1002 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
1004 if (n_prerequisites > 0)
1006 fprintf (fp, g_type_name (type));
1007 for (i=0; i < n_prerequisites; i++)
1008 fprintf (fp, " %s", g_type_name (prerequisites[i]));
1009 fprintf (fp, "\\n");
1011 g_free (prerequisites);
1013 children = g_type_children (type, &n_children);
1015 for (i=0; i < n_children; i++)
1016 output_prerequisites (fp, children[i]);
1028 fp = fopen (args_filename, "w");
1031 g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno));
1035 for (i = 0; object_types[i]; i++) {
1036 output_object_args (fp, object_types[i]);
1043 compare_param_specs (const void *a, const void *b)
1045 GParamSpec *spec_a = *(GParamSpec **)a;
1046 GParamSpec *spec_b = *(GParamSpec **)b;
1048 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
1051 /* Its common to have unsigned properties restricted
1052 * to the signed range. Therefore we make this look
1053 * a bit nicer by spelling out the max constants.
1056 /* Don't use "==" with floats, it might trigger a gcc warning. */
1057 #define GTKDOC_COMPARE_FLOAT(x, y) (x <= y && x >= y)
1060 describe_double_constant (gdouble value)
1064 if (GTKDOC_COMPARE_FLOAT (value, G_MAXDOUBLE))
1065 desc = g_strdup ("G_MAXDOUBLE");
1066 else if (GTKDOC_COMPARE_FLOAT (value, G_MINDOUBLE))
1067 desc = g_strdup ("G_MINDOUBLE");
1068 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXDOUBLE))
1069 desc = g_strdup ("-G_MAXDOUBLE");
1070 else if (GTKDOC_COMPARE_FLOAT (value, G_MAXFLOAT))
1071 desc = g_strdup ("G_MAXFLOAT");
1072 else if (GTKDOC_COMPARE_FLOAT (value, G_MINFLOAT))
1073 desc = g_strdup ("G_MINFLOAT");
1074 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXFLOAT))
1075 desc = g_strdup ("-G_MAXFLOAT");
1077 desc = g_strdup_printf ("%lg", value);
1083 describe_signed_constant (gint64 value)
1087 if (value == G_MAXINT)
1088 desc = g_strdup ("G_MAXINT");
1089 else if (value == G_MININT)
1090 desc = g_strdup ("G_MININT");
1091 else if (value == G_MAXUINT)
1092 desc = g_strdup ("G_MAXUINT");
1093 else if (value == G_MAXLONG)
1094 desc = g_strdup ("G_MAXLONG");
1095 else if (value == G_MINLONG)
1096 desc = g_strdup ("G_MINLONG");
1097 else if (value == G_MAXULONG)
1098 desc = g_strdup ("G_MAXULONG");
1099 else if (value == G_MAXINT64)
1100 desc = g_strdup ("G_MAXINT64");
1101 else if (value == G_MININT64)
1102 desc = g_strdup ("G_MININT64");
1104 desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
1110 describe_unsigned_constant (guint64 value)
1114 if (value == G_MAXINT)
1115 desc = g_strdup ("G_MAXINT");
1116 else if (value == G_MININT)
1117 desc = g_strdup ("G_MININT");
1118 else if (value == G_MAXUINT)
1119 desc = g_strdup ("G_MAXUINT");
1120 else if (value == G_MAXLONG)
1121 desc = g_strdup ("G_MAXLONG");
1122 else if (value == G_MINLONG)
1123 desc = g_strdup ("G_MINLONG");
1124 else if (value == G_MAXULONG)
1125 desc = g_strdup ("G_MAXULONG");
1126 else if (value == G_MAXINT64)
1127 desc = g_strdup ("G_MAXINT64");
1128 else if (value == G_MININT64)
1129 desc = g_strdup ("G_MININT64");
1130 else if (value == G_MAXUINT64)
1131 desc = g_strdup ("G_MAXUINT64");
1133 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
1139 describe_type (GParamSpec *spec)
1145 if (G_IS_PARAM_SPEC_CHAR (spec))
1147 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1149 lower = describe_signed_constant (pspec->minimum);
1150 upper = describe_signed_constant (pspec->maximum);
1151 if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
1152 desc = g_strdup ("");
1153 else if (pspec->minimum == G_MININT8)
1154 desc = g_strdup_printf ("<= %s", upper);
1155 else if (pspec->maximum == G_MAXINT8)
1156 desc = g_strdup_printf (">= %s", lower);
1158 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1162 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1164 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1166 lower = describe_unsigned_constant (pspec->minimum);
1167 upper = describe_unsigned_constant (pspec->maximum);
1168 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
1169 desc = g_strdup ("");
1170 else if (pspec->minimum == 0)
1171 desc = g_strdup_printf ("<= %s", upper);
1172 else if (pspec->maximum == G_MAXUINT8)
1173 desc = g_strdup_printf (">= %s", lower);
1175 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1179 else if (G_IS_PARAM_SPEC_INT (spec))
1181 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1183 lower = describe_signed_constant (pspec->minimum);
1184 upper = describe_signed_constant (pspec->maximum);
1185 if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
1186 desc = g_strdup ("");
1187 else if (pspec->minimum == G_MININT)
1188 desc = g_strdup_printf ("<= %s", upper);
1189 else if (pspec->maximum == G_MAXINT)
1190 desc = g_strdup_printf (">= %s", lower);
1192 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1196 else if (G_IS_PARAM_SPEC_UINT (spec))
1198 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1200 lower = describe_unsigned_constant (pspec->minimum);
1201 upper = describe_unsigned_constant (pspec->maximum);
1202 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
1203 desc = g_strdup ("");
1204 else if (pspec->minimum == 0)
1205 desc = g_strdup_printf ("<= %s", upper);
1206 else if (pspec->maximum == G_MAXUINT)
1207 desc = g_strdup_printf (">= %s", lower);
1209 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1213 else if (G_IS_PARAM_SPEC_LONG (spec))
1215 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1217 lower = describe_signed_constant (pspec->minimum);
1218 upper = describe_signed_constant (pspec->maximum);
1219 if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
1220 desc = g_strdup ("");
1221 else if (pspec->minimum == G_MINLONG)
1222 desc = g_strdup_printf ("<= %s", upper);
1223 else if (pspec->maximum == G_MAXLONG)
1224 desc = g_strdup_printf (">= %s", lower);
1226 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1230 else if (G_IS_PARAM_SPEC_ULONG (spec))
1232 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1235 lower = describe_unsigned_constant (pspec->minimum);
1236 upper = describe_unsigned_constant (pspec->maximum);
1237 if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
1238 desc = g_strdup ("");
1239 else if (pspec->minimum == 0)
1240 desc = g_strdup_printf ("<= %s", upper);
1241 else if (pspec->maximum == G_MAXULONG)
1242 desc = g_strdup_printf (">= %s", lower);
1244 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1248 else if (G_IS_PARAM_SPEC_INT64 (spec))
1250 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1252 lower = describe_signed_constant (pspec->minimum);
1253 upper = describe_signed_constant (pspec->maximum);
1254 if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
1255 desc = g_strdup ("");
1256 else if (pspec->minimum == G_MININT64)
1257 desc = g_strdup_printf ("<= %s", upper);
1258 else if (pspec->maximum == G_MAXINT64)
1259 desc = g_strdup_printf (">= %s", lower);
1261 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1265 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1267 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1269 lower = describe_unsigned_constant (pspec->minimum);
1270 upper = describe_unsigned_constant (pspec->maximum);
1271 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
1272 desc = g_strdup ("");
1273 else if (pspec->minimum == 0)
1274 desc = g_strdup_printf ("<= %s", upper);
1275 else if (pspec->maximum == G_MAXUINT64)
1276 desc = g_strdup_printf (">= %s", lower);
1278 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1282 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1284 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1286 lower = describe_double_constant (pspec->minimum);
1287 upper = describe_double_constant (pspec->maximum);
1288 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXFLOAT))
1290 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1291 desc = g_strdup ("");
1293 desc = g_strdup_printf ("<= %s", upper);
1295 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1296 desc = g_strdup_printf (">= %s", lower);
1298 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1302 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1304 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1306 lower = describe_double_constant (pspec->minimum);
1307 upper = describe_double_constant (pspec->maximum);
1308 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXDOUBLE))
1310 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1311 desc = g_strdup ("");
1313 desc = g_strdup_printf ("<= %s", upper);
1315 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1316 desc = g_strdup_printf (">= %s", lower);
1318 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1324 desc = g_strdup ("");
1331 describe_default (GParamSpec *spec)
1335 if (G_IS_PARAM_SPEC_CHAR (spec))
1337 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1339 desc = g_strdup_printf ("%d", pspec->default_value);
1341 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1343 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1345 desc = g_strdup_printf ("%u", pspec->default_value);
1347 else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
1349 GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
1351 desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
1353 else if (G_IS_PARAM_SPEC_INT (spec))
1355 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1357 desc = g_strdup_printf ("%d", pspec->default_value);
1359 else if (G_IS_PARAM_SPEC_UINT (spec))
1361 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1363 desc = g_strdup_printf ("%u", pspec->default_value);
1365 else if (G_IS_PARAM_SPEC_LONG (spec))
1367 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1369 desc = g_strdup_printf ("%ld", pspec->default_value);
1371 else if (G_IS_PARAM_SPEC_LONG (spec))
1373 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1375 desc = g_strdup_printf ("%lu", pspec->default_value);
1377 else if (G_IS_PARAM_SPEC_INT64 (spec))
1379 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1381 desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
1383 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1385 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1387 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
1389 else if (G_IS_PARAM_SPEC_UNICHAR (spec))
1391 GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
1393 if (g_unichar_isprint (pspec->default_value))
1394 desc = g_strdup_printf ("'%c'", pspec->default_value);
1396 desc = g_strdup_printf ("%u", pspec->default_value);
1398 else if (G_IS_PARAM_SPEC_ENUM (spec))
1400 GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
1402 GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
1404 desc = g_strdup_printf ("%s", value->value_name);
1406 desc = g_strdup_printf ("%d", pspec->default_value);
1408 else if (G_IS_PARAM_SPEC_FLAGS (spec))
1410 GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
1411 guint default_value;
1414 default_value = pspec->default_value;
1415 acc = g_string_new ("");
1417 while (default_value)
1419 GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
1425 g_string_append (acc, "|");
1426 g_string_append (acc, value->value_name);
1428 default_value &= ~value->value;
1431 if (default_value == 0)
1432 desc = g_string_free (acc, FALSE);
1435 desc = g_strdup_printf ("%d", pspec->default_value);
1436 g_string_free (acc, TRUE);
1439 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1441 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1443 desc = g_strdup_printf ("%g", pspec->default_value);
1445 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1447 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1449 desc = g_strdup_printf ("%lg", pspec->default_value);
1451 else if (G_IS_PARAM_SPEC_STRING (spec))
1453 GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
1455 if (pspec->default_value)
1457 gchar *esc = g_strescape (pspec->default_value, NULL);
1459 desc = g_strdup_printf ("\\"%s\\"", esc);
1464 desc = g_strdup_printf ("NULL");
1468 desc = g_strdup ("");
1476 output_object_args (FILE *fp, GType object_type)
1479 const gchar *object_class_name;
1481 gchar flags[16], *pos;
1482 GParamSpec **properties;
1484 gboolean child_prop;
1485 gboolean style_prop;
1486 gboolean is_pointer;
1487 const gchar *type_name;
1489 gchar *default_value;
1491 if (G_TYPE_IS_OBJECT (object_type))
1493 class = g_type_class_peek (object_type);
1497 properties = g_object_class_list_properties (class, &n_properties);
1499 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
1500 else if (G_TYPE_IS_INTERFACE (object_type))
1502 class = g_type_default_interface_ref (object_type);
1507 properties = g_object_interface_list_properties (class, &n_properties);
1513 object_class_name = g_type_name (object_type);
1519 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
1520 for (arg = 0; arg < n_properties; arg++)
1522 GParamSpec *spec = properties[arg];
1523 const gchar *nick, *blurb, *dot;
1525 if (spec->owner_type != object_type)
1529 /* We use one-character flags for simplicity. */
1530 if (child_prop && !style_prop)
1534 if (spec->flags & G_PARAM_READABLE)
1536 if (spec->flags & G_PARAM_WRITABLE)
1538 if (spec->flags & G_PARAM_CONSTRUCT)
1540 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
1544 nick = g_param_spec_get_nick (spec);
1545 blurb = g_param_spec_get_blurb (spec);
1549 int str_len = strlen (blurb);
1550 if (str_len > 0 && blurb[str_len - 1] != '.')
1554 type_desc = describe_type (spec);
1555 default_value = describe_default (spec);
1556 type_name = get_type_name (spec->value_type, &is_pointer);
1557 fprintf (fp, "<ARG>\\n<NAME>%s::%s</NAME>\\n<TYPE>%s%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",
1558 object_class_name, g_param_spec_get_name (spec), type_name, is_pointer ? "*" : "", type_desc, flags, nick ? nick : "(null)", blurb ? blurb : "(null)", dot, default_value);
1560 g_free (default_value);
1563 g_free (properties);
1565 #ifdef GTK_IS_CONTAINER_CLASS
1566 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
1567 properties = gtk_container_class_list_child_properties (class, &n_properties);
1573 #ifdef GTK_IS_WIDGET_CLASS
1574 #if GTK_CHECK_VERSION(2,1,0)
1575 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
1576 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1590 # Compile and run our file
1592 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
1593 $LD = $ENV{LD} ? $ENV{LD} : $CC;
1594 $CFLAGS = $ENV{CFLAGS} ? "$ENV{CFLAGS} -Wall -g" : "-Wall -g";
1595 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
1598 if ($CC =~ /libtool/) {
1599 $o_file = "$MODULE-scan.lo"
1601 $o_file = "$MODULE-scan.o"
1604 print "gtk-doc: Compiling scanner\n";
1605 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c";
1606 system($command) == 0 or die "Compilation of scanner failed: $!\n";
1608 print "gtk-doc: Linking scanner\n";
1609 $command = "$LD -o $MODULE-scan $o_file $LDFLAGS";
1610 system($command) == 0 or die "Linking of scanner failed: $!\n";
1612 print "gtk-doc: Running scanner $MODULE-scan\n";
1613 system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n";
1615 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
1617 #&UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
1618 &UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
1619 &UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
1620 &UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
1621 #&UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);