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.3\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;
127 #ifdef GTK_IS_WIDGET_CLASS
128 #include <gtk/gtkversion.h>
130 gint num_object_types = 0;
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 ("source: %s\\n", source);
155 if (!source || strcmp (gst_plugin_get_source (plugin), "$SOURCE") != 0) {
160 gst_registry_get_feature_list_by_plugin (gst_registry_get_default (),
163 GstPluginFeature *feature;
164 feature = GST_PLUGIN_FEATURE (features->data);
165 feature = gst_plugin_feature_load (feature);
167 g_warning ("Could not load plugin feature %s",
168 gst_plugin_feature_get_name (feature));
171 if (GST_IS_ELEMENT_FACTORY (feature)) {
172 factory = GST_ELEMENT_FACTORY (feature);
173 factories = g_list_append (factories, factory);
175 features = g_list_next (features);
179 num_object_types = g_list_length (factories);
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));
191 factory = GST_ELEMENT_FACTORY (l->data);
192 g_message ("adding type for factory %s", gst_element_factory_get_longname (factory));
193 type = gst_element_factory_get_element_type (factory);
194 g_message ("adding type %p", (void *) type);
195 object_types[i] = type;
203 /* Need to make sure all the types are loaded in and initialize
204 * their signals and properties.
206 g_message ("class reffing");
208 for (i=0; i < num_object_types; i++) {
209 if (G_TYPE_IS_CLASSED (object_types[i]))
210 g_type_class_ref (object_types[i]);
217 * This uses GTK type functions to output signal prototypes and the widget
221 /* The output files */
222 gchar *signals_filename = "$new_signals_filename";
223 gchar *hierarchy_filename = "$new_hierarchy_filename";
224 gchar *interfaces_filename = "$new_interfaces_filename";
225 gchar *prerequisites_filename = "$new_prerequisites_filename";
226 gchar *args_filename = "$new_args_filename";
229 static void output_signals (void);
230 static void output_widget_signals (FILE *fp,
232 static void output_widget_signal (FILE *fp,
234 const gchar *object_class_name,
236 static const gchar * get_type_name (GType type,
237 gboolean * is_pointer);
238 static gchar * get_gdk_event (const gchar * signal_name);
239 static gchar ** lookup_signal_arg_names (const gchar * type,
240 const gchar * signal_name);
242 static void output_widget_hierarchy (void);
243 static void output_hierarchy (FILE *fp,
247 static void output_widget_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_widget_args (FILE *fp, GType object_type);
259 main (int argc, char *argv[])
265 g_message ("output signals");
267 g_message ("output widget hierarchy");
268 output_widget_hierarchy ();
269 output_widget_interfaces ();
270 output_interface_prerequisites ();
271 g_message ("output args");
279 output_signals (void)
284 fp = fopen (signals_filename, "w");
287 g_warning ("Couldn't open output file: %s", signals_filename);
291 for (i = 0; i < num_object_types; i++)
292 output_widget_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 widget. */
308 output_widget_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_widget_signal (fp, object_type, object_class_name,
333 /* This outputs one signal. */
335 output_widget_signal (FILE *fp,
337 const gchar *object_name,
340 GSignalQuery query_info;
341 const gchar *type_name, *ret_type, *object_arg;
342 gchar *pos, *arg_name, *object_arg_lower;
344 gchar ret_type_buffer[1024], buffer[1024];
347 gint param_num, widget_num, event_num, callback_num;
349 gchar signal_name[128];
352 /* g_print ("Object: %s Type: %i Signal: %u\\n", object_name, object_type,
356 widget_num = event_num = callback_num = 0;
358 g_signal_query (signal_id, &query_info);
360 /* Output the return type and function name. */
361 ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
362 sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
364 /* Output the signal object type and the argument name. We assume the
365 type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
366 convert to lower case for the argument name. */
368 sprintf (pos, "%s ", object_name);
371 if (!strncmp (object_name, "Gtk", 3))
372 object_arg = object_name + 3;
373 else if (!strncmp (object_name, "Gnome", 5))
374 object_arg = object_name + 5;
376 object_arg = object_name;
378 object_arg_lower = g_ascii_strdown (object_arg, -1);
379 sprintf (pos, "*%s\\n", object_arg_lower);
381 if (!strncmp (object_arg_lower, "widget", 6))
383 g_free(object_arg_lower);
385 /* Convert signal name to use underscores rather than dashes '-'. */
386 strcpy (signal_name, query_info.signal_name);
387 for (i = 0; signal_name[i]; i++)
389 if (signal_name[i] == '-')
390 signal_name[i] = '_';
393 /* Output the signal parameters. */
394 arg_names = lookup_signal_arg_names (object_name, signal_name);
396 for (param = 0; param < query_info.n_params; param++)
400 sprintf (pos, "%s\\n", arg_names[param]);
405 type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
407 /* Most arguments to the callback are called "arg1", "arg2", etc.
408 GdkWidgets are called "widget", "widget2", ...
409 GdkEvents are called "event", "event2", ...
410 GtkCallbacks are called "callback", "callback2", ... */
411 if (!strcmp (type_name, "GtkWidget"))
414 arg_num = &widget_num;
416 else if (!strcmp (type_name, "GdkEvent"))
418 type_name = get_gdk_event (signal_name);
420 arg_num = &event_num;
423 else if (!strcmp (type_name, "GtkCallback")
424 || !strcmp (type_name, "GtkCCallback"))
426 arg_name = "callback";
427 arg_num = &callback_num;
432 arg_num = ¶m_num;
434 sprintf (pos, "%s ", type_name);
437 if (!arg_num || *arg_num == 0)
438 sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
440 sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
455 "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n%s</SIGNAL>\\n\\n",
456 object_name, query_info.signal_name, ret_type_buffer, buffer);
460 /* Returns the type name to use for a signal argument or return value, given
461 the GtkType from the signal info. It also sets is_pointer to TRUE if the
462 argument needs a '*' since it is a pointer. */
464 get_type_name (GType type, gboolean * is_pointer)
466 const gchar *type_name;
469 type_name = g_type_name (type);
483 /* These all have normal C type names so they are OK. */
487 /* A GtkString is really a gchar*. */
493 /* We use a gint for both of these. Hopefully a subtype with a decent
494 name will be registered and used instead, as GTK+ does itself. */
498 /* The boxed type shouldn't be used itself, only subtypes. Though we
499 return 'gpointer' just in case. */
503 /* A GParam is really a GParamSpec*. */
511 /* For all GtkObject subclasses we can use the class name with a "*",
512 e.g. 'GtkWidget *'. */
513 if (g_type_is_a (type, G_TYPE_OBJECT))
516 if (G_TYPE_IS_CLASSED (type))
519 /* All boxed subtypes will be pointers as well. */
520 if (g_type_is_a (type, G_TYPE_BOXED))
523 /* All pointer subtypes will be pointers as well. */
524 if (g_type_is_a (type, G_TYPE_POINTER))
532 get_gdk_event (const gchar * signal_name)
534 static gchar *GbGDKEvents[] =
536 "button_press_event", "GdkEventButton",
537 "button_release_event", "GdkEventButton",
538 "motion_notify_event", "GdkEventMotion",
539 "delete_event", "GdkEvent",
540 "destroy_event", "GdkEvent",
541 "expose_event", "GdkEventExpose",
542 "key_press_event", "GdkEventKey",
543 "key_release_event", "GdkEventKey",
544 "enter_notify_event", "GdkEventCrossing",
545 "leave_notify_event", "GdkEventCrossing",
546 "configure_event", "GdkEventConfigure",
547 "focus_in_event", "GdkEventFocus",
548 "focus_out_event", "GdkEventFocus",
549 "map_event", "GdkEvent",
550 "unmap_event", "GdkEvent",
551 "property_notify_event", "GdkEventProperty",
552 "selection_clear_event", "GdkEventSelection",
553 "selection_request_event", "GdkEventSelection",
554 "selection_notify_event", "GdkEventSelection",
555 "proximity_in_event", "GdkEventProximity",
556 "proximity_out_event", "GdkEventProximity",
557 "drag_begin_event", "GdkEventDragBegin",
558 "drag_request_event", "GdkEventDragRequest",
559 "drag_end_event", "GdkEventDragRequest",
560 "drop_enter_event", "GdkEventDropEnter",
561 "drop_leave_event", "GdkEventDropLeave",
562 "drop_data_available_event", "GdkEventDropDataAvailable",
563 "other_event", "GdkEventOther",
564 "client_event", "GdkEventClient",
565 "no_expose_event", "GdkEventNoExpose",
566 "visibility_notify_event", "GdkEventVisibility",
567 "window_state_event", "GdkEventWindowState",
568 "scroll_event", "GdkEventScroll",
574 for (i = 0; GbGDKEvents[i]; i += 2)
576 if (!strcmp (signal_name, GbGDKEvents[i]))
577 return GbGDKEvents[i + 1];
583 /* This returns argument names to use for some known GTK signals.
584 It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
585 'select_row' and it returns a pointer to an array of argument types and
588 lookup_signal_arg_names (const gchar * type, const gchar * signal_name)
590 /* Each arg array starts with the object type name and the signal name,
591 and then signal arguments follow. */
592 static gchar *GbArgTable[][16] =
594 {"GtkCList", "select_row",
597 "GdkEventButton *event"},
598 {"GtkCList", "unselect_row",
601 "GdkEventButton *event"},
602 {"GtkCList", "click_column",
605 {"GtkCList", "resize_column",
609 {"GtkCList", "extend_selection",
610 "GtkScrollType scroll_type",
612 "gboolean auto_start_selection"},
613 {"GtkCList", "scroll_vertical",
614 "GtkScrollType scroll_type",
616 {"GtkCList", "scroll_horizontal",
617 "GtkScrollType scroll_type",
620 {"GtkCTree", "tree_select_row",
621 "GtkCTreeNode *node",
623 {"GtkCTree", "tree_unselect_row",
624 "GtkCTreeNode *node",
626 {"GtkCTree", "tree_expand",
627 "GtkCTreeNode *node"},
628 {"GtkCTree", "tree_collapse",
629 "GtkCTreeNode *node"},
630 {"GtkCTree", "tree_move",
631 "GtkCTreeNode *node",
632 "GtkCTreeNode *new_parent",
633 "GtkCTreeNode *new_sibling"},
634 {"GtkCTree", "change_focus_row_expansion",
635 "GtkCTreeExpansionType expansion"},
637 {"GtkEditable", "insert_text",
639 "gint new_text_length",
641 {"GtkEditable", "delete_text",
644 {"GtkEditable", "set_editable",
645 "gboolean is_editable"},
646 {"GtkEditable", "move_cursor",
649 {"GtkEditable", "move_word",
651 {"GtkEditable", "move_page",
654 {"GtkEditable", "move_to_row",
656 {"GtkEditable", "move_to_column",
659 {"GtkEditable", "kill_char",
661 {"GtkEditable", "kill_word",
663 {"GtkEditable", "kill_line",
667 {"GtkInputDialog", "enable_device",
668 "GdkDevice *deviceid"},
669 {"GtkInputDialog", "disable_device",
670 "GdkDevice *deviceid"},
672 {"GtkListItem", "extend_selection",
673 "GtkScrollType scroll_type",
675 "gboolean auto_start_selection"},
676 {"GtkListItem", "scroll_vertical",
677 "GtkScrollType scroll_type",
679 {"GtkListItem", "scroll_horizontal",
680 "GtkScrollType scroll_type",
683 {"GtkMenuShell", "move_current",
684 "GtkMenuDirectionType direction"},
685 {"GtkMenuShell", "activate_current",
686 "gboolean force_hide"},
689 {"GtkNotebook", "switch_page",
690 "GtkNotebookPage *page",
692 {"GtkStatusbar", "text_pushed",
695 {"GtkStatusbar", "text_popped",
698 {"GtkTipsQuery", "widget_entered",
701 "gchar *tip_private"},
702 {"GtkTipsQuery", "widget_selected",
705 "gchar *tip_private",
706 "GdkEventButton *event"},
707 {"GtkToolbar", "orientation_changed",
708 "GtkOrientation orientation"},
709 {"GtkToolbar", "style_changed",
710 "GtkToolbarStyle style"},
711 {"GtkWidget", "draw",
712 "GdkRectangle *area"},
713 {"GtkWidget", "size_request",
714 "GtkRequisition *requisition"},
715 {"GtkWidget", "size_allocate",
716 "GtkAllocation *allocation"},
717 {"GtkWidget", "state_changed",
718 "GtkStateType state"},
719 {"GtkWidget", "style_set",
720 "GtkStyle *previous_style"},
722 {"GtkWidget", "install_accelerator",
723 "gchar *signal_name",
727 {"GtkWidget", "add_accelerator",
728 "guint accel_signal_id",
729 "GtkAccelGroup *accel_group",
731 "GdkModifierType accel_mods",
732 "GtkAccelFlags accel_flags"},
734 {"GtkWidget", "parent_set",
735 "GtkObject *old_parent"},
737 {"GtkWidget", "remove_accelerator",
738 "GtkAccelGroup *accel_group",
740 "GdkModifierType accel_mods"},
741 {"GtkWidget", "debug_msg",
743 {"GtkWindow", "move_resize",
748 {"GtkWindow", "set_focus",
749 "GtkWidget *widget"},
751 {"GtkWidget", "selection_get",
752 "GtkSelectionData *data",
755 {"GtkWidget", "selection_received",
756 "GtkSelectionData *data",
759 {"GtkWidget", "drag_begin",
760 "GdkDragContext *drag_context"},
761 {"GtkWidget", "drag_end",
762 "GdkDragContext *drag_context"},
763 {"GtkWidget", "drag_data_delete",
764 "GdkDragContext *drag_context"},
765 {"GtkWidget", "drag_leave",
766 "GdkDragContext *drag_context",
768 {"GtkWidget", "drag_motion",
769 "GdkDragContext *drag_context",
773 {"GtkWidget", "drag_drop",
774 "GdkDragContext *drag_context",
778 {"GtkWidget", "drag_data_get",
779 "GdkDragContext *drag_context",
780 "GtkSelectionData *data",
783 {"GtkWidget", "drag_data_received",
784 "GdkDragContext *drag_context",
787 "GtkSelectionData *data",
796 for (i = 0; GbArgTable[i][0]; i++)
799 if (!strcmp (type, GbArgTable[i][0])
800 && !strcmp (signal_name, GbArgTable[i][1]))
801 return &GbArgTable[i][2];
807 /* This outputs the hierarchy of all widgets which have been initialized,
808 i.e. by calling their XXX_get_type() initialization function. */
810 output_widget_hierarchy (void)
814 fp = fopen (hierarchy_filename, "w");
817 g_warning ("Couldn't open output file: %s", hierarchy_filename);
820 output_hierarchy (fp, G_TYPE_OBJECT, 0);
821 output_hierarchy (fp, G_TYPE_INTERFACE, 0);
825 /* This is called recursively to output the hierarchy of a widget. */
827 output_hierarchy (FILE *fp,
838 for (i = 0; i < level; i++)
840 fprintf (fp, g_type_name (type));
843 children = g_type_children (type, &n_children);
845 for (i=0; i < n_children; i++)
846 output_hierarchy (fp, children[i], level + 1);
851 static void output_widget_interfaces (void)
855 fp = fopen (interfaces_filename, "w");
858 g_warning ("Couldn't open output file: %s", interfaces_filename);
861 output_interfaces (fp, G_TYPE_OBJECT);
866 output_interfaces (FILE *fp,
870 GType *children, *interfaces;
871 guint n_children, n_interfaces;
876 interfaces = g_type_interfaces (type, &n_interfaces);
878 if (n_interfaces > 0)
880 fprintf (fp, g_type_name (type));
881 for (i=0; i < n_interfaces; i++)
882 fprintf (fp, " %s", g_type_name (interfaces[i]));
887 children = g_type_children (type, &n_children);
889 for (i=0; i < n_children; i++)
890 output_interfaces (fp, children[i]);
895 static void output_interface_prerequisites (void)
899 fp = fopen (prerequisites_filename, "w");
902 g_warning ("Couldn't open output file: %s", prerequisites_filename);
905 output_prerequisites (fp, G_TYPE_INTERFACE);
910 output_prerequisites (FILE *fp,
913 #if GLIB_CHECK_VERSION(2,1,0)
915 GType *children, *prerequisites;
916 guint n_children, n_prerequisites;
921 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
923 if (n_prerequisites > 0)
925 fprintf (fp, g_type_name (type));
926 for (i=0; i < n_prerequisites; i++)
927 fprintf (fp, " %s", g_type_name (prerequisites[i]));
930 g_free (prerequisites);
932 children = g_type_children (type, &n_children);
934 for (i=0; i < n_children; i++)
935 output_prerequisites (fp, children[i]);
947 fp = fopen (args_filename, "w");
950 g_warning ("Couldn't open output file: %s", args_filename);
954 for (i = 0; i < num_object_types; i++)
955 output_widget_args (fp, object_types[i]);
961 compare_param_specs (const void *a, const void *b)
963 GParamSpec *spec_a = *(GParamSpec **)a;
964 GParamSpec *spec_b = *(GParamSpec **)b;
966 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
969 /* Its common to have unsigned properties restricted
970 * to the signed range. Therefore we make this look
971 * a bit nicer by spelling out the max constants.
975 describe_double_constant (gdouble value)
979 if (value == G_MAXDOUBLE)
980 desc = g_strdup ("G_MAXDOUBLE");
981 else if (value == G_MINDOUBLE)
982 desc = g_strdup ("G_MINDOUBLE");
983 else if (value == -G_MAXDOUBLE)
984 desc = g_strdup ("-G_MAXDOUBLE");
985 else if (value == G_MAXFLOAT)
986 desc = g_strdup ("G_MAXFLOAT");
987 else if (value == G_MINFLOAT)
988 desc = g_strdup ("G_MINFLOAT");
989 else if (value == -G_MAXFLOAT)
990 desc = g_strdup ("-G_MAXFLOAT");
992 desc = g_strdup_printf ("%lg", value);
998 describe_signed_constant (gint64 value)
1002 if (value == G_MAXINT)
1003 desc = g_strdup ("G_MAXINT");
1004 else if (value == G_MININT)
1005 desc = g_strdup ("G_MININT");
1006 else if (value == G_MAXUINT)
1007 desc = g_strdup ("G_MAXUINT");
1008 else if (value == G_MAXLONG)
1009 desc = g_strdup ("G_MAXLONG");
1010 else if (value == G_MINLONG)
1011 desc = g_strdup ("G_MINLONG");
1012 else if (value == G_MAXULONG)
1013 desc = g_strdup ("G_MAXULONG");
1014 else if (value == G_MAXINT64)
1015 desc = g_strdup ("G_MAXINT64");
1016 else if (value == G_MININT64)
1017 desc = g_strdup ("G_MININT64");
1019 desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
1025 describe_unsigned_constant (guint64 value)
1029 if (value == G_MAXINT)
1030 desc = g_strdup ("G_MAXINT");
1031 else if (value == G_MININT)
1032 desc = g_strdup ("G_MININT");
1033 else if (value == G_MAXUINT)
1034 desc = g_strdup ("G_MAXUINT");
1035 else if (value == G_MAXLONG)
1036 desc = g_strdup ("G_MAXLONG");
1037 else if (value == G_MINLONG)
1038 desc = g_strdup ("G_MINLONG");
1039 else if (value == G_MAXULONG)
1040 desc = g_strdup ("G_MAXULONG");
1041 else if (value == G_MAXINT64)
1042 desc = g_strdup ("G_MAXINT64");
1043 else if (value == G_MININT64)
1044 desc = g_strdup ("G_MININT64");
1045 else if (value == G_MAXUINT64)
1046 desc = g_strdup ("G_MAXUINT64");
1048 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
1054 describe_type (GParamSpec *spec)
1060 if (G_IS_PARAM_SPEC_CHAR (spec))
1062 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1064 lower = describe_signed_constant (pspec->minimum);
1065 upper = describe_signed_constant (pspec->maximum);
1066 if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
1067 desc = g_strdup ("");
1068 else if (pspec->minimum == G_MININT8)
1069 desc = g_strdup_printf ("<= %s", upper);
1070 else if (pspec->maximum == G_MAXINT8)
1071 desc = g_strdup_printf (">= %s", lower);
1073 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1077 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1079 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1081 lower = describe_unsigned_constant (pspec->minimum);
1082 upper = describe_unsigned_constant (pspec->maximum);
1083 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
1084 desc = g_strdup ("");
1085 else if (pspec->minimum == 0)
1086 desc = g_strdup_printf ("<= %s", upper);
1087 else if (pspec->maximum == G_MAXUINT8)
1088 desc = g_strdup_printf (">= %s", lower);
1090 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1094 else if (G_IS_PARAM_SPEC_INT (spec))
1096 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1098 lower = describe_signed_constant (pspec->minimum);
1099 upper = describe_signed_constant (pspec->maximum);
1100 if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
1101 desc = g_strdup ("");
1102 else if (pspec->minimum == G_MININT)
1103 desc = g_strdup_printf ("<= %s", upper);
1104 else if (pspec->maximum == G_MAXINT)
1105 desc = g_strdup_printf (">= %s", lower);
1107 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1111 else if (G_IS_PARAM_SPEC_UINT (spec))
1113 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1115 lower = describe_unsigned_constant (pspec->minimum);
1116 upper = describe_unsigned_constant (pspec->maximum);
1117 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
1118 desc = g_strdup ("");
1119 else if (pspec->minimum == 0)
1120 desc = g_strdup_printf ("<= %s", upper);
1121 else if (pspec->maximum == G_MAXUINT)
1122 desc = g_strdup_printf (">= %s", lower);
1124 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1128 else if (G_IS_PARAM_SPEC_LONG (spec))
1130 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1132 lower = describe_signed_constant (pspec->minimum);
1133 upper = describe_signed_constant (pspec->maximum);
1134 if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
1135 desc = g_strdup ("");
1136 else if (pspec->minimum == G_MINLONG)
1137 desc = g_strdup_printf ("<= %s", upper);
1138 else if (pspec->maximum == G_MAXLONG)
1139 desc = g_strdup_printf (">= %s", lower);
1141 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1145 else if (G_IS_PARAM_SPEC_ULONG (spec))
1147 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1150 lower = describe_unsigned_constant (pspec->minimum);
1151 upper = describe_unsigned_constant (pspec->maximum);
1152 if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
1153 desc = g_strdup ("");
1154 else if (pspec->minimum == 0)
1155 desc = g_strdup_printf ("<= %s", upper);
1156 else if (pspec->maximum == G_MAXULONG)
1157 desc = g_strdup_printf (">= %s", lower);
1159 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1163 else if (G_IS_PARAM_SPEC_INT64 (spec))
1165 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1167 lower = describe_signed_constant (pspec->minimum);
1168 upper = describe_signed_constant (pspec->maximum);
1169 if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
1170 desc = g_strdup ("");
1171 else if (pspec->minimum == G_MININT64)
1172 desc = g_strdup_printf ("<= %s", upper);
1173 else if (pspec->maximum == G_MAXINT64)
1174 desc = g_strdup_printf (">= %s", lower);
1176 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1180 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1182 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1184 lower = describe_unsigned_constant (pspec->minimum);
1185 upper = describe_unsigned_constant (pspec->maximum);
1186 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
1187 desc = g_strdup ("");
1188 else if (pspec->minimum == 0)
1189 desc = g_strdup_printf ("<= %s", upper);
1190 else if (pspec->maximum == G_MAXUINT64)
1191 desc = g_strdup_printf (">= %s", lower);
1193 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1197 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1199 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1201 lower = describe_double_constant (pspec->minimum);
1202 upper = describe_double_constant (pspec->maximum);
1203 if (pspec->minimum == -G_MAXFLOAT && pspec->maximum == G_MAXFLOAT)
1204 desc = g_strdup ("");
1205 else if (pspec->minimum == -G_MAXFLOAT)
1206 desc = g_strdup_printf ("<= %s", upper);
1207 else if (pspec->maximum == G_MAXFLOAT)
1208 desc = g_strdup_printf (">= %s", lower);
1210 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1214 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1216 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1218 lower = describe_double_constant (pspec->minimum);
1219 upper = describe_double_constant (pspec->maximum);
1220 if (pspec->minimum == -G_MAXDOUBLE && pspec->maximum == G_MAXDOUBLE)
1221 desc = g_strdup ("");
1222 else if (pspec->minimum == -G_MAXDOUBLE)
1223 desc = g_strdup_printf ("<= %s", upper);
1224 else if (pspec->maximum == G_MAXDOUBLE)
1225 desc = g_strdup_printf (">= %s", lower);
1227 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1233 desc = g_strdup ("");
1240 describe_default (GParamSpec *spec)
1244 if (G_IS_PARAM_SPEC_CHAR (spec))
1246 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1248 desc = g_strdup_printf ("%d", pspec->default_value);
1250 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1252 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1254 desc = g_strdup_printf ("%u", pspec->default_value);
1256 else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
1258 GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
1260 desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
1262 else if (G_IS_PARAM_SPEC_INT (spec))
1264 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1266 desc = g_strdup_printf ("%d", pspec->default_value);
1268 else if (G_IS_PARAM_SPEC_UINT (spec))
1270 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1272 desc = g_strdup_printf ("%u", pspec->default_value);
1274 else if (G_IS_PARAM_SPEC_LONG (spec))
1276 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1278 desc = g_strdup_printf ("%ld", pspec->default_value);
1280 else if (G_IS_PARAM_SPEC_LONG (spec))
1282 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1284 desc = g_strdup_printf ("%lu", pspec->default_value);
1286 else if (G_IS_PARAM_SPEC_INT64 (spec))
1288 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1290 desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
1292 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1294 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1296 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
1298 else if (G_IS_PARAM_SPEC_UNICHAR (spec))
1300 GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
1302 if (g_unichar_isprint (pspec->default_value))
1303 desc = g_strdup_printf ("'%c'", pspec->default_value);
1305 desc = g_strdup_printf ("%u", pspec->default_value);
1307 else if (G_IS_PARAM_SPEC_ENUM (spec))
1309 GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
1311 GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
1313 desc = g_strdup_printf ("%s", value->value_name);
1315 desc = g_strdup_printf ("%d", pspec->default_value);
1317 else if (G_IS_PARAM_SPEC_FLAGS (spec))
1319 GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
1320 guint default_value;
1323 default_value = pspec->default_value;
1324 acc = g_string_new ("");
1326 while (default_value)
1328 GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
1334 g_string_append (acc, "|");
1335 g_string_append (acc, value->value_name);
1337 default_value &= ~value->value;
1340 if (default_value == 0)
1341 desc = g_string_free (acc, FALSE);
1344 desc = g_strdup_printf ("%d", pspec->default_value);
1345 g_string_free (acc, TRUE);
1348 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1350 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1352 desc = g_strdup_printf ("%g", pspec->default_value);
1354 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1356 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1358 desc = g_strdup_printf ("%lg", pspec->default_value);
1360 else if (G_IS_PARAM_SPEC_STRING (spec))
1362 GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
1364 if (pspec->default_value)
1366 gchar *esc = g_strescape (pspec->default_value, NULL);
1368 desc = g_strdup_printf ("\\"%s\\"", esc);
1373 desc = g_strdup_printf ("NULL");
1377 desc = g_strdup ("");
1385 output_widget_args (FILE *fp, GType object_type)
1388 const gchar *object_class_name;
1390 gchar flags[16], *pos;
1391 GParamSpec **properties;
1393 gboolean child_prop;
1394 gboolean style_prop;
1396 gchar *default_value;
1398 if (G_TYPE_IS_CLASSED (object_type))
1400 class = g_type_class_peek (object_type);
1404 properties = g_object_class_list_properties (class, &n_properties);
1406 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
1407 else if (G_TYPE_IS_INTERFACE (object_type))
1409 class = g_type_default_interface_ref (object_type);
1414 properties = g_object_interface_list_properties (class, &n_properties);
1420 object_class_name = g_type_name (object_type);
1426 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
1427 for (arg = 0; arg < n_properties; arg++)
1429 GParamSpec *spec = properties[arg];
1430 const gchar *nick, *blurb, *dot;
1432 if (spec->owner_type != object_type)
1436 /* We use one-character flags for simplicity. */
1437 if (child_prop && !style_prop)
1441 if (spec->flags & G_PARAM_READABLE)
1443 if (spec->flags & G_PARAM_WRITABLE)
1445 if (spec->flags & G_PARAM_CONSTRUCT)
1447 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
1451 nick = g_param_spec_get_nick (spec);
1452 blurb = g_param_spec_get_blurb (spec);
1456 int str_len = strlen (blurb);
1457 if (str_len > 0 && blurb[str_len - 1] != '.')
1461 type_desc = describe_type (spec);
1462 default_value = describe_default (spec);
1463 fprintf (fp, "<ARG>\\n<NAME>%s::%s</NAME>\\n<TYPE>%s</TYPE>\\n<RANGE>%s</RANGE>\\n<FLAGS>%s</FLAGS>\\n<NICK>%s</NICK>\\n<BLURB>%s%s</BLURB>\\n<DEFAULT>%s</DEFAULT>\\n</ARG>\\n\\n",
1464 object_class_name, g_param_spec_get_name (spec), g_type_name (spec->value_type), type_desc, flags, nick ? nick : "(null)", blurb ? blurb : "(null)", dot, default_value);
1466 g_free (default_value);
1469 g_free (properties);
1471 #ifdef GTK_IS_CONTAINER_CLASS
1472 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
1473 properties = gtk_container_class_list_child_properties (class, &n_properties);
1479 #ifdef GTK_IS_WIDGET_CLASS
1480 #if GTK_CHECK_VERSION(2,1,0)
1481 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
1482 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1496 # Compile and run our file
1498 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
1499 $LD = $ENV{LD} ? $ENV{LD} : $CC;
1500 $CFLAGS = $ENV{CFLAGS} ? "$ENV{CFLAGS} -Wall -g" : "-Wall -g";
1501 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
1504 if ($CC =~ /libtool/) {
1505 $o_file = "$MODULE-scan.lo"
1507 $o_file = "$MODULE-scan.o"
1510 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c && $LD -o $MODULE-scan $o_file $LDFLAGS";
1512 system($command) == 0 or die "Compilation of scanner failed\n";
1514 system("./$MODULE-scan") == 0 or die "Scan failed\n";
1516 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
1518 #&UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
1519 #&UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
1520 #&UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
1521 #&UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
1522 #&UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);