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 # THOMAS: dynamic types; only use types file for headers
85 $TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$OUTPUT_DIR/$MODULE.types";
87 open (TYPES, $TYPES_FILE) || die "Cannot open $TYPES_FILE: $!\n";
88 open (OUTPUT, ">$MODULE-scan.c") || die "Cannot open $MODULE-scan.c: $!\n";
90 my $old_signals_filename = "$OUTPUT_DIR/$MODULE.signals";
91 my $new_signals_filename = "$OUTPUT_DIR/$MODULE.signals.new";
92 my $old_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy";
93 my $new_hierarchy_filename = "$OUTPUT_DIR/$MODULE.hierarchy.new";
94 my $old_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces";
95 my $new_interfaces_filename = "$OUTPUT_DIR/$MODULE.interfaces.new";
96 my $old_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites";
97 my $new_prerequisites_filename = "$OUTPUT_DIR/$MODULE.prerequisites.new";
98 my $old_args_filename = "$OUTPUT_DIR/$MODULE.args";
99 my $new_args_filename = "$OUTPUT_DIR/$MODULE.args.new";
101 # write a C program to scan the types
111 # } elsif (/^\s*$/) {
119 #$ntypes = @types + 1;
128 #ifdef GTK_IS_WIDGET_CLASS
129 #include <gtk/gtkversion.h>
131 GType *object_types = NULL;
134 get_object_types (void)
136 GList *plugins = NULL;
137 GList *factories = NULL;
139 GstElementFactory *factory = NULL;
143 /* get a list of features from plugins in our source module */
144 plugins = gst_registry_get_plugin_list (gst_registry_get_default());
151 plugin = (GstPlugin *) (plugins->data);
152 plugins = g_list_next (plugins);
153 source = gst_plugin_get_source (plugin);
154 /*g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);*/
155 if (!source || strcmp (source, "$SOURCE") != 0) {
158 g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);
161 gst_registry_get_feature_list_by_plugin (gst_registry_get_default (),
164 GstPluginFeature *feature;
165 feature = GST_PLUGIN_FEATURE (features->data);
166 feature = gst_plugin_feature_load (feature);
168 g_warning ("Could not load plugin feature %s",
169 gst_plugin_feature_get_name (feature));
172 if (GST_IS_ELEMENT_FACTORY (feature)) {
173 factory = GST_ELEMENT_FACTORY (feature);
174 factories = g_list_prepend (factories, factory);
176 features = g_list_next (features);
180 g_message ("number of element factories: %d", g_list_length (factories));
182 /* allocate the object_types array to hold them */
183 object_types = g_new0 (GType, g_list_length (factories)+1);
191 factory = GST_ELEMENT_FACTORY (l->data);
192 type = gst_element_factory_get_element_type (factory);
193 g_message ("adding type %p for factory %s", (void *) type, gst_element_factory_get_longname (factory));
194 object_types[i] = type;
203 /* Need to make sure all the types are loaded in and initialize
204 * their signals and properties.
206 for (i=0; object_types[i]; i++) {
207 if (G_TYPE_IS_CLASSED (object_types[i]))
208 g_type_class_ref (object_types[i]);
210 g_warning ("not reffing type: %s", g_type_name (object_types[i]));
218 * This uses GObject type functions to output signal prototypes and the object
222 /* The output files */
223 const gchar *signals_filename = "$new_signals_filename";
224 const gchar *hierarchy_filename = "$new_hierarchy_filename";
225 const gchar *interfaces_filename = "$new_interfaces_filename";
226 const gchar *prerequisites_filename = "$new_prerequisites_filename";
227 const gchar *args_filename = "$new_args_filename";
230 static void output_signals (void);
231 static void output_object_signals (FILE *fp,
233 static void output_object_signal (FILE *fp,
234 const gchar *object_class_name,
236 static const gchar * get_type_name (GType type,
237 gboolean * is_pointer);
238 static const gchar * get_gdk_event (const gchar * signal_name);
239 static const gchar ** lookup_signal_arg_names (const gchar * type,
240 const gchar * signal_name);
242 static void output_object_hierarchy (void);
243 static void output_hierarchy (FILE *fp,
247 static void output_object_interfaces (void);
248 static void output_interfaces (FILE *fp,
251 static void output_interface_prerequisites (void);
252 static void output_prerequisites (FILE *fp,
255 static void output_args (void);
256 static void output_object_args (FILE *fp, GType object_type);
259 main (int argc, char *argv[])
261 /* Silence the compiler: */
262 if (argv != argv) argc = argc;
269 output_object_hierarchy ();
270 output_object_interfaces ();
271 output_interface_prerequisites ();
279 output_signals (void)
284 fp = fopen (signals_filename, "w");
287 g_warning ("Couldn't open output file: %s : %s", signals_filename, strerror(errno));
291 for (i = 0; object_types[i]; i++)
292 output_object_signals (fp, object_types[i]);
298 compare_signals (const void *a, const void *b)
300 const guint *signal_a = a;
301 const guint *signal_b = b;
303 return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b));
306 /* This outputs all the signals of one object. */
308 output_object_signals (FILE *fp, GType object_type)
310 const gchar *object_class_name;
311 guint *signals, n_signals;
314 if (G_TYPE_IS_INSTANTIATABLE (object_type) ||
315 G_TYPE_IS_INTERFACE (object_type))
318 object_class_name = g_type_name (object_type);
320 signals = g_signal_list_ids (object_type, &n_signals);
321 qsort (signals, n_signals, sizeof (guint), compare_signals);
323 for (sig = 0; sig < n_signals; sig++)
325 output_object_signal (fp, object_class_name, signals[sig]);
332 /* This outputs one signal. */
334 output_object_signal (FILE *fp,
335 const gchar *object_name,
338 GSignalQuery query_info;
339 const gchar *type_name, *ret_type, *object_arg, *arg_name;
340 gchar *pos, *object_arg_lower;
342 gchar ret_type_buffer[1024], buffer[1024];
344 const gchar **arg_names;
345 gint param_num, widget_num, event_num, callback_num;
347 gchar signal_name[128];
350 /* g_print ("Object: %s Signal: %u\\n", object_name, signal_id);*/
353 widget_num = event_num = callback_num = 0;
355 g_signal_query (signal_id, &query_info);
357 /* Output the return type and function name. */
358 ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
359 sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
361 /* Output the signal object type and the argument name. We assume the
362 type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
363 convert to lower case for the argument name. */
365 sprintf (pos, "%s ", object_name);
368 if (!strncmp (object_name, "Gtk", 3))
369 object_arg = object_name + 3;
370 else if (!strncmp (object_name, "Gnome", 5))
371 object_arg = object_name + 5;
373 object_arg = object_name;
375 object_arg_lower = g_ascii_strdown (object_arg, -1);
376 sprintf (pos, "*%s\\n", object_arg_lower);
378 if (!strncmp (object_arg_lower, "widget", 6))
380 g_free(object_arg_lower);
382 /* Convert signal name to use underscores rather than dashes '-'. */
383 strcpy (signal_name, query_info.signal_name);
384 for (i = 0; signal_name[i]; i++)
386 if (signal_name[i] == '-')
387 signal_name[i] = '_';
390 /* Output the signal parameters. */
391 arg_names = lookup_signal_arg_names (object_name, signal_name);
393 for (param = 0; param < query_info.n_params; param++)
397 sprintf (pos, "%s\\n", arg_names[param]);
402 type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
404 /* Most arguments to the callback are called "arg1", "arg2", etc.
405 GdkWidgets are called "widget", "widget2", ...
406 GdkEvents are called "event", "event2", ...
407 GtkCallbacks are called "callback", "callback2", ... */
408 if (!strcmp (type_name, "GtkWidget"))
411 arg_num = &widget_num;
413 else if (!strcmp (type_name, "GdkEvent"))
415 type_name = get_gdk_event (signal_name);
417 arg_num = &event_num;
420 else if (!strcmp (type_name, "GtkCallback")
421 || !strcmp (type_name, "GtkCCallback"))
423 arg_name = "callback";
424 arg_num = &callback_num;
429 arg_num = ¶m_num;
431 sprintf (pos, "%s ", type_name);
434 if (!arg_num || *arg_num == 0)
435 sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
437 sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
452 /* We use one-character flags for simplicity. */
453 if (query_info.signal_flags & G_SIGNAL_RUN_FIRST)
455 if (query_info.signal_flags & G_SIGNAL_RUN_LAST)
457 if (query_info.signal_flags & G_SIGNAL_RUN_CLEANUP)
459 if (query_info.signal_flags & G_SIGNAL_NO_RECURSE)
461 if (query_info.signal_flags & G_SIGNAL_DETAILED)
463 if (query_info.signal_flags & G_SIGNAL_ACTION)
465 if (query_info.signal_flags & G_SIGNAL_NO_HOOKS)
470 "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n<FLAGS>%s</FLAGS>\\n%s</SIGNAL>\\n\\n",
471 object_name, query_info.signal_name, ret_type_buffer, flags, buffer);
475 /* Returns the type name to use for a signal argument or return value, given
476 the GtkType from the signal info. It also sets is_pointer to TRUE if the
477 argument needs a '*' since it is a pointer. */
479 get_type_name (GType type, gboolean * is_pointer)
481 const gchar *type_name;
484 type_name = g_type_name (type);
498 /* These all have normal C type names so they are OK. */
502 /* A GtkString is really a gchar*. */
508 /* We use a gint for both of these. Hopefully a subtype with a decent
509 name will be registered and used instead, as GTK+ does itself. */
513 /* The boxed type shouldn't be used itself, only subtypes. Though we
514 return 'gpointer' just in case. */
518 /* A GParam is really a GParamSpec*. */
526 /* For all GObject subclasses we can use the class name with a "*",
527 e.g. 'GtkWidget *'. */
528 if (g_type_is_a (type, G_TYPE_OBJECT))
531 if (G_TYPE_IS_CLASSED (type))
534 /* All boxed subtypes will be pointers as well. */
535 if (g_type_is_a (type, G_TYPE_BOXED))
538 /* All pointer subtypes will be pointers as well. */
539 if (g_type_is_a (type, G_TYPE_POINTER))
542 /* But enums are not */
543 if (g_type_is_a (type, G_TYPE_ENUM) ||
544 g_type_is_a (type, G_TYPE_FLAGS))
552 get_gdk_event (const gchar * signal_name)
554 static const gchar *GbGDKEvents[] =
556 "button_press_event", "GdkEventButton",
557 "button_release_event", "GdkEventButton",
558 "motion_notify_event", "GdkEventMotion",
559 "delete_event", "GdkEvent",
560 "destroy_event", "GdkEvent",
561 "expose_event", "GdkEventExpose",
562 "key_press_event", "GdkEventKey",
563 "key_release_event", "GdkEventKey",
564 "enter_notify_event", "GdkEventCrossing",
565 "leave_notify_event", "GdkEventCrossing",
566 "configure_event", "GdkEventConfigure",
567 "focus_in_event", "GdkEventFocus",
568 "focus_out_event", "GdkEventFocus",
569 "map_event", "GdkEvent",
570 "unmap_event", "GdkEvent",
571 "property_notify_event", "GdkEventProperty",
572 "selection_clear_event", "GdkEventSelection",
573 "selection_request_event", "GdkEventSelection",
574 "selection_notify_event", "GdkEventSelection",
575 "proximity_in_event", "GdkEventProximity",
576 "proximity_out_event", "GdkEventProximity",
577 "drag_begin_event", "GdkEventDragBegin",
578 "drag_request_event", "GdkEventDragRequest",
579 "drag_end_event", "GdkEventDragRequest",
580 "drop_enter_event", "GdkEventDropEnter",
581 "drop_leave_event", "GdkEventDropLeave",
582 "drop_data_available_event", "GdkEventDropDataAvailable",
583 "other_event", "GdkEventOther",
584 "client_event", "GdkEventClient",
585 "no_expose_event", "GdkEventNoExpose",
586 "visibility_notify_event", "GdkEventVisibility",
587 "window_state_event", "GdkEventWindowState",
588 "scroll_event", "GdkEventScroll",
594 for (i = 0; GbGDKEvents[i]; i += 2)
596 if (!strcmp (signal_name, GbGDKEvents[i]))
597 return GbGDKEvents[i + 1];
603 /* This returns argument names to use for some known GTK signals.
604 It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
605 'select_row' and it returns a pointer to an array of argument types and
607 static const gchar **
608 lookup_signal_arg_names (const gchar * type, const gchar * signal_name)
610 /* Each arg array starts with the object type name and the signal name,
611 and then signal arguments follow. */
612 static const gchar *GbArgTable[][16] =
614 {"GtkCList", "select_row",
617 "GdkEventButton *event"},
618 {"GtkCList", "unselect_row",
621 "GdkEventButton *event"},
622 {"GtkCList", "click_column",
625 {"GtkCList", "resize_column",
629 {"GtkCList", "extend_selection",
630 "GtkScrollType scroll_type",
632 "gboolean auto_start_selection"},
633 {"GtkCList", "scroll_vertical",
634 "GtkScrollType scroll_type",
636 {"GtkCList", "scroll_horizontal",
637 "GtkScrollType scroll_type",
640 {"GtkCTree", "tree_select_row",
641 "GtkCTreeNode *node",
643 {"GtkCTree", "tree_unselect_row",
644 "GtkCTreeNode *node",
646 {"GtkCTree", "tree_expand",
647 "GtkCTreeNode *node"},
648 {"GtkCTree", "tree_collapse",
649 "GtkCTreeNode *node"},
650 {"GtkCTree", "tree_move",
651 "GtkCTreeNode *node",
652 "GtkCTreeNode *new_parent",
653 "GtkCTreeNode *new_sibling"},
654 {"GtkCTree", "change_focus_row_expansion",
655 "GtkCTreeExpansionType expansion"},
657 {"GtkEditable", "insert_text",
659 "gint new_text_length",
661 {"GtkEditable", "delete_text",
664 {"GtkEditable", "set_editable",
665 "gboolean is_editable"},
666 {"GtkEditable", "move_cursor",
669 {"GtkEditable", "move_word",
671 {"GtkEditable", "move_page",
674 {"GtkEditable", "move_to_row",
676 {"GtkEditable", "move_to_column",
679 {"GtkEditable", "kill_char",
681 {"GtkEditable", "kill_word",
683 {"GtkEditable", "kill_line",
687 {"GtkInputDialog", "enable_device",
688 "GdkDevice *deviceid"},
689 {"GtkInputDialog", "disable_device",
690 "GdkDevice *deviceid"},
692 {"GtkListItem", "extend_selection",
693 "GtkScrollType scroll_type",
695 "gboolean auto_start_selection"},
696 {"GtkListItem", "scroll_vertical",
697 "GtkScrollType scroll_type",
699 {"GtkListItem", "scroll_horizontal",
700 "GtkScrollType scroll_type",
703 {"GtkMenuShell", "move_current",
704 "GtkMenuDirectionType direction"},
705 {"GtkMenuShell", "activate_current",
706 "gboolean force_hide"},
709 {"GtkNotebook", "switch_page",
710 "GtkNotebookPage *page",
712 {"GtkStatusbar", "text_pushed",
715 {"GtkStatusbar", "text_popped",
718 {"GtkTipsQuery", "widget_entered",
721 "gchar *tip_private"},
722 {"GtkTipsQuery", "widget_selected",
725 "gchar *tip_private",
726 "GdkEventButton *event"},
727 {"GtkToolbar", "orientation_changed",
728 "GtkOrientation orientation"},
729 {"GtkToolbar", "style_changed",
730 "GtkToolbarStyle style"},
731 {"GtkWidget", "draw",
732 "GdkRectangle *area"},
733 {"GtkWidget", "size_request",
734 "GtkRequisition *requisition"},
735 {"GtkWidget", "size_allocate",
736 "GtkAllocation *allocation"},
737 {"GtkWidget", "state_changed",
738 "GtkStateType state"},
739 {"GtkWidget", "style_set",
740 "GtkStyle *previous_style"},
742 {"GtkWidget", "install_accelerator",
743 "gchar *signal_name",
747 {"GtkWidget", "add_accelerator",
748 "guint accel_signal_id",
749 "GtkAccelGroup *accel_group",
751 "GdkModifierType accel_mods",
752 "GtkAccelFlags accel_flags"},
754 {"GtkWidget", "parent_set",
755 "GtkObject *old_parent"},
757 {"GtkWidget", "remove_accelerator",
758 "GtkAccelGroup *accel_group",
760 "GdkModifierType accel_mods"},
761 {"GtkWidget", "debug_msg",
763 {"GtkWindow", "move_resize",
768 {"GtkWindow", "set_focus",
769 "GtkWidget *widget"},
771 {"GtkWidget", "selection_get",
772 "GtkSelectionData *data",
775 {"GtkWidget", "selection_received",
776 "GtkSelectionData *data",
779 {"GtkWidget", "drag_begin",
780 "GdkDragContext *drag_context"},
781 {"GtkWidget", "drag_end",
782 "GdkDragContext *drag_context"},
783 {"GtkWidget", "drag_data_delete",
784 "GdkDragContext *drag_context"},
785 {"GtkWidget", "drag_leave",
786 "GdkDragContext *drag_context",
788 {"GtkWidget", "drag_motion",
789 "GdkDragContext *drag_context",
793 {"GtkWidget", "drag_drop",
794 "GdkDragContext *drag_context",
798 {"GtkWidget", "drag_data_get",
799 "GdkDragContext *drag_context",
800 "GtkSelectionData *data",
803 {"GtkWidget", "drag_data_received",
804 "GdkDragContext *drag_context",
807 "GtkSelectionData *data",
816 for (i = 0; GbArgTable[i][0]; i++)
819 if (!strcmp (type, GbArgTable[i][0])
820 && !strcmp (signal_name, GbArgTable[i][1]))
821 return &GbArgTable[i][2];
827 /* This outputs the hierarchy of all objects which have been initialized,
828 i.e. by calling their XXX_get_type() initialization function. */
830 output_object_hierarchy (void)
835 fp = fopen (hierarchy_filename, "w");
838 g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, strerror(errno));
841 output_hierarchy (fp, G_TYPE_OBJECT, 0);
842 output_hierarchy (fp, G_TYPE_INTERFACE, 0);
844 for (i=0; object_types[i]; i++) {
845 if (!g_type_parent (object_types[i]) &&
846 (object_types[i] != G_TYPE_NONE) &&
847 (object_types[i] != G_TYPE_OBJECT) &&
848 (object_types[i] != G_TYPE_INTERFACE)
850 g_warning ("printing hierarchy for root type: %s",
851 g_type_name (object_types[i]));
852 output_hierarchy (fp, object_types[i], 0);
856 for (i=0; object_types[i]; i++) {
857 if(object_types[i] != G_TYPE_NONE) {
858 g_print ("type has not been added to hierarchy: %s\\n",
859 g_type_name (object_types[i]));
867 /* This is called recursively to output the hierarchy of a widget. */
869 output_hierarchy (FILE *fp,
881 for (i=0; object_types[i]; i++) {
882 if(object_types[i] == type) {
883 g_print ("added type to hierarchy (level %d): %s\\n",
884 level, g_type_name (type));
885 object_types[i] = G_TYPE_NONE;
891 for (i = 0; i < level; i++)
893 fprintf (fp, g_type_name (type));
896 children = g_type_children (type, &n_children);
898 for (i=0; i < n_children; i++) {
899 output_hierarchy (fp, children[i], level + 1);
905 static void output_object_interfaces (void)
910 fp = fopen (interfaces_filename, "w");
913 g_warning ("Couldn't open output file: %s : %s", interfaces_filename, strerror(errno));
916 output_interfaces (fp, G_TYPE_OBJECT);
918 for (i = 0; object_types[i]; i++)
920 if (!g_type_parent (object_types[i]) &&
921 (object_types[i] != G_TYPE_OBJECT) &&
922 G_TYPE_IS_INSTANTIATABLE (object_types[i]))
924 output_interfaces (fp, object_types[i]);
931 output_interfaces (FILE *fp,
935 GType *children, *interfaces;
936 guint n_children, n_interfaces;
941 interfaces = g_type_interfaces (type, &n_interfaces);
943 if (n_interfaces > 0)
945 fprintf (fp, g_type_name (type));
946 for (i=0; i < n_interfaces; i++)
947 fprintf (fp, " %s", g_type_name (interfaces[i]));
952 children = g_type_children (type, &n_children);
954 for (i=0; i < n_children; i++)
955 output_interfaces (fp, children[i]);
960 static void output_interface_prerequisites (void)
964 fp = fopen (prerequisites_filename, "w");
967 g_warning ("Couldn't open output file: %s : %s", prerequisites_filename, strerror(errno));
970 output_prerequisites (fp, G_TYPE_INTERFACE);
975 output_prerequisites (FILE *fp,
978 #if GLIB_CHECK_VERSION(2,1,0)
980 GType *children, *prerequisites;
981 guint n_children, n_prerequisites;
986 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
988 if (n_prerequisites > 0)
990 fprintf (fp, g_type_name (type));
991 for (i=0; i < n_prerequisites; i++)
992 fprintf (fp, " %s", g_type_name (prerequisites[i]));
995 g_free (prerequisites);
997 children = g_type_children (type, &n_children);
999 for (i=0; i < n_children; i++)
1000 output_prerequisites (fp, children[i]);
1012 fp = fopen (args_filename, "w");
1015 g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno));
1019 for (i = 0; object_types[i]; i++) {
1020 output_object_args (fp, object_types[i]);
1027 compare_param_specs (const void *a, const void *b)
1029 GParamSpec *spec_a = *(GParamSpec **)a;
1030 GParamSpec *spec_b = *(GParamSpec **)b;
1032 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
1035 /* Its common to have unsigned properties restricted
1036 * to the signed range. Therefore we make this look
1037 * a bit nicer by spelling out the max constants.
1040 /* Don't use "==" with floats, it might trigger a gcc warning. */
1041 #define GTKDOC_COMPARE_FLOAT(x, y) (x <= y && x >= y)
1044 describe_double_constant (gdouble value)
1048 if (GTKDOC_COMPARE_FLOAT (value, G_MAXDOUBLE))
1049 desc = g_strdup ("G_MAXDOUBLE");
1050 else if (GTKDOC_COMPARE_FLOAT (value, G_MINDOUBLE))
1051 desc = g_strdup ("G_MINDOUBLE");
1052 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXDOUBLE))
1053 desc = g_strdup ("-G_MAXDOUBLE");
1054 else if (GTKDOC_COMPARE_FLOAT (value, G_MAXFLOAT))
1055 desc = g_strdup ("G_MAXFLOAT");
1056 else if (GTKDOC_COMPARE_FLOAT (value, G_MINFLOAT))
1057 desc = g_strdup ("G_MINFLOAT");
1058 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXFLOAT))
1059 desc = g_strdup ("-G_MAXFLOAT");
1061 desc = g_strdup_printf ("%lg", value);
1067 describe_signed_constant (gint64 value)
1071 if (value == G_MAXINT)
1072 desc = g_strdup ("G_MAXINT");
1073 else if (value == G_MININT)
1074 desc = g_strdup ("G_MININT");
1075 else if (value == G_MAXUINT)
1076 desc = g_strdup ("G_MAXUINT");
1077 else if (value == G_MAXLONG)
1078 desc = g_strdup ("G_MAXLONG");
1079 else if (value == G_MINLONG)
1080 desc = g_strdup ("G_MINLONG");
1081 else if (value == G_MAXULONG)
1082 desc = g_strdup ("G_MAXULONG");
1083 else if (value == G_MAXINT64)
1084 desc = g_strdup ("G_MAXINT64");
1085 else if (value == G_MININT64)
1086 desc = g_strdup ("G_MININT64");
1088 desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
1094 describe_unsigned_constant (guint64 value)
1098 if (value == G_MAXINT)
1099 desc = g_strdup ("G_MAXINT");
1100 else if (value == G_MININT)
1101 desc = g_strdup ("G_MININT");
1102 else if (value == G_MAXUINT)
1103 desc = g_strdup ("G_MAXUINT");
1104 else if (value == G_MAXLONG)
1105 desc = g_strdup ("G_MAXLONG");
1106 else if (value == G_MINLONG)
1107 desc = g_strdup ("G_MINLONG");
1108 else if (value == G_MAXULONG)
1109 desc = g_strdup ("G_MAXULONG");
1110 else if (value == G_MAXINT64)
1111 desc = g_strdup ("G_MAXINT64");
1112 else if (value == G_MININT64)
1113 desc = g_strdup ("G_MININT64");
1114 else if (value == G_MAXUINT64)
1115 desc = g_strdup ("G_MAXUINT64");
1117 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
1123 describe_type (GParamSpec *spec)
1129 if (G_IS_PARAM_SPEC_CHAR (spec))
1131 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1133 lower = describe_signed_constant (pspec->minimum);
1134 upper = describe_signed_constant (pspec->maximum);
1135 if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
1136 desc = g_strdup ("");
1137 else if (pspec->minimum == G_MININT8)
1138 desc = g_strdup_printf ("<= %s", upper);
1139 else if (pspec->maximum == G_MAXINT8)
1140 desc = g_strdup_printf (">= %s", lower);
1142 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1146 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1148 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1150 lower = describe_unsigned_constant (pspec->minimum);
1151 upper = describe_unsigned_constant (pspec->maximum);
1152 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
1153 desc = g_strdup ("");
1154 else if (pspec->minimum == 0)
1155 desc = g_strdup_printf ("<= %s", upper);
1156 else if (pspec->maximum == G_MAXUINT8)
1157 desc = g_strdup_printf (">= %s", lower);
1159 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1163 else if (G_IS_PARAM_SPEC_INT (spec))
1165 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1167 lower = describe_signed_constant (pspec->minimum);
1168 upper = describe_signed_constant (pspec->maximum);
1169 if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
1170 desc = g_strdup ("");
1171 else if (pspec->minimum == G_MININT)
1172 desc = g_strdup_printf ("<= %s", upper);
1173 else if (pspec->maximum == G_MAXINT)
1174 desc = g_strdup_printf (">= %s", lower);
1176 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1180 else if (G_IS_PARAM_SPEC_UINT (spec))
1182 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1184 lower = describe_unsigned_constant (pspec->minimum);
1185 upper = describe_unsigned_constant (pspec->maximum);
1186 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
1187 desc = g_strdup ("");
1188 else if (pspec->minimum == 0)
1189 desc = g_strdup_printf ("<= %s", upper);
1190 else if (pspec->maximum == G_MAXUINT)
1191 desc = g_strdup_printf (">= %s", lower);
1193 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1197 else if (G_IS_PARAM_SPEC_LONG (spec))
1199 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1201 lower = describe_signed_constant (pspec->minimum);
1202 upper = describe_signed_constant (pspec->maximum);
1203 if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
1204 desc = g_strdup ("");
1205 else if (pspec->minimum == G_MINLONG)
1206 desc = g_strdup_printf ("<= %s", upper);
1207 else if (pspec->maximum == G_MAXLONG)
1208 desc = g_strdup_printf (">= %s", lower);
1210 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1214 else if (G_IS_PARAM_SPEC_ULONG (spec))
1216 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1219 lower = describe_unsigned_constant (pspec->minimum);
1220 upper = describe_unsigned_constant (pspec->maximum);
1221 if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
1222 desc = g_strdup ("");
1223 else if (pspec->minimum == 0)
1224 desc = g_strdup_printf ("<= %s", upper);
1225 else if (pspec->maximum == G_MAXULONG)
1226 desc = g_strdup_printf (">= %s", lower);
1228 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1232 else if (G_IS_PARAM_SPEC_INT64 (spec))
1234 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1236 lower = describe_signed_constant (pspec->minimum);
1237 upper = describe_signed_constant (pspec->maximum);
1238 if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
1239 desc = g_strdup ("");
1240 else if (pspec->minimum == G_MININT64)
1241 desc = g_strdup_printf ("<= %s", upper);
1242 else if (pspec->maximum == G_MAXINT64)
1243 desc = g_strdup_printf (">= %s", lower);
1245 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1249 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1251 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1253 lower = describe_unsigned_constant (pspec->minimum);
1254 upper = describe_unsigned_constant (pspec->maximum);
1255 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
1256 desc = g_strdup ("");
1257 else if (pspec->minimum == 0)
1258 desc = g_strdup_printf ("<= %s", upper);
1259 else if (pspec->maximum == G_MAXUINT64)
1260 desc = g_strdup_printf (">= %s", lower);
1262 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1266 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1268 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1270 lower = describe_double_constant (pspec->minimum);
1271 upper = describe_double_constant (pspec->maximum);
1272 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXFLOAT))
1274 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1275 desc = g_strdup ("");
1277 desc = g_strdup_printf ("<= %s", upper);
1279 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1280 desc = g_strdup_printf (">= %s", lower);
1282 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1286 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1288 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1290 lower = describe_double_constant (pspec->minimum);
1291 upper = describe_double_constant (pspec->maximum);
1292 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXDOUBLE))
1294 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1295 desc = g_strdup ("");
1297 desc = g_strdup_printf ("<= %s", upper);
1299 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1300 desc = g_strdup_printf (">= %s", lower);
1302 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1308 desc = g_strdup ("");
1315 describe_default (GParamSpec *spec)
1319 if (G_IS_PARAM_SPEC_CHAR (spec))
1321 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1323 desc = g_strdup_printf ("%d", pspec->default_value);
1325 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1327 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1329 desc = g_strdup_printf ("%u", pspec->default_value);
1331 else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
1333 GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
1335 desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
1337 else if (G_IS_PARAM_SPEC_INT (spec))
1339 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1341 desc = g_strdup_printf ("%d", pspec->default_value);
1343 else if (G_IS_PARAM_SPEC_UINT (spec))
1345 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1347 desc = g_strdup_printf ("%u", pspec->default_value);
1349 else if (G_IS_PARAM_SPEC_LONG (spec))
1351 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1353 desc = g_strdup_printf ("%ld", pspec->default_value);
1355 else if (G_IS_PARAM_SPEC_LONG (spec))
1357 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1359 desc = g_strdup_printf ("%lu", pspec->default_value);
1361 else if (G_IS_PARAM_SPEC_INT64 (spec))
1363 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1365 desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
1367 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1369 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1371 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
1373 else if (G_IS_PARAM_SPEC_UNICHAR (spec))
1375 GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
1377 if (g_unichar_isprint (pspec->default_value))
1378 desc = g_strdup_printf ("'%c'", pspec->default_value);
1380 desc = g_strdup_printf ("%u", pspec->default_value);
1382 else if (G_IS_PARAM_SPEC_ENUM (spec))
1384 GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
1386 GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
1388 desc = g_strdup_printf ("%s", value->value_name);
1390 desc = g_strdup_printf ("%d", pspec->default_value);
1392 else if (G_IS_PARAM_SPEC_FLAGS (spec))
1394 GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
1395 guint default_value;
1398 default_value = pspec->default_value;
1399 acc = g_string_new ("");
1401 while (default_value)
1403 GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
1409 g_string_append (acc, "|");
1410 g_string_append (acc, value->value_name);
1412 default_value &= ~value->value;
1415 if (default_value == 0)
1416 desc = g_string_free (acc, FALSE);
1419 desc = g_strdup_printf ("%d", pspec->default_value);
1420 g_string_free (acc, TRUE);
1423 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1425 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1427 desc = g_strdup_printf ("%g", pspec->default_value);
1429 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1431 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1433 desc = g_strdup_printf ("%lg", pspec->default_value);
1435 else if (G_IS_PARAM_SPEC_STRING (spec))
1437 GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
1439 if (pspec->default_value)
1441 gchar *esc = g_strescape (pspec->default_value, NULL);
1443 desc = g_strdup_printf ("\\"%s\\"", esc);
1448 desc = g_strdup_printf ("NULL");
1452 desc = g_strdup ("");
1460 output_object_args (FILE *fp, GType object_type)
1463 const gchar *object_class_name;
1465 gchar flags[16], *pos;
1466 GParamSpec **properties;
1468 gboolean child_prop;
1469 gboolean style_prop;
1470 gboolean is_pointer;
1471 const gchar *type_name;
1473 gchar *default_value;
1475 if (G_TYPE_IS_OBJECT (object_type))
1477 class = g_type_class_peek (object_type);
1481 properties = g_object_class_list_properties (class, &n_properties);
1483 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
1484 else if (G_TYPE_IS_INTERFACE (object_type))
1486 class = g_type_default_interface_ref (object_type);
1491 properties = g_object_interface_list_properties (class, &n_properties);
1497 object_class_name = g_type_name (object_type);
1503 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
1504 for (arg = 0; arg < n_properties; arg++)
1506 GParamSpec *spec = properties[arg];
1507 const gchar *nick, *blurb, *dot;
1509 if (spec->owner_type != object_type)
1513 /* We use one-character flags for simplicity. */
1514 if (child_prop && !style_prop)
1518 if (spec->flags & G_PARAM_READABLE)
1520 if (spec->flags & G_PARAM_WRITABLE)
1522 if (spec->flags & G_PARAM_CONSTRUCT)
1524 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
1528 nick = g_param_spec_get_nick (spec);
1529 blurb = g_param_spec_get_blurb (spec);
1533 int str_len = strlen (blurb);
1534 if (str_len > 0 && blurb[str_len - 1] != '.')
1538 type_desc = describe_type (spec);
1539 default_value = describe_default (spec);
1540 type_name = get_type_name (spec->value_type, &is_pointer);
1541 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",
1542 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);
1544 g_free (default_value);
1547 g_free (properties);
1549 #ifdef GTK_IS_CONTAINER_CLASS
1550 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
1551 properties = gtk_container_class_list_child_properties (class, &n_properties);
1557 #ifdef GTK_IS_WIDGET_CLASS
1558 #if GTK_CHECK_VERSION(2,1,0)
1559 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
1560 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1574 # Compile and run our file
1576 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
1577 $LD = $ENV{LD} ? $ENV{LD} : $CC;
1578 $CFLAGS = $ENV{CFLAGS} ? "$ENV{CFLAGS} -Wall -g" : "-Wall -g";
1579 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
1582 if ($CC =~ /libtool/) {
1583 $o_file = "$MODULE-scan.lo"
1585 $o_file = "$MODULE-scan.o"
1588 print "gtk-doc: Compiling scanner\n";
1589 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c";
1590 system($command) == 0 or die "Compilation of scanner failed: $!\n";
1592 print "gtk-doc: Linking scanner\n";
1593 $command = "$LD -o $MODULE-scan $o_file $LDFLAGS";
1594 system($command) == 0 or die "Linking of scanner failed: $!\n";
1596 print "gtk-doc: Running scanner $MODULE-scan\n";
1597 system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n";
1599 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
1601 #&UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
1602 &UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
1603 &UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
1604 &UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
1605 #&UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);