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 the number of types from the registry */
144 plugins = gst_registry_pool_plugin_list ();
150 plugin = (GstPlugin *) (plugins->data);
151 plugins = g_list_next (plugins);
152 if (strcmp (gst_plugin_get_source (plugin), "$SOURCE") != 0) {
156 features = gst_plugin_get_feature_list (plugin);
158 GstPluginFeature *feature;
159 feature = GST_PLUGIN_FEATURE (features->data);
160 if (!gst_plugin_feature_ensure_loaded (feature)) {
161 g_warning ("Could not load plugin feature %s",
162 gst_plugin_feature_get_name (feature));
165 if (GST_IS_ELEMENT_FACTORY (feature)) {
166 factory = GST_ELEMENT_FACTORY (feature);
167 factories = g_list_append (factories, factory);
169 features = g_list_next (features);
173 num_object_types = g_list_length (factories);
174 g_message ("number of element factories: %d", g_list_length (factories));
176 /* allocate the object_types array to hold them */
177 object_types = g_new0 (GType, g_list_length (factories));
185 factory = GST_ELEMENT_FACTORY (l->data);
186 g_message ("adding type for factory %s", gst_element_factory_get_longname (factory));
187 type = gst_element_factory_get_element_type (factory);
188 g_message ("adding type %p", (void *) type);
189 object_types[i] = type;
197 /* Need to make sure all the types are loaded in and initialize
198 * their signals and properties.
200 g_message ("class reffing");
202 for (i=0; i < num_object_types; i++) {
203 if (G_TYPE_IS_CLASSED (object_types[i]))
204 g_type_class_ref (object_types[i]);
211 * This uses GTK type functions to output signal prototypes and the widget
215 /* The output files */
216 gchar *signals_filename = "$new_signals_filename";
217 gchar *hierarchy_filename = "$new_hierarchy_filename";
218 gchar *interfaces_filename = "$new_interfaces_filename";
219 gchar *prerequisites_filename = "$new_prerequisites_filename";
220 gchar *args_filename = "$new_args_filename";
223 static void output_signals (void);
224 static void output_widget_signals (FILE *fp,
226 static void output_widget_signal (FILE *fp,
228 const gchar *object_class_name,
230 static const gchar * get_type_name (GType type,
231 gboolean * is_pointer);
232 static gchar * get_gdk_event (const gchar * signal_name);
233 static gchar ** lookup_signal_arg_names (const gchar * type,
234 const gchar * signal_name);
236 static void output_widget_hierarchy (void);
237 static void output_hierarchy (FILE *fp,
241 static void output_widget_interfaces (void);
242 static void output_interfaces (FILE *fp,
245 static void output_interface_prerequisites (void);
246 static void output_prerequisites (FILE *fp,
249 static void output_args (void);
250 static void output_widget_args (FILE *fp, GType object_type);
253 main (int argc, char *argv[])
259 g_message ("output signals");
261 g_message ("output widget hierarchy");
262 output_widget_hierarchy ();
263 output_widget_interfaces ();
264 output_interface_prerequisites ();
265 g_message ("output args");
273 output_signals (void)
278 fp = fopen (signals_filename, "w");
281 g_warning ("Couldn't open output file: %s", signals_filename);
285 for (i = 0; i < num_object_types; i++)
286 output_widget_signals (fp, object_types[i]);
292 compare_signals (const void *a, const void *b)
294 const guint *signal_a = a;
295 const guint *signal_b = b;
297 return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b));
300 /* This outputs all the signals of one widget. */
302 output_widget_signals (FILE *fp, GType object_type)
304 const gchar *object_class_name;
305 guint *signals, n_signals;
308 if (G_TYPE_IS_INSTANTIATABLE (object_type) ||
309 G_TYPE_IS_INTERFACE (object_type))
312 object_class_name = g_type_name (object_type);
314 signals = g_signal_list_ids (object_type, &n_signals);
315 qsort (signals, n_signals, sizeof (guint), compare_signals);
317 for (sig = 0; sig < n_signals; sig++)
319 output_widget_signal (fp, object_type, object_class_name,
327 /* This outputs one signal. */
329 output_widget_signal (FILE *fp,
331 const gchar *object_name,
334 GSignalQuery query_info;
335 const gchar *type_name, *ret_type, *object_arg;
336 gchar *pos, *arg_name, *object_arg_lower;
338 gchar ret_type_buffer[1024], buffer[1024];
341 gint param_num, widget_num, event_num, callback_num;
343 gchar signal_name[128];
346 /* g_print ("Object: %s Type: %i Signal: %u\\n", object_name, object_type,
350 widget_num = event_num = callback_num = 0;
352 g_signal_query (signal_id, &query_info);
354 /* Output the return type and function name. */
355 ret_type = get_type_name (query_info.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
356 sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : "");
358 /* Output the signal object type and the argument name. We assume the
359 type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and
360 convert to lower case for the argument name. */
362 sprintf (pos, "%s ", object_name);
365 if (!strncmp (object_name, "Gtk", 3))
366 object_arg = object_name + 3;
367 else if (!strncmp (object_name, "Gnome", 5))
368 object_arg = object_name + 5;
370 object_arg = object_name;
372 object_arg_lower = g_ascii_strdown (object_arg, -1);
373 sprintf (pos, "*%s\\n", object_arg_lower);
375 if (!strncmp (object_arg_lower, "widget", 6))
377 g_free(object_arg_lower);
379 /* Convert signal name to use underscores rather than dashes '-'. */
380 strcpy (signal_name, query_info.signal_name);
381 for (i = 0; signal_name[i]; i++)
383 if (signal_name[i] == '-')
384 signal_name[i] = '_';
387 /* Output the signal parameters. */
388 arg_names = lookup_signal_arg_names (object_name, signal_name);
390 for (param = 0; param < query_info.n_params; param++)
394 sprintf (pos, "%s\\n", arg_names[param]);
399 type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
401 /* Most arguments to the callback are called "arg1", "arg2", etc.
402 GdkWidgets are called "widget", "widget2", ...
403 GdkEvents are called "event", "event2", ...
404 GtkCallbacks are called "callback", "callback2", ... */
405 if (!strcmp (type_name, "GtkWidget"))
408 arg_num = &widget_num;
410 else if (!strcmp (type_name, "GdkEvent"))
412 type_name = get_gdk_event (signal_name);
414 arg_num = &event_num;
417 else if (!strcmp (type_name, "GtkCallback")
418 || !strcmp (type_name, "GtkCCallback"))
420 arg_name = "callback";
421 arg_num = &callback_num;
426 arg_num = ¶m_num;
428 sprintf (pos, "%s ", type_name);
431 if (!arg_num || *arg_num == 0)
432 sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
434 sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
449 "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n%s</SIGNAL>\\n\\n",
450 object_name, query_info.signal_name, ret_type_buffer, buffer);
454 /* Returns the type name to use for a signal argument or return value, given
455 the GtkType from the signal info. It also sets is_pointer to TRUE if the
456 argument needs a '*' since it is a pointer. */
458 get_type_name (GType type, gboolean * is_pointer)
460 const gchar *type_name;
463 type_name = g_type_name (type);
477 /* These all have normal C type names so they are OK. */
481 /* A GtkString is really a gchar*. */
487 /* We use a gint for both of these. Hopefully a subtype with a decent
488 name will be registered and used instead, as GTK+ does itself. */
492 /* The boxed type shouldn't be used itself, only subtypes. Though we
493 return 'gpointer' just in case. */
497 /* A GParam is really a GParamSpec*. */
505 /* For all GtkObject subclasses we can use the class name with a "*",
506 e.g. 'GtkWidget *'. */
507 if (g_type_is_a (type, G_TYPE_OBJECT))
510 /* All boxed subtypes will be pointers as well. */
511 if (g_type_is_a (type, G_TYPE_BOXED))
514 /* All pointer subtypes will be pointers as well. */
515 if (g_type_is_a (type, G_TYPE_POINTER))
523 get_gdk_event (const gchar * signal_name)
525 static gchar *GbGDKEvents[] =
527 "button_press_event", "GdkEventButton",
528 "button_release_event", "GdkEventButton",
529 "motion_notify_event", "GdkEventMotion",
530 "delete_event", "GdkEvent",
531 "destroy_event", "GdkEvent",
532 "expose_event", "GdkEventExpose",
533 "key_press_event", "GdkEventKey",
534 "key_release_event", "GdkEventKey",
535 "enter_notify_event", "GdkEventCrossing",
536 "leave_notify_event", "GdkEventCrossing",
537 "configure_event", "GdkEventConfigure",
538 "focus_in_event", "GdkEventFocus",
539 "focus_out_event", "GdkEventFocus",
540 "map_event", "GdkEvent",
541 "unmap_event", "GdkEvent",
542 "property_notify_event", "GdkEventProperty",
543 "selection_clear_event", "GdkEventSelection",
544 "selection_request_event", "GdkEventSelection",
545 "selection_notify_event", "GdkEventSelection",
546 "proximity_in_event", "GdkEventProximity",
547 "proximity_out_event", "GdkEventProximity",
548 "drag_begin_event", "GdkEventDragBegin",
549 "drag_request_event", "GdkEventDragRequest",
550 "drag_end_event", "GdkEventDragRequest",
551 "drop_enter_event", "GdkEventDropEnter",
552 "drop_leave_event", "GdkEventDropLeave",
553 "drop_data_available_event", "GdkEventDropDataAvailable",
554 "other_event", "GdkEventOther",
555 "client_event", "GdkEventClient",
556 "no_expose_event", "GdkEventNoExpose",
557 "visibility_notify_event", "GdkEventVisibility",
558 "window_state_event", "GdkEventWindowState",
559 "scroll_event", "GdkEventScroll",
565 for (i = 0; GbGDKEvents[i]; i += 2)
567 if (!strcmp (signal_name, GbGDKEvents[i]))
568 return GbGDKEvents[i + 1];
574 /* This returns argument names to use for some known GTK signals.
575 It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
576 'select_row' and it returns a pointer to an array of argument types and
579 lookup_signal_arg_names (const gchar * type, const gchar * signal_name)
581 /* Each arg array starts with the object type name and the signal name,
582 and then signal arguments follow. */
583 static gchar *GbArgTable[][16] =
585 {"GtkCList", "select_row",
588 "GdkEventButton *event"},
589 {"GtkCList", "unselect_row",
592 "GdkEventButton *event"},
593 {"GtkCList", "click_column",
596 {"GtkCList", "resize_column",
600 {"GtkCList", "extend_selection",
601 "GtkScrollType scroll_type",
603 "gboolean auto_start_selection"},
604 {"GtkCList", "scroll_vertical",
605 "GtkScrollType scroll_type",
607 {"GtkCList", "scroll_horizontal",
608 "GtkScrollType scroll_type",
611 {"GtkCTree", "tree_select_row",
612 "GtkCTreeNode *node",
614 {"GtkCTree", "tree_unselect_row",
615 "GtkCTreeNode *node",
617 {"GtkCTree", "tree_expand",
618 "GtkCTreeNode *node"},
619 {"GtkCTree", "tree_collapse",
620 "GtkCTreeNode *node"},
621 {"GtkCTree", "tree_move",
622 "GtkCTreeNode *node",
623 "GtkCTreeNode *new_parent",
624 "GtkCTreeNode *new_sibling"},
625 {"GtkCTree", "change_focus_row_expansion",
626 "GtkCTreeExpansionType expansion"},
628 {"GtkEditable", "insert_text",
630 "gint new_text_length",
632 {"GtkEditable", "delete_text",
635 {"GtkEditable", "set_editable",
636 "gboolean is_editable"},
637 {"GtkEditable", "move_cursor",
640 {"GtkEditable", "move_word",
642 {"GtkEditable", "move_page",
645 {"GtkEditable", "move_to_row",
647 {"GtkEditable", "move_to_column",
650 {"GtkEditable", "kill_char",
652 {"GtkEditable", "kill_word",
654 {"GtkEditable", "kill_line",
658 {"GtkInputDialog", "enable_device",
659 "GdkDevice *deviceid"},
660 {"GtkInputDialog", "disable_device",
661 "GdkDevice *deviceid"},
663 {"GtkListItem", "extend_selection",
664 "GtkScrollType scroll_type",
666 "gboolean auto_start_selection"},
667 {"GtkListItem", "scroll_vertical",
668 "GtkScrollType scroll_type",
670 {"GtkListItem", "scroll_horizontal",
671 "GtkScrollType scroll_type",
674 {"GtkMenuShell", "move_current",
675 "GtkMenuDirectionType direction"},
676 {"GtkMenuShell", "activate_current",
677 "gboolean force_hide"},
680 {"GtkNotebook", "switch_page",
681 "GtkNotebookPage *page",
683 {"GtkStatusbar", "text_pushed",
686 {"GtkStatusbar", "text_popped",
689 {"GtkTipsQuery", "widget_entered",
692 "gchar *tip_private"},
693 {"GtkTipsQuery", "widget_selected",
696 "gchar *tip_private",
697 "GdkEventButton *event"},
698 {"GtkToolbar", "orientation_changed",
699 "GtkOrientation orientation"},
700 {"GtkToolbar", "style_changed",
701 "GtkToolbarStyle style"},
702 {"GtkWidget", "draw",
703 "GdkRectangle *area"},
704 {"GtkWidget", "size_request",
705 "GtkRequisition *requisition"},
706 {"GtkWidget", "size_allocate",
707 "GtkAllocation *allocation"},
708 {"GtkWidget", "state_changed",
709 "GtkStateType state"},
710 {"GtkWidget", "style_set",
711 "GtkStyle *previous_style"},
713 {"GtkWidget", "install_accelerator",
714 "gchar *signal_name",
718 {"GtkWidget", "add_accelerator",
719 "guint accel_signal_id",
720 "GtkAccelGroup *accel_group",
722 "GdkModifierType accel_mods",
723 "GtkAccelFlags accel_flags"},
725 {"GtkWidget", "parent_set",
726 "GtkObject *old_parent"},
728 {"GtkWidget", "remove_accelerator",
729 "GtkAccelGroup *accel_group",
731 "GdkModifierType accel_mods"},
732 {"GtkWidget", "debug_msg",
734 {"GtkWindow", "move_resize",
739 {"GtkWindow", "set_focus",
740 "GtkWidget *widget"},
742 {"GtkWidget", "selection_get",
743 "GtkSelectionData *data",
746 {"GtkWidget", "selection_received",
747 "GtkSelectionData *data",
750 {"GtkWidget", "drag_begin",
751 "GdkDragContext *drag_context"},
752 {"GtkWidget", "drag_end",
753 "GdkDragContext *drag_context"},
754 {"GtkWidget", "drag_data_delete",
755 "GdkDragContext *drag_context"},
756 {"GtkWidget", "drag_leave",
757 "GdkDragContext *drag_context",
759 {"GtkWidget", "drag_motion",
760 "GdkDragContext *drag_context",
764 {"GtkWidget", "drag_drop",
765 "GdkDragContext *drag_context",
769 {"GtkWidget", "drag_data_get",
770 "GdkDragContext *drag_context",
771 "GtkSelectionData *data",
774 {"GtkWidget", "drag_data_received",
775 "GdkDragContext *drag_context",
778 "GtkSelectionData *data",
787 for (i = 0; GbArgTable[i][0]; i++)
790 if (!strcmp (type, GbArgTable[i][0])
791 && !strcmp (signal_name, GbArgTable[i][1]))
792 return &GbArgTable[i][2];
798 /* This outputs the hierarchy of all widgets which have been initialized,
799 i.e. by calling their XXX_get_type() initialization function. */
801 output_widget_hierarchy (void)
805 fp = fopen (hierarchy_filename, "w");
808 g_warning ("Couldn't open output file: %s", hierarchy_filename);
811 output_hierarchy (fp, G_TYPE_OBJECT, 0);
812 output_hierarchy (fp, G_TYPE_INTERFACE, 0);
816 /* This is called recursively to output the hierarchy of a widget. */
818 output_hierarchy (FILE *fp,
829 for (i = 0; i < level; i++)
831 fprintf (fp, g_type_name (type));
834 children = g_type_children (type, &n_children);
836 for (i=0; i < n_children; i++)
837 output_hierarchy (fp, children[i], level + 1);
842 static void output_widget_interfaces (void)
846 fp = fopen (interfaces_filename, "w");
849 g_warning ("Couldn't open output file: %s", interfaces_filename);
852 output_interfaces (fp, G_TYPE_OBJECT);
857 output_interfaces (FILE *fp,
861 GType *children, *interfaces;
862 guint n_children, n_interfaces;
867 interfaces = g_type_interfaces (type, &n_interfaces);
869 if (n_interfaces > 0)
871 fprintf (fp, g_type_name (type));
872 for (i=0; i < n_interfaces; i++)
873 fprintf (fp, " %s", g_type_name (interfaces[i]));
878 children = g_type_children (type, &n_children);
880 for (i=0; i < n_children; i++)
881 output_interfaces (fp, children[i]);
886 static void output_interface_prerequisites (void)
890 fp = fopen (prerequisites_filename, "w");
893 g_warning ("Couldn't open output file: %s", prerequisites_filename);
896 output_prerequisites (fp, G_TYPE_INTERFACE);
901 output_prerequisites (FILE *fp,
904 #if GLIB_CHECK_VERSION(2,1,0)
906 GType *children, *prerequisites;
907 guint n_children, n_prerequisites;
912 prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
914 if (n_prerequisites > 0)
916 fprintf (fp, g_type_name (type));
917 for (i=0; i < n_prerequisites; i++)
918 fprintf (fp, " %s", g_type_name (prerequisites[i]));
921 g_free (prerequisites);
923 children = g_type_children (type, &n_children);
925 for (i=0; i < n_children; i++)
926 output_prerequisites (fp, children[i]);
938 fp = fopen (args_filename, "w");
941 g_warning ("Couldn't open output file: %s", args_filename);
945 for (i = 0; i < num_object_types; i++)
946 output_widget_args (fp, object_types[i]);
952 compare_param_specs (const void *a, const void *b)
954 GParamSpec *spec_a = *(GParamSpec **)a;
955 GParamSpec *spec_b = *(GParamSpec **)b;
957 return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
960 /* Its common to have unsigned properties restricted
961 * to the signed range. Therefore we make this look
962 * a bit nicer by spelling out the max constants.
966 describe_double_constant (gdouble value)
970 if (value == G_MAXDOUBLE)
971 desc = g_strdup ("G_MAXDOUBLE");
972 else if (value == G_MINDOUBLE)
973 desc = g_strdup ("G_MINDOUBLE");
974 else if (value == -G_MAXDOUBLE)
975 desc = g_strdup ("-G_MAXDOUBLE");
976 else if (value == G_MAXFLOAT)
977 desc = g_strdup ("G_MAXFLOAT");
978 else if (value == G_MINFLOAT)
979 desc = g_strdup ("G_MINFLOAT");
980 else if (value == -G_MAXFLOAT)
981 desc = g_strdup ("-G_MAXFLOAT");
983 desc = g_strdup_printf ("%lg", value);
989 describe_signed_constant (gint64 value)
993 if (value == G_MAXINT)
994 desc = g_strdup ("G_MAXINT");
995 else if (value == G_MININT)
996 desc = g_strdup ("G_MININT");
997 else if (value == G_MAXUINT)
998 desc = g_strdup ("G_MAXUINT");
999 else if (value == G_MAXLONG)
1000 desc = g_strdup ("G_MAXLONG");
1001 else if (value == G_MINLONG)
1002 desc = g_strdup ("G_MINLONG");
1003 else if (value == G_MAXULONG)
1004 desc = g_strdup ("G_MAXULONG");
1005 else if (value == G_MAXINT64)
1006 desc = g_strdup ("G_MAXINT64");
1007 else if (value == G_MININT64)
1008 desc = g_strdup ("G_MININT64");
1010 desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
1016 describe_unsigned_constant (guint64 value)
1020 if (value == G_MAXINT)
1021 desc = g_strdup ("G_MAXINT");
1022 else if (value == G_MININT)
1023 desc = g_strdup ("G_MININT");
1024 else if (value == G_MAXUINT)
1025 desc = g_strdup ("G_MAXUINT");
1026 else if (value == G_MAXLONG)
1027 desc = g_strdup ("G_MAXLONG");
1028 else if (value == G_MINLONG)
1029 desc = g_strdup ("G_MINLONG");
1030 else if (value == G_MAXULONG)
1031 desc = g_strdup ("G_MAXULONG");
1032 else if (value == G_MAXINT64)
1033 desc = g_strdup ("G_MAXINT64");
1034 else if (value == G_MININT64)
1035 desc = g_strdup ("G_MININT64");
1036 else if (value == G_MAXUINT64)
1037 desc = g_strdup ("G_MAXUINT64");
1039 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
1045 describe_type (GParamSpec *spec)
1051 if (G_IS_PARAM_SPEC_CHAR (spec))
1053 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1055 lower = describe_signed_constant (pspec->minimum);
1056 upper = describe_signed_constant (pspec->maximum);
1057 if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
1058 desc = g_strdup ("");
1059 else if (pspec->minimum == G_MININT8)
1060 desc = g_strdup_printf ("<= %s", upper);
1061 else if (pspec->maximum == G_MAXINT8)
1062 desc = g_strdup_printf (">= %s", lower);
1064 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1068 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1070 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1072 lower = describe_unsigned_constant (pspec->minimum);
1073 upper = describe_unsigned_constant (pspec->maximum);
1074 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
1075 desc = g_strdup ("");
1076 else if (pspec->minimum == 0)
1077 desc = g_strdup_printf ("<= %s", upper);
1078 else if (pspec->maximum == G_MAXUINT8)
1079 desc = g_strdup_printf (">= %s", lower);
1081 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1085 else if (G_IS_PARAM_SPEC_INT (spec))
1087 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1089 lower = describe_signed_constant (pspec->minimum);
1090 upper = describe_signed_constant (pspec->maximum);
1091 if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
1092 desc = g_strdup ("");
1093 else if (pspec->minimum == G_MININT)
1094 desc = g_strdup_printf ("<= %s", upper);
1095 else if (pspec->maximum == G_MAXINT)
1096 desc = g_strdup_printf (">= %s", lower);
1098 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1102 else if (G_IS_PARAM_SPEC_UINT (spec))
1104 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1106 lower = describe_unsigned_constant (pspec->minimum);
1107 upper = describe_unsigned_constant (pspec->maximum);
1108 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
1109 desc = g_strdup ("");
1110 else if (pspec->minimum == 0)
1111 desc = g_strdup_printf ("<= %s", upper);
1112 else if (pspec->maximum == G_MAXUINT)
1113 desc = g_strdup_printf (">= %s", lower);
1115 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1119 else if (G_IS_PARAM_SPEC_LONG (spec))
1121 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1123 lower = describe_signed_constant (pspec->minimum);
1124 upper = describe_signed_constant (pspec->maximum);
1125 if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
1126 desc = g_strdup ("");
1127 else if (pspec->minimum == G_MINLONG)
1128 desc = g_strdup_printf ("<= %s", upper);
1129 else if (pspec->maximum == G_MAXLONG)
1130 desc = g_strdup_printf (">= %s", lower);
1132 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1136 else if (G_IS_PARAM_SPEC_ULONG (spec))
1138 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1141 lower = describe_unsigned_constant (pspec->minimum);
1142 upper = describe_unsigned_constant (pspec->maximum);
1143 if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
1144 desc = g_strdup ("");
1145 else if (pspec->minimum == 0)
1146 desc = g_strdup_printf ("<= %s", upper);
1147 else if (pspec->maximum == G_MAXULONG)
1148 desc = g_strdup_printf (">= %s", lower);
1150 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1154 else if (G_IS_PARAM_SPEC_INT64 (spec))
1156 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1158 lower = describe_signed_constant (pspec->minimum);
1159 upper = describe_signed_constant (pspec->maximum);
1160 if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
1161 desc = g_strdup ("");
1162 else if (pspec->minimum == G_MININT64)
1163 desc = g_strdup_printf ("<= %s", upper);
1164 else if (pspec->maximum == G_MAXINT64)
1165 desc = g_strdup_printf (">= %s", lower);
1167 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1171 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1173 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1175 lower = describe_unsigned_constant (pspec->minimum);
1176 upper = describe_unsigned_constant (pspec->maximum);
1177 if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
1178 desc = g_strdup ("");
1179 else if (pspec->minimum == 0)
1180 desc = g_strdup_printf ("<= %s", upper);
1181 else if (pspec->maximum == G_MAXUINT64)
1182 desc = g_strdup_printf (">= %s", lower);
1184 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1188 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1190 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1192 lower = describe_double_constant (pspec->minimum);
1193 upper = describe_double_constant (pspec->maximum);
1194 if (pspec->minimum == -G_MAXFLOAT && pspec->maximum == G_MAXFLOAT)
1195 desc = g_strdup ("");
1196 else if (pspec->minimum == -G_MAXFLOAT)
1197 desc = g_strdup_printf ("<= %s", upper);
1198 else if (pspec->maximum == G_MAXFLOAT)
1199 desc = g_strdup_printf (">= %s", lower);
1201 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1205 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1207 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1209 lower = describe_double_constant (pspec->minimum);
1210 upper = describe_double_constant (pspec->maximum);
1211 if (pspec->minimum == -G_MAXDOUBLE && pspec->maximum == G_MAXDOUBLE)
1212 desc = g_strdup ("");
1213 else if (pspec->minimum == -G_MAXDOUBLE)
1214 desc = g_strdup_printf ("<= %s", upper);
1215 else if (pspec->maximum == G_MAXDOUBLE)
1216 desc = g_strdup_printf (">= %s", lower);
1218 desc = g_strdup_printf ("[%s,%s]", lower, upper);
1224 desc = g_strdup ("");
1231 describe_default (GParamSpec *spec)
1235 if (G_IS_PARAM_SPEC_CHAR (spec))
1237 GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
1239 desc = g_strdup_printf ("%d", pspec->default_value);
1241 else if (G_IS_PARAM_SPEC_UCHAR (spec))
1243 GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
1245 desc = g_strdup_printf ("%u", pspec->default_value);
1247 else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
1249 GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
1251 desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
1253 else if (G_IS_PARAM_SPEC_INT (spec))
1255 GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
1257 desc = g_strdup_printf ("%d", pspec->default_value);
1259 else if (G_IS_PARAM_SPEC_UINT (spec))
1261 GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
1263 desc = g_strdup_printf ("%u", pspec->default_value);
1265 else if (G_IS_PARAM_SPEC_LONG (spec))
1267 GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
1269 desc = g_strdup_printf ("%ld", pspec->default_value);
1271 else if (G_IS_PARAM_SPEC_LONG (spec))
1273 GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
1275 desc = g_strdup_printf ("%lu", pspec->default_value);
1277 else if (G_IS_PARAM_SPEC_INT64 (spec))
1279 GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
1281 desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
1283 else if (G_IS_PARAM_SPEC_UINT64 (spec))
1285 GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
1287 desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
1289 else if (G_IS_PARAM_SPEC_UNICHAR (spec))
1291 GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
1293 if (g_unichar_isprint (pspec->default_value))
1294 desc = g_strdup_printf ("'%c'", pspec->default_value);
1296 desc = g_strdup_printf ("%u", pspec->default_value);
1298 else if (G_IS_PARAM_SPEC_ENUM (spec))
1300 GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
1302 GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
1304 desc = g_strdup_printf ("%s", value->value_name);
1306 desc = g_strdup_printf ("%d", pspec->default_value);
1308 else if (G_IS_PARAM_SPEC_FLAGS (spec))
1310 GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
1311 guint default_value;
1314 default_value = pspec->default_value;
1315 acc = g_string_new ("");
1317 while (default_value)
1319 GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
1325 g_string_append (acc, "|");
1326 g_string_append (acc, value->value_name);
1328 default_value &= ~value->value;
1331 if (default_value == 0)
1332 desc = g_string_free (acc, FALSE);
1335 desc = g_strdup_printf ("%d", pspec->default_value);
1336 g_string_free (acc, TRUE);
1339 else if (G_IS_PARAM_SPEC_FLOAT (spec))
1341 GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
1343 desc = g_strdup_printf ("%g", pspec->default_value);
1345 else if (G_IS_PARAM_SPEC_DOUBLE (spec))
1347 GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
1349 desc = g_strdup_printf ("%lg", pspec->default_value);
1351 else if (G_IS_PARAM_SPEC_STRING (spec))
1353 GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
1355 if (pspec->default_value)
1357 gchar *esc = g_strescape (pspec->default_value, NULL);
1359 desc = g_strdup_printf ("\\"%s\\"", esc);
1364 desc = g_strdup_printf ("NULL");
1368 desc = g_strdup ("");
1376 output_widget_args (FILE *fp, GType object_type)
1379 const gchar *object_class_name;
1381 gchar flags[16], *pos;
1382 GParamSpec **properties;
1384 gboolean child_prop;
1385 gboolean style_prop;
1387 gchar *default_value;
1389 if (G_TYPE_IS_CLASSED (object_type))
1391 class = g_type_class_peek (object_type);
1395 properties = g_object_class_list_properties (class, &n_properties);
1397 #if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
1398 else if (G_TYPE_IS_INTERFACE (object_type))
1400 class = g_type_default_interface_ref (object_type);
1405 properties = g_object_interface_list_properties (class, &n_properties);
1411 object_class_name = g_type_name (object_type);
1417 qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
1418 for (arg = 0; arg < n_properties; arg++)
1420 GParamSpec *spec = properties[arg];
1421 const gchar *nick, *blurb, *dot;
1423 if (spec->owner_type != object_type)
1427 /* We use one-character flags for simplicity. */
1428 if (child_prop && !style_prop)
1432 if (spec->flags & G_PARAM_READABLE)
1434 if (spec->flags & G_PARAM_WRITABLE)
1436 if (spec->flags & G_PARAM_CONSTRUCT)
1438 if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
1442 nick = g_param_spec_get_nick (spec);
1443 blurb = g_param_spec_get_blurb (spec);
1447 int str_len = strlen (blurb);
1448 if (str_len > 0 && blurb[str_len - 1] != '.')
1452 type_desc = describe_type (spec);
1453 default_value = describe_default (spec);
1454 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",
1455 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);
1457 g_free (default_value);
1460 g_free (properties);
1462 #ifdef GTK_IS_CONTAINER_CLASS
1463 if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
1464 properties = gtk_container_class_list_child_properties (class, &n_properties);
1470 #ifdef GTK_IS_WIDGET_CLASS
1471 #if GTK_CHECK_VERSION(2,1,0)
1472 if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
1473 properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
1487 # Compile and run our file
1489 $CC = $ENV{CC} ? $ENV{CC} : "gcc";
1490 $LD = $ENV{LD} ? $ENV{LD} : $CC;
1491 $CFLAGS = $ENV{CFLAGS} ? $ENV{CFLAGS} : "";
1492 $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
1495 if ($CC =~ /libtool/) {
1496 $o_file = "$MODULE-scan.lo"
1498 $o_file = "$MODULE-scan.o"
1501 $command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c && $LD -o $MODULE-scan $o_file $LDFLAGS";
1503 system($command) == 0 or die "Compilation of scanner failed\n";
1505 system("./$MODULE-scan") == 0 or die "Scan failed\n";
1507 unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
1509 #&UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
1510 #&UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
1511 #&UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
1512 #&UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
1513 #&UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);