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;
149 /* get a list of features from plugins in our source module */
150 plugins = gst_registry_get_plugin_list (gst_registry_get_default());
157 plugin = (GstPlugin *) (plugins->data);
158 plugins = g_list_next (plugins);
159 source = gst_plugin_get_source (plugin);
160 /*g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);*/
161 if (!source || strcmp (source, "$SOURCE") != 0) {
164 g_print ("plugin: %s source: %s\\n", plugin->desc.name, source);
167 gst_registry_get_feature_list_by_plugin (gst_registry_get_default (),
170 GstPluginFeature *feature;
171 feature = GST_PLUGIN_FEATURE (features->data);
172 feature = gst_plugin_feature_load (feature);
174 g_warning ("Could not load plugin feature %s",
175 gst_plugin_feature_get_name (feature));
178 if (GST_IS_ELEMENT_FACTORY (feature)) {
179 factory = GST_ELEMENT_FACTORY (feature);
180 factories = g_list_prepend (factories, factory);
182 features = g_list_next (features);
186 g_message ("number of element factories: %d", g_list_length (factories));
188 /* allocate the object_types array to hold them */
189 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);
199 g_message ("adding type %p for factory %s", (void *) type, gst_element_factory_get_longname (factory));
200 object_types[i++] = type;
202 g_message ("type info for factory %s not found",
203 gst_element_factory_get_longname (factory));
210 # get_type functions:
215 g_message ("$_ () didn't return a valid type");
218 object_types[i++] = type;
223 # Implicit types retrieved from GLib:
226 type = g_type_from_name ("$_");
228 g_message ("Implicit type $_ not found");
231 object_types[i++] = type;
240 /* Need to make sure all the types are loaded in and initialize
241 * their signals and properties.
243 for (i=0; object_types[i]; i++) {
244 if (G_TYPE_IS_CLASSED (object_types[i]))
245 g_type_class_ref (object_types[i]);
247 g_warning ("not reffing type: %s", g_type_name (object_types[i]));
255 * This uses GObject type functions to output signal prototypes and the object
259 /* The output files */
260 const gchar *signals_filename = "$new_signals_filename";
261 const gchar *hierarchy_filename = "$new_hierarchy_filename";
262 const gchar *interfaces_filename = "$new_interfaces_filename";
263 const gchar *prerequisites_filename = "$new_prerequisites_filename";
264 const gchar *args_filename = "$new_args_filename";
267 static void output_signals (void);
268 static void output_object_signals (FILE *fp,
270 static void output_object_signal (FILE *fp,
271 const gchar *object_class_name,
273 static const gchar * get_type_name (GType type,
274 gboolean * is_pointer);
275 static const gchar * get_gdk_event (const gchar * signal_name);
276 static const gchar ** lookup_signal_arg_names (const gchar * type,
277 const gchar * signal_name);
279 static void output_object_hierarchy (void);
280 static void output_hierarchy (FILE *fp,
284 static void output_object_interfaces (void);
285 static void output_interfaces (FILE *fp,
288 static void output_interface_prerequisites (void);
289 static void output_prerequisites (FILE *fp,
292 static void output_args (void);
293 static void output_object_args (FILE *fp, GType object_type);
296 main (int argc, char *argv[])
298 /* Silence the compiler: */
299 if (argv != argv) argc = argc;
306 output_object_hierarchy ();
307 output_object_interfaces ();
308 output_interface_prerequisites ();
316 output_signals (void)
321 fp = fopen (signals_filename, "w");
324 g_warning ("Couldn't open output file: %s : %s", signals_filename, strerror(errno));
328 for (i = 0; object_types[i]; i++)
329 output_object_signals (fp, object_types[i]);
335 compare_signals (const void *a, const void *b)
337 const guint *signal_a = a;
338 const guint *signal_b = b;
340 return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b));
343 /* This outputs all the signals of one object. */
345 output_object_signals (FILE *fp, GType object_type)
347 const gchar *object_class_name;
348 guint *signals, n_signals;
351 if (G_TYPE_IS_INSTANTIATABLE (object_type) ||
352 G_TYPE_IS_INTERFACE (object_type))
355 object_class_name = g_type_name (object_type);
357 signals = g_signal_list_ids (object_type, &n_signals);
358 qsort (signals, n_signals, sizeof (guint), compare_signals);
360 for (sig = 0; sig < n_signals; sig++)
362 output_object_signal (fp, object_class_name, signals[sig]);
369 /* This outputs one signal. */
371 output_object_signal (FILE *fp,
372 const gchar *object_name,
375 GSignalQuery query_info;
376 const gchar *type_name, *ret_type, *object_arg, *arg_name;
377 gchar *pos, *object_arg_lower;
379 gchar ret_type_buffer[1024], buffer[1024];
381 const gchar **arg_names;
382 gint param_num, widget_num, event_num, callback_num;
384 gchar signal_name[128];
387 /* g_print ("Object: %s Signal: %u\\n", object_name, signal_id);*/
390 widget_num = event_num = callback_num = 0;
392 g_signal_query (signal_id, &query_info);
394 /* Output the return type and function name. */
395 ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
396 sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
398 /* Output the signal object type and the argument name. We assume the
399 type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
400 convert to lower case for the argument name. */
402 sprintf (pos, "%s ", object_name);
405 if (!strncmp (object_name, "Gtk", 3))
406 object_arg = object_name + 3;
407 else if (!strncmp (object_name, "Gnome", 5))
408 object_arg = object_name + 5;
410 object_arg = object_name;
412 object_arg_lower = g_ascii_strdown (object_arg, -1);
413 sprintf (pos, "*%s\\n", object_arg_lower);
415 if (!strncmp (object_arg_lower, "widget", 6))
417 g_free(object_arg_lower);
419 /* Convert signal name to use underscores rather than dashes '-'. */
420 strcpy (signal_name, query_info.signal_name);
421 for (i = 0; signal_name[i]; i++)
423 if (signal_name[i] == '-')
424 signal_name[i] = '_';
427 /* Output the signal parameters. */
428 arg_names = lookup_signal_arg_names (object_name, signal_name);
430 for (param = 0; param < query_info.n_params; param++)
434 sprintf (pos, "%s\\n", arg_names[param]);
439 type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
441 /* Most arguments to the callback are called "arg1", "arg2", etc.
442 GdkWidgets are called "widget", "widget2", ...
443 GdkEvents are called "event", "event2", ...
444 GtkCallbacks are called "callback", "callback2", ... */
445 if (!strcmp (type_name, "GtkWidget"))
448 arg_num = &widget_num;
450 else if (!strcmp (type_name, "GdkEvent"))
452 type_name = get_gdk_event (signal_name);
454 arg_num = &event_num;
457 else if (!strcmp (type_name, "GtkCallback")
458 || !strcmp (type_name, "GtkCCallback"))
460 arg_name = "callback";
461 arg_num = &callback_num;
466 arg_num = ¶m_num;
468 sprintf (pos, "%s ", type_name);
471 if (!arg_num || *arg_num == 0)
472 sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
474 sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
489 /* We use one-character flags for simplicity. */
490 if (query_info.signal_flags & G_SIGNAL_RUN_FIRST)
492 if (query_info.signal_flags & G_SIGNAL_RUN_LAST)
494 if (query_info.signal_flags & G_SIGNAL_RUN_CLEANUP)
496 if (query_info.signal_flags & G_SIGNAL_NO_RECURSE)
498 if (query_info.signal_flags & G_SIGNAL_DETAILED)
500 if (query_info.signal_flags & G_SIGNAL_ACTION)
502 if (query_info.signal_flags & G_SIGNAL_NO_HOOKS)
507 "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n<FLAGS>%s</FLAGS>\\n%s</SIGNAL>\\n\\n",
508 object_name, query_info.signal_name, ret_type_buffer, flags, buffer);
512 /* Returns the type name to use for a signal argument or return value, given
513 the GtkType from the signal info. It also sets is_pointer to TRUE if the
514 argument needs a '*' since it is a pointer. */
516 get_type_name (GType type, gboolean * is_pointer)
518 const gchar *type_name;
521 type_name = g_type_name (type);
535 /* These all have normal C type names so they are OK. */
539 /* A GtkString is really a gchar*. */
545 /* We use a gint for both of these. Hopefully a subtype with a decent
546 name will be registered and used instead, as GTK+ does itself. */
550 /* The boxed type shouldn't be used itself, only subtypes. Though we
551 return 'gpointer' just in case. */
555 /* A GParam is really a GParamSpec*. */
563 /* For all GObject subclasses we can use the class name with a "*",
564 e.g. 'GtkWidget *'. */
565 if (g_type_is_a (type, G_TYPE_OBJECT))
568 if (G_TYPE_IS_CLASSED (type))
571 /* All boxed subtypes will be pointers as well. */
572 if (g_type_is_a (type, G_TYPE_BOXED))
575 /* All pointer subtypes will be pointers as well. */
576 if (g_type_is_a (type, G_TYPE_POINTER))
579 /* But enums are not */
580 if (g_type_is_a (type, G_TYPE_ENUM) ||
581 g_type_is_a (type, G_TYPE_FLAGS))
589 get_gdk_event (const gchar * signal_name)
591 static const gchar *GbGDKEvents[] =
593 "button_press_event", "GdkEventButton",
594 "button_release_event", "GdkEventButton",
595 "motion_notify_event", "GdkEventMotion",
596 "delete_event", "GdkEvent",
597 "destroy_event", "GdkEvent",
598 "expose_event", "GdkEventExpose",
599 "key_press_event", "GdkEventKey",
600 "key_release_event", "GdkEventKey",
601 "enter_notify_event", "GdkEventCrossing",
602 "leave_notify_event", "GdkEventCrossing",
603 "configure_event", "GdkEventConfigure",
604 "focus_in_event", "GdkEventFocus",
605 "focus_out_event", "GdkEventFocus",
606 "map_event", "GdkEvent",
607 "unmap_event", "GdkEvent",
608 "property_notify_event", "GdkEventProperty",
609 "selection_clear_event", "GdkEventSelection",
610 "selection_request_event", "GdkEventSelection",
611 "selection_notify_event", "GdkEventSelection",
612 "proximity_in_event", "GdkEventProximity",
613 "proximity_out_event", "GdkEventProximity",
614 "drag_begin_event", "GdkEventDragBegin",
615 "drag_request_event", "GdkEventDragRequest",
616 "drag_end_event", "GdkEventDragRequest",
617 "drop_enter_event", "GdkEventDropEnter",
618 "drop_leave_event", "GdkEventDropLeave",
619 "drop_data_available_event", "GdkEventDropDataAvailable",
620 "other_event", "GdkEventOther",
621 "client_event", "GdkEventClient",
622 "no_expose_event", "GdkEventNoExpose",
623 "visibility_notify_event", "GdkEventVisibility",
624 "window_state_event", "GdkEventWindowState",
625 "scroll_event", "GdkEventScroll",
631 for (i = 0; GbGDKEvents[i]; i += 2)
633 if (!strcmp (signal_name, GbGDKEvents[i]))
634 return GbGDKEvents[i + 1];
640 /* This returns argument names to use for some known GTK signals.
641 It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
642 'select_row' and it returns a pointer to an array of argument types and
644 static const gchar **
645 lookup_signal_arg_names (const gchar * type, const gchar * signal_name)
647 /* Each arg array starts with the object type name and the signal name,
648 and then signal arguments follow. */
649 static const gchar *GbArgTable[][16] =
651 {"GtkCList", "select_row",
654 "GdkEventButton *event"},
655 {"GtkCList", "unselect_row",
658 "GdkEventButton *event"},
659 {"GtkCList", "click_column",
662 {"GtkCList", "resize_column",
666 {"GtkCList", "extend_selection",
667 "GtkScrollType scroll_type",
669 "gboolean auto_start_selection"},
670 {"GtkCList", "scroll_vertical",
671 "GtkScrollType scroll_type",
673 {"GtkCList", "scroll_horizontal",
674 "GtkScrollType scroll_type",
677 {"GtkCTree", "tree_select_row",
678 "GtkCTreeNode *node",
680 {"GtkCTree", "tree_unselect_row",
681 "GtkCTreeNode *node",
683 {"GtkCTree", "tree_expand",
684 "GtkCTreeNode *node"},
685 {"GtkCTree", "tree_collapse",
686 "GtkCTreeNode *node"},
687 {"GtkCTree", "tree_move",
688 "GtkCTreeNode *node",
689 "GtkCTreeNode *new_parent",
690 "GtkCTreeNode *new_sibling"},
691 {"GtkCTree", "change_focus_row_expansion",
692 "GtkCTreeExpansionType expansion"},
694 {"GtkEditable", "insert_text",
696 "gint new_text_length",
698 {"GtkEditable", "delete_text",
701 {"GtkEditable", "set_editable",
702 "gboolean is_editable"},
703 {"GtkEditable", "move_cursor",
706 {"GtkEditable", "move_word",
708 {"GtkEditable", "move_page",
711 {"GtkEditable", "move_to_row",
713 {"GtkEditable", "move_to_column",
716 {"GtkEditable", "kill_char",
718 {"GtkEditable", "kill_word",
720 {"GtkEditable", "kill_line",
724 {"GtkInputDialog", "enable_device",
725 "GdkDevice *deviceid"},
726 {"GtkInputDialog", "disable_device",
727 "GdkDevice *deviceid"},
729 {"GtkListItem", "extend_selection",
730 "GtkScrollType scroll_type",
732 "gboolean auto_start_selection"},
733 {"GtkListItem", "scroll_vertical",
734 "GtkScrollType scroll_type",
736 {"GtkListItem", "scroll_horizontal",
737 "GtkScrollType scroll_type",
740 {"GtkMenuShell", "move_current",
741 "GtkMenuDirectionType direction"},
742 {"GtkMenuShell", "activate_current",
743 "gboolean force_hide"},
746 {"GtkNotebook", "switch_page",
747 "GtkNotebookPage *page",
749 {"GtkStatusbar", "text_pushed",
752 {"GtkStatusbar", "text_popped",
755 {"GtkTipsQuery", "widget_entered",
758 "gchar *tip_private"},
759 {"GtkTipsQuery", "widget_selected",
762 "gchar *tip_private",
763 "GdkEventButton *event"},
764 {"GtkToolbar", "orientation_changed",
765 "GtkOrientation orientation"},
766 {"GtkToolbar", "style_changed",
767 "GtkToolbarStyle style"},
768 {"GtkWidget", "draw",
769 "GdkRectangle *area"},
770 {"GtkWidget", "size_request",
771 "GtkRequisition *requisition"},
772 {"GtkWidget", "size_allocate",
773 "GtkAllocation *allocation"},
774 {"GtkWidget", "state_changed",
775 "GtkStateType state"},
776 {"GtkWidget", "style_set",
777 "GtkStyle *previous_style"},
779 {"GtkWidget", "install_accelerator",
780 "gchar *signal_name",
784 {"GtkWidget", "add_accelerator",
785 "guint accel_signal_id",
786 "GtkAccelGroup *accel_group",
788 "GdkModifierType accel_mods",
789 "GtkAccelFlags accel_flags"},
791 {"GtkWidget", "parent_set",
792 "GtkObject *old_parent"},
794 {"GtkWidget", "remove_accelerator",
795 "GtkAccelGroup *accel_group",
797 "GdkModifierType accel_mods"},
798 {"GtkWidget", "debug_msg",
800 {"GtkWindow", "move_resize",
805 {"GtkWindow", "set_focus",
806 "GtkWidget *widget"},
808 {"GtkWidget", "selection_get",
809 "GtkSelectionData *data",
812 {"GtkWidget", "selection_received",
813 "GtkSelectionData *data",
816 {"GtkWidget", "drag_begin",
817 "GdkDragContext *drag_context"},
818 {"GtkWidget", "drag_end",
819 "GdkDragContext *drag_context"},
820 {"GtkWidget", "drag_data_delete",
821 "GdkDragContext *drag_context"},
822 {"GtkWidget", "drag_leave",
823 "GdkDragContext *drag_context",
825 {"GtkWidget", "drag_motion",
826 "GdkDragContext *drag_context",
830 {"GtkWidget", "drag_drop",
831 "GdkDragContext *drag_context",
835 {"GtkWidget", "drag_data_get",
836 "GdkDragContext *drag_context",
837 "GtkSelectionData *data",
840 {"GtkWidget", "drag_data_received",
841 "GdkDragContext *drag_context",
844 "GtkSelectionData *data",
853 for (i = 0; GbArgTable[i][0]; i++)
856 if (!strcmp (type, GbArgTable[i][0])
857 && !strcmp (signal_name, GbArgTable[i][1]))
858 return &GbArgTable[i][2];
864 /* This outputs the hierarchy of all objects which have been initialized,
865 i.e. by calling their XXX_get_type() initialization function. */
867 output_object_hierarchy (void)
872 fp = fopen (hierarchy_filename, "w");
875 g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, strerror(errno));
878 output_hierarchy (fp, G_TYPE_OBJECT, 0);
879 output_hierarchy (fp, G_TYPE_INTERFACE, 0);
881 for (i=0; object_types[i]; i++) {
882 if (!g_type_parent (object_types[i]) &&
883 (object_types[i] != G_TYPE_NONE) &&
884 (object_types[i] != G_TYPE_OBJECT) &&
885 (object_types[i] != G_TYPE_INTERFACE)
887 g_warning ("printing hierarchy for root type: %s",
888 g_type_name (object_types[i]));
889 output_hierarchy (fp, object_types[i], 0);
893 for (i=0; object_types[i]; i++) {
894 if(object_types[i] != G_TYPE_NONE) {
895 g_print ("type has not been added to hierarchy: %s\\n",
896 g_type_name (object_types[i]));
904 /* This is called recursively to output the hierarchy of a widget. */
906 output_hierarchy (FILE *fp,
918 for (i=0; object_types[i]; i++) {
919 if(object_types[i] == type) {
920 g_print ("added type to hierarchy (level %d): %s\\n",
921 level, g_type_name (type));
922 object_types[i] = G_TYPE_NONE;
928 for (i = 0; i < level; i++)
930 fprintf (fp, "%s", g_type_name (type));
933 children = g_type_children (type, &n_children);
935 for (i=0; i < n_children; i++) {
936 output_hierarchy (fp, children[i], level + 1);
942 static void output_object_interfaces (void)
947 fp = fopen (interfaces_filename, "w");
950 g_warning ("Couldn't open output file: %s : %s", interfaces_filename, strerror(errno));
953 output_interfaces (fp, G_TYPE_OBJECT);
955 for (i = 0; object_types[i]; i++)
957 if (!g_type_parent (object_types[i]) &&
958 (object_types[i] != G_TYPE_OBJECT) &&
959 G_TYPE_IS_INSTANTIATABLE (object_types[i]))
961 output_interfaces (fp, object_types[i]);
968 output_interfaces (FILE *fp,
972 GType *children, *interfaces;
973 guint n_children, n_interfaces;
978 interfaces = g_type_interfaces (type, &n_interfaces);
980 if (n_interfaces > 0)
982 fprintf (fp, "%s", g_type_name (type));
983 for (i=0; i < n_interfaces; i++)
984 fprintf (fp, " %s", g_type_name (interfaces[i]));
989 children = g_type_children (type, &n_children);
991 for (i=0; i < n_children; i++)
992 output_interfaces (fp, children[i]);
997 static void output_interface_prerequisites (void)
1001 fp = fopen (prerequisites_filename, "w");
1004 g_warning ("Couldn't open output file: %s : %s", prerequisites_filename, strerror(errno));
1007 output_prerequisites (fp, G_TYPE_INTERFACE);
1012 output_prerequisites (FILE *fp,
1015 #if GLIB_CHECK_VERSION(2,1,0)
1017 GType *children, *prerequisites;
1018 guint n_children, n_prerequisites;
1023 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
1025 if (n_prerequisites > 0)
1027 fprintf (fp, "%s", g_type_name (type));
1028 for (i=0; i < n_prerequisites; i++)
1029 fprintf (fp, " %s", g_type_name (prerequisites[i]));
1030 fprintf (fp, "\\n");
1032 g_free (prerequisites);
1034 children = g_type_children (type, &n_children);
1036 for (i=0; i < n_children; i++)
1037 output_prerequisites (fp, children[i]);
1049 fp = fopen (args_filename, "w");
1052 g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno));
1056 for (i = 0; object_types[i]; i++) {
1057 output_object_args (fp, object_types[i]);
1064 compare_param_specs (const void *a, const void *b)
1066 GParamSpec *spec_a = *(GParamSpec **)a;
1067 GParamSpec *spec_b = *(GParamSpec **)b;
1069 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
1072 /* Its common to have unsigned properties restricted
1073 * to the signed range. Therefore we make this look
1074 * a bit nicer by spelling out the max constants.
1077 /* Don't use "==" with floats, it might trigger a gcc warning. */
1078 #define GTKDOC_COMPARE_FLOAT(x, y) (x <= y && x >= y)
1081 describe_double_constant (gdouble value)
1085 if (GTKDOC_COMPARE_FLOAT (value, G_MAXDOUBLE))
1086 desc = g_strdup ("G_MAXDOUBLE");
1087 else if (GTKDOC_COMPARE_FLOAT (value, G_MINDOUBLE))
1088 desc = g_strdup ("G_MINDOUBLE");
1089 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXDOUBLE))
1090 desc = g_strdup ("-G_MAXDOUBLE");
1091 else if (GTKDOC_COMPARE_FLOAT (value, G_MAXFLOAT))
1092 desc = g_strdup ("G_MAXFLOAT");
1093 else if (GTKDOC_COMPARE_FLOAT (value, G_MINFLOAT))
1094 desc = g_strdup ("G_MINFLOAT");
1095 else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXFLOAT))
1096 desc = g_strdup ("-G_MAXFLOAT");
1098 desc = g_strdup_printf ("%lg", value);
1104 describe_signed_constant (gint64 value)
1108 if (value == G_MAXINT)
1109 desc = g_strdup ("G_MAXINT");
1110 else if (value == G_MININT)
1111 desc = g_strdup ("G_MININT");
1112 else if (value == G_MAXUINT)
1113 desc = g_strdup ("G_MAXUINT");
1114 else if (value == G_MAXLONG)
1115 desc = g_strdup ("G_MAXLONG");
1116 else if (value == G_MINLONG)
1117 desc = g_strdup ("G_MINLONG");
1118 else if (value == G_MAXULONG)
1119 desc = g_strdup ("G_MAXULONG");
1120 else if (value == G_MAXINT64)
1121 desc = g_strdup ("G_MAXINT64");
1122 else if (value == G_MININT64)
1123 desc = g_strdup ("G_MININT64");
1125 desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
1131 describe_unsigned_constant (guint64 value)
1135 if (value == G_MAXINT)
1136 desc = g_strdup ("G_MAXINT");
1137 else if (value == G_MININT)
1138 desc = g_strdup ("G_MININT");
1139 else if (value == G_MAXUINT)
1140 desc = g_strdup ("G_MAXUINT");
1141 else if (value == G_MAXLONG)
1142 desc = g_strdup ("G_MAXLONG");
1143 else if (value == G_MINLONG)
1144 desc = g_strdup ("G_MINLONG");
1145 else if (value == G_MAXULONG)
1146 desc = g_strdup ("G_MAXULONG");
1147 else if (value == G_MAXINT64)
1148 desc = g_strdup ("G_MAXINT64");
1149 else if (value == G_MININT64)
1150 desc = g_strdup ("G_MININT64");
1151 else if (value == G_MAXUINT64)
1152 desc = g_strdup ("G_MAXUINT64");
1154 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
1160 describe_type (GParamSpec *spec)
1166 if (G_IS_PARAM_SPEC_CHAR (spec))
1168 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1170 lower = describe_signed_constant (pspec->minimum);
1171 upper = describe_signed_constant (pspec->maximum);
1172 if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
1173 desc = g_strdup ("");
1174 else if (pspec->minimum == G_MININT8)
1175 desc = g_strdup_printf ("<= %s", upper);
1176 else if (pspec->maximum == G_MAXINT8)
1177 desc = g_strdup_printf (">= %s", lower);
1179 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1183 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1185 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1187 lower = describe_unsigned_constant (pspec->minimum);
1188 upper = describe_unsigned_constant (pspec->maximum);
1189 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
1190 desc = g_strdup ("");
1191 else if (pspec->minimum == 0)
1192 desc = g_strdup_printf ("<= %s", upper);
1193 else if (pspec->maximum == G_MAXUINT8)
1194 desc = g_strdup_printf (">= %s", lower);
1196 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1200 else if (G_IS_PARAM_SPEC_INT (spec))
1202 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1204 lower = describe_signed_constant (pspec->minimum);
1205 upper = describe_signed_constant (pspec->maximum);
1206 if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
1207 desc = g_strdup ("");
1208 else if (pspec->minimum == G_MININT)
1209 desc = g_strdup_printf ("<= %s", upper);
1210 else if (pspec->maximum == G_MAXINT)
1211 desc = g_strdup_printf (">= %s", lower);
1213 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1217 else if (G_IS_PARAM_SPEC_UINT (spec))
1219 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1221 lower = describe_unsigned_constant (pspec->minimum);
1222 upper = describe_unsigned_constant (pspec->maximum);
1223 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
1224 desc = g_strdup ("");
1225 else if (pspec->minimum == 0)
1226 desc = g_strdup_printf ("<= %s", upper);
1227 else if (pspec->maximum == G_MAXUINT)
1228 desc = g_strdup_printf (">= %s", lower);
1230 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1234 else if (G_IS_PARAM_SPEC_LONG (spec))
1236 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1238 lower = describe_signed_constant (pspec->minimum);
1239 upper = describe_signed_constant (pspec->maximum);
1240 if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
1241 desc = g_strdup ("");
1242 else if (pspec->minimum == G_MINLONG)
1243 desc = g_strdup_printf ("<= %s", upper);
1244 else if (pspec->maximum == G_MAXLONG)
1245 desc = g_strdup_printf (">= %s", lower);
1247 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1251 else if (G_IS_PARAM_SPEC_ULONG (spec))
1253 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1256 lower = describe_unsigned_constant (pspec->minimum);
1257 upper = describe_unsigned_constant (pspec->maximum);
1258 if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
1259 desc = g_strdup ("");
1260 else if (pspec->minimum == 0)
1261 desc = g_strdup_printf ("<= %s", upper);
1262 else if (pspec->maximum == G_MAXULONG)
1263 desc = g_strdup_printf (">= %s", lower);
1265 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1269 else if (G_IS_PARAM_SPEC_INT64 (spec))
1271 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1273 lower = describe_signed_constant (pspec->minimum);
1274 upper = describe_signed_constant (pspec->maximum);
1275 if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
1276 desc = g_strdup ("");
1277 else if (pspec->minimum == G_MININT64)
1278 desc = g_strdup_printf ("<= %s", upper);
1279 else if (pspec->maximum == G_MAXINT64)
1280 desc = g_strdup_printf (">= %s", lower);
1282 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1286 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1288 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1290 lower = describe_unsigned_constant (pspec->minimum);
1291 upper = describe_unsigned_constant (pspec->maximum);
1292 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
1293 desc = g_strdup ("");
1294 else if (pspec->minimum == 0)
1295 desc = g_strdup_printf ("<= %s", upper);
1296 else if (pspec->maximum == G_MAXUINT64)
1297 desc = g_strdup_printf (">= %s", lower);
1299 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1303 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1305 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1307 lower = describe_double_constant (pspec->minimum);
1308 upper = describe_double_constant (pspec->maximum);
1309 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXFLOAT))
1311 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1312 desc = g_strdup ("");
1314 desc = g_strdup_printf ("<= %s", upper);
1316 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
1317 desc = g_strdup_printf (">= %s", lower);
1319 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1323 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1325 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1327 lower = describe_double_constant (pspec->minimum);
1328 upper = describe_double_constant (pspec->maximum);
1329 if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXDOUBLE))
1331 if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1332 desc = g_strdup ("");
1334 desc = g_strdup_printf ("<= %s", upper);
1336 else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
1337 desc = g_strdup_printf (">= %s", lower);
1339 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1345 desc = g_strdup ("");
1352 describe_default (GParamSpec *spec)
1356 if (G_IS_PARAM_SPEC_CHAR (spec))
1358 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1360 desc = g_strdup_printf ("%d", pspec->default_value);
1362 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1364 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1366 desc = g_strdup_printf ("%u", pspec->default_value);
1368 else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
1370 GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
1372 desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
1374 else if (G_IS_PARAM_SPEC_INT (spec))
1376 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1378 desc = g_strdup_printf ("%d", pspec->default_value);
1380 else if (G_IS_PARAM_SPEC_UINT (spec))
1382 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1384 desc = g_strdup_printf ("%u", pspec->default_value);
1386 else if (G_IS_PARAM_SPEC_LONG (spec))
1388 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1390 desc = g_strdup_printf ("%ld", pspec->default_value);
1392 else if (G_IS_PARAM_SPEC_LONG (spec))
1394 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1396 desc = g_strdup_printf ("%lu", pspec->default_value);
1398 else if (G_IS_PARAM_SPEC_INT64 (spec))
1400 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1402 desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
1404 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1406 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1408 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
1410 else if (G_IS_PARAM_SPEC_UNICHAR (spec))
1412 GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
1414 if (g_unichar_isprint (pspec->default_value))
1415 desc = g_strdup_printf ("'%c'", pspec->default_value);
1417 desc = g_strdup_printf ("%u", pspec->default_value);
1419 else if (G_IS_PARAM_SPEC_ENUM (spec))
1421 GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
1423 GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
1425 desc = g_strdup_printf ("%s", value->value_name);
1427 desc = g_strdup_printf ("%d", pspec->default_value);
1429 else if (G_IS_PARAM_SPEC_FLAGS (spec))
1431 GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
1432 guint default_value;
1435 default_value = pspec->default_value;
1436 acc = g_string_new ("");
1438 while (default_value)
1440 GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
1446 g_string_append (acc, "|");
1447 g_string_append (acc, value->value_name);
1449 default_value &= ~value->value;
1452 if (default_value == 0)
1453 desc = g_string_free (acc, FALSE);
1456 desc = g_strdup_printf ("%d", pspec->default_value);
1457 g_string_free (acc, TRUE);
1460 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1462 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1464 desc = g_strdup_printf ("%g", pspec->default_value);
1466 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1468 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1470 desc = g_strdup_printf ("%lg", pspec->default_value);
1472 else if (G_IS_PARAM_SPEC_STRING (spec))
1474 GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
1476 if (pspec->default_value)
1478 gchar *esc = g_strescape (pspec->default_value, NULL);
1480 desc = g_strdup_printf ("\\"%s\\"", esc);
1485 desc = g_strdup_printf ("NULL");
1489 desc = g_strdup ("");
1497 output_object_args (FILE *fp, GType object_type)
1500 const gchar *object_class_name;
1502 gchar flags[16], *pos;
1503 GParamSpec **properties;
1505 gboolean child_prop;
1506 gboolean style_prop;
1507 gboolean is_pointer;
1508 const gchar *type_name;
1510 gchar *default_value;
1512 if (G_TYPE_IS_OBJECT (object_type))
1514 class = g_type_class_peek (object_type);
1518 properties = g_object_class_list_properties (class, &n_properties);
1520 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
1521 else if (G_TYPE_IS_INTERFACE (object_type))
1523 class = g_type_default_interface_ref (object_type);
1528 properties = g_object_interface_list_properties (class, &n_properties);
1534 object_class_name = g_type_name (object_type);
1540 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
1541 for (arg = 0; arg < n_properties; arg++)
1543 GParamSpec *spec = properties[arg];
1544 const gchar *nick, *blurb, *dot;
1546 if (spec->owner_type != object_type)
1550 /* We use one-character flags for simplicity. */
1551 if (child_prop && !style_prop)
1555 if (spec->flags & G_PARAM_READABLE)
1557 if (spec->flags & G_PARAM_WRITABLE)
1559 if (spec->flags & G_PARAM_CONSTRUCT)
1561 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
1565 nick = g_param_spec_get_nick (spec);
1566 blurb = g_param_spec_get_blurb (spec);
1570 int str_len = strlen (blurb);
1571 if (str_len > 0 && blurb[str_len - 1] != '.')
1575 type_desc = describe_type (spec);
1576 default_value = describe_default (spec);
1577 type_name = get_type_name (spec->value_type, &is_pointer);
1578 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",
1579 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);
1581 g_free (default_value);
1584 g_free (properties);
1586 #ifdef GTK_IS_CONTAINER_CLASS
1587 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
1588 properties = gtk_container_class_list_child_properties (class, &n_properties);
1594 #ifdef GTK_IS_WIDGET_CLASS
1595 #if GTK_CHECK_VERSION(2,1,0)
1596 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
1597 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1611 # Compile and run our file
1613 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
1614 $LD = $ENV{LD} ? $ENV{LD} : $CC;
1615 $CFLAGS = $ENV{CFLAGS} ? "$ENV{CFLAGS} -Wall -g" : "-Wall -g";
1616 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
1619 if ($CC =~ /libtool/) {
1620 $o_file = "$MODULE-scan.lo"
1622 $o_file = "$MODULE-scan.o"
1625 print "gtk-doc: Compiling scanner\n";
1626 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c";
1627 system($command) == 0 or die "Compilation of scanner failed: $!\n";
1629 print "gtk-doc: Linking scanner\n";
1630 $command = "$LD -o $MODULE-scan $o_file $LDFLAGS";
1631 system($command) == 0 or die "Linking of scanner failed: $!\n";
1633 print "gtk-doc: Running scanner $MODULE-scan\n";
1634 system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n";
1636 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
1638 #&UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
1639 &UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
1640 &UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
1641 &UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
1642 #&UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);