| #!/usr/bin/perl -w |
| # |
| # gtk-doc - GTK DocBook documentation generator. |
| # Copyright (C) 1998 Damon Chaplin |
| # |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 2 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program; if not, write to the Free Software |
| # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
| # |
| |
| # |
| # This gets information about object heirarchies and signals |
| # by compiling a small C program. CFLAGS and LDFLAGS must be |
| # set appropriately before running this script. |
| # |
| # NOTE: the lookup_signal_srg_names() function contains the argument names of |
| # standard GTK signal handlers. This may need to be updated for new |
| # GTK signals or Gnome widget signals. |
| |
| use Getopt::Long; |
| |
| # Options |
| |
| # name of documentation module |
| my $MODULE; |
| my $OUTPUT_DIR; |
| |
| %optctl = (module => \$MODULE, |
| types => \$TYPES_FILE, |
| nogtkinit => \$NO_GTK_INIT); |
| |
| GetOptions(\%optctl, "module=s", "types:s", "nogtkinit"); |
| |
| $TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$MODULE.types"; |
| |
| open TYPES, $TYPES_FILE || die "Cannot open $TYPES_FILE: $!\n"; |
| open OUTPUT, ">$MODULE-scan.c" || die "Cannot open $MODULE-scan.c: $!\n"; |
| |
| # write a C program to scan the types |
| |
| $includes = ""; |
| @types = (); |
| |
| for (<TYPES>) { |
| if (/^#include/) { |
| $includes .= $_; |
| } elsif (/^%/) { |
| next; |
| } elsif (/^\s*$/) { |
| next; |
| } else { |
| chomp; |
| push @types, $_; |
| } |
| } |
| |
| $ntypes = @types + 1; |
| |
| print OUTPUT <<EOT; |
| #include <string.h> |
| #include <stdio.h> |
| |
| $includes |
| GtkType object_types[$ntypes]; |
| GstElement *elements[$ntypes]; |
| |
| gint _typenr = 0; |
| |
| gboolean |
| get_plugins () |
| { |
| gint i = 0; |
| EOT |
| |
| for (@types) { |
| print OUTPUT " gst_plugin_load(\"$_\");\n"; |
| print OUTPUT " elements[i] = gst_elementfactory_make(\"$_\", \"dummy\");\n"; |
| print OUTPUT " object_types[i] = GTK_OBJECT_TYPE(GTK_OBJECT(elements[i]));\n"; |
| print OUTPUT " i++; \n"; |
| } |
| print OUTPUT " object_types[i] = 0;\n"; |
| |
| print OUTPUT <<EOT; |
| return TRUE; |
| } |
| |
| /* |
| * This uses GTK type functions to output signal prototypes and the widget |
| * hierarchy. |
| */ |
| |
| /* The output files */ |
| gchar *signals_filename = "$MODULE.signals"; |
| gchar *hierarchy_filename = "$MODULE.hierarchy"; |
| gchar *args_filename = "$MODULE.args"; |
| gchar *pads_filename = "$MODULE.pads"; |
| |
| |
| static void output_signals (); |
| static void output_widget_signals (FILE *fp, |
| GtkType object_type); |
| static void output_widget_signal (FILE *fp, |
| GtkType object_type, |
| gchar *object_class_name, |
| guint signal_id); |
| static gchar * get_type_name (GtkType type, |
| gboolean * is_pointer); |
| static gchar * get_gdk_event (const gchar * signal_name); |
| static gchar ** lookup_signal_arg_names (gchar * type, |
| const gchar * signal_name); |
| |
| static void output_widget_hierarchy (); |
| static void output_hierarchy (FILE *fp, |
| GtkType type, |
| gint level); |
| |
| static void output_args (); |
| static void output_widget_args (FILE *fp, GtkType object_type); |
| |
| static void output_pads (); |
| static void output_widget_pads (FILE *fp, GstElement *element); |
| |
| int |
| main (int argc, char *argv[]) |
| { |
| EOT |
| |
| if ($NO_GTK_INIT) { |
| print OUTPUT <<EOT; |
| gtk_type_init (); |
| EOT |
| } else { |
| print OUTPUT <<EOT; |
| gtk_init (&argc, &argv); |
| EOT |
| } |
| |
| print OUTPUT <<EOT; |
| gst_init (&argc, &argv); |
| get_plugins(); |
| |
| output_widget_hierarchy (); |
| output_signals (); |
| output_args (); |
| output_pads (); |
| |
| return 0; |
| } |
| |
| |
| static void |
| output_signals () |
| { |
| FILE *fp; |
| gint i; |
| |
| fp = fopen (signals_filename, "w"); |
| if (fp == NULL) |
| { |
| g_warning ("Couldn't open output file: %s", signals_filename); |
| return; |
| } |
| |
| for (i = 0; object_types[i]; i++) |
| output_widget_signals (fp, object_types[i]); |
| |
| fclose (fp); |
| } |
| |
| |
| /* This outputs all the signals of one widget. */ |
| static void |
| output_widget_signals (FILE *fp, GtkType object_type) |
| { |
| GtkObjectClass *class; |
| gchar *object_class_name; |
| guint sig; |
| |
| class = gtk_type_class (object_type); |
| if (!class || class->nsignals == 0) |
| return; |
| |
| object_class_name = gtk_type_name (object_type); |
| |
| for (sig = 0; sig < class->nsignals; sig++) |
| { |
| if (!class->signals[sig]) |
| { |
| /*g_print ("Signal slot [%u] is empty\n", sig);*/ |
| continue; |
| } |
| |
| output_widget_signal (fp, object_type, object_class_name, |
| class->signals[sig]); |
| } |
| } |
| |
| |
| /* This outputs one signal. */ |
| static void |
| output_widget_signal (FILE *fp, |
| GtkType object_type, |
| gchar *object_name, |
| guint signal_id) |
| { |
| GtkSignalQuery *query_info; |
| gchar *ret_type, *pos, *type_name, *arg_name, *object_arg, *object_arg_start; |
| gboolean is_pointer; |
| gchar ret_type_buffer[1024], buffer[1024]; |
| gint i, param; |
| gchar **arg_names; |
| gint param_num, widget_num, event_num, callback_num; |
| gint *arg_num; |
| gchar signal_name[128]; |
| |
| |
| /* g_print ("Object: %s Type: %i Signal: %u\n", object_name, object_type, |
| signal_id);*/ |
| |
| param_num = 1; |
| widget_num = event_num = callback_num = 0; |
| |
| query_info = gtk_signal_query (signal_id); |
| if (query_info == NULL) |
| { |
| g_warning ("Couldn't query signal"); |
| return; |
| } |
| |
| /* Output the return type and function name. */ |
| ret_type = get_type_name (query_info->return_val, &is_pointer); |
| sprintf (ret_type_buffer, "%s%s", ret_type, is_pointer ? "*" : ""); |
| |
| /* Output the signal object type and the argument name. We assume the |
| type is a pointer - I think that is OK. We remove "Gtk" or "Gnome" and |
| convert to lower case for the argument name. */ |
| pos = buffer; |
| sprintf (pos, "%s ", object_name); |
| pos += strlen (pos); |
| |
| if (!strncmp (object_name, "Gtk", 3)) |
| object_arg = object_name + 3; |
| else if (!strncmp (object_name, "Gnome", 5)) |
| object_arg = object_name + 5; |
| else |
| object_arg = object_name; |
| |
| object_arg_start = pos; |
| sprintf (pos, "*%s\n", object_arg); |
| pos += strlen (pos); |
| g_strdown (object_arg_start); |
| if (!strcmp (object_arg_start, "widget")) |
| widget_num++; |
| |
| /* Convert signal name to use underscores rather than dashes '-'. */ |
| strcpy (signal_name, query_info->signal_name); |
| for (i = 0; signal_name[i]; i++) |
| { |
| if (signal_name[i] == '-') |
| signal_name[i] = '_'; |
| } |
| |
| /* Output the signal parameters. */ |
| arg_names = lookup_signal_arg_names (object_name, signal_name); |
| |
| for (param = 0; param < query_info->nparams; param++) |
| { |
| if (arg_names) |
| { |
| sprintf (pos, "%s\n", arg_names[param]); |
| pos += strlen (pos); |
| } |
| else |
| { |
| type_name = get_type_name (query_info->params[param], &is_pointer); |
| |
| /* Most arguments to the callback are called "arg1", "arg2", etc. |
| GdkWidgets are called "widget", "widget2", ... |
| GdkEvents are called "event", "event2", ... |
| GtkCallbacks are called "callback", "callback2", ... */ |
| if (!strcmp (type_name, "GtkWidget")) |
| { |
| arg_name = "widget"; |
| arg_num = &widget_num; |
| } |
| else if (!strcmp (type_name, "GdkEvent")) |
| { |
| type_name = get_gdk_event (signal_name); |
| arg_name = "event"; |
| arg_num = &event_num; |
| is_pointer = TRUE; |
| } |
| else if (!strcmp (type_name, "GtkCallback") |
| || !strcmp (type_name, "GtkCCallback")) |
| { |
| arg_name = "callback"; |
| arg_num = &callback_num; |
| } |
| else |
| { |
| arg_name = "arg"; |
| arg_num = ¶m_num; |
| } |
| sprintf (pos, "%s ", type_name); |
| pos += strlen (pos); |
| |
| if (!arg_num || *arg_num == 0) |
| sprintf (pos, "%s%s\n", is_pointer ? "*" : " ", arg_name); |
| else |
| sprintf (pos, "%s%s%i\n", is_pointer ? "*" : " ", arg_name, |
| *arg_num); |
| pos += strlen (pos); |
| |
| if (arg_num) |
| *arg_num += 1; |
| } |
| } |
| |
| fprintf (fp, |
| "<SIGNAL>\n<NAME>%s::%s</NAME>\n<RETURNS>%s</RETURNS>\n%s</SIGNAL>\n\n", |
| object_name, query_info->signal_name, ret_type_buffer, buffer); |
| g_free (query_info); |
| } |
| |
| |
| static gchar * |
| get_type_name (GtkType type, gboolean * is_pointer) |
| { |
| static gchar *GbTypeNames[] = |
| { |
| "char", "gchar", |
| "bool", "gboolean", |
| "int", "gint", |
| "uint", "guint", |
| "long", "glong", |
| "ulong", "gulong", |
| "float", "gfloat", |
| "double", "gdouble", |
| "string", "gchar", |
| "enum", "gint", |
| "flags", "gint", |
| "boxed", "gpointer", |
| "foreign", "gpointer", |
| "callback", "GtkCallback", /* ?? */ |
| "args", "gpointer", |
| |
| "pointer", "gpointer", |
| "signal", "gpointer", |
| "c_callback", "GtkCallback", /* ?? */ |
| |
| NULL |
| }; |
| |
| GtkType parent_type; |
| gchar *type_name, *parent_type_name; |
| gint i; |
| |
| *is_pointer = FALSE; |
| type_name = gtk_type_name (type); |
| for (i = 0; GbTypeNames[i]; i += 2) |
| { |
| if (!strcmp (type_name, GbTypeNames[i])) |
| { |
| if (!strcmp (type_name, "string")) |
| *is_pointer = TRUE; |
| return GbTypeNames[i + 1]; |
| } |
| } |
| |
| for (;;) |
| { |
| parent_type = gtk_type_parent (type); |
| if (parent_type == 0) |
| break; |
| type = parent_type; |
| } |
| parent_type_name = gtk_type_name (type); |
| /*g_print ("Parent type name: %s\n", parent_type_name);*/ |
| if (!strcmp (parent_type_name, "GtkObject") |
| || !strcmp (parent_type_name, "boxed") |
| || !strcmp (parent_type_name, "GtkBoxed")) |
| *is_pointer = TRUE; |
| |
| return type_name; |
| } |
| |
| |
| static gchar * |
| get_gdk_event (const gchar * signal_name) |
| { |
| static gchar *GbGDKEvents[] = |
| { |
| "button_press_event", "GdkEventButton", |
| "button_release_event", "GdkEventButton", |
| "motion_notify_event", "GdkEventMotion", |
| "delete_event", "GdkEvent", |
| "destroy_event", "GdkEvent", |
| "expose_event", "GdkEventExpose", |
| "key_press_event", "GdkEventKey", |
| "key_release_event", "GdkEventKey", |
| "enter_notify_event", "GdkEventCrossing", |
| "leave_notify_event", "GdkEventCrossing", |
| "configure_event", "GdkEventConfigure", |
| "focus_in_event", "GdkEventFocus", |
| "focus_out_event", "GdkEventFocus", |
| "map_event", "GdkEvent", |
| "unmap_event", "GdkEvent", |
| "property_notify_event", "GdkEventProperty", |
| "selection_clear_event", "GdkEventSelection", |
| "selection_request_event", "GdkEventSelection", |
| "selection_notify_event", "GdkEventSelection", |
| "proximity_in_event", "GdkEventProximity", |
| "proximity_out_event", "GdkEventProximity", |
| "drag_begin_event", "GdkEventDragBegin", |
| "drag_request_event", "GdkEventDragRequest", |
| "drag_end_event", "GdkEventDragRequest", |
| "drop_enter_event", "GdkEventDropEnter", |
| "drop_leave_event", "GdkEventDropLeave", |
| "drop_data_available_event", "GdkEventDropDataAvailable", |
| "other_event", "GdkEventOther", |
| "client_event", "GdkEventClient", |
| "no_expose_event", "GdkEventNoExpose", |
| NULL |
| }; |
| |
| gint i; |
| |
| for (i = 0; GbGDKEvents[i]; i += 2) |
| { |
| if (!strcmp (signal_name, GbGDKEvents[i])) |
| return GbGDKEvents[i + 1]; |
| } |
| return "GdkEvent"; |
| } |
| |
| |
| /* This returns argument names to use for some known GTK signals. |
| It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g. |
| 'select_row' and it returns a pointer to an array of argument types and |
| names. */ |
| static gchar ** |
| lookup_signal_arg_names (gchar * type, const gchar * signal_name) |
| { |
| /* Each arg array starts with the object type name and the signal name, |
| and then signal arguments follow. */ |
| static gchar *GbArgTable[][16] = |
| { |
| {"GtkCList", "select_row", |
| "gint row", |
| "gint column", |
| "GdkEventButton *event"}, |
| {"GtkCList", "unselect_row", |
| "gint row", |
| "gint column", |
| "GdkEventButton *event"}, |
| {"GtkCList", "click_column", |
| "gint column"}, |
| |
| {"GtkCList", "resize_column", |
| "gint column", |
| "gint width"}, |
| |
| {"GtkCList", "extend_selection", |
| "GtkScrollType scroll_type", |
| "gfloat position", |
| "gboolean auto_start_selection"}, |
| {"GtkCList", "scroll_vertical", |
| "GtkScrollType scroll_type", |
| "gfloat position"}, |
| {"GtkCList", "scroll_horizontal", |
| "GtkScrollType scroll_type", |
| "gfloat position"}, |
| {"GtkContainer", "focus", |
| "GtkDirectionType direction"}, |
| {"GtkCTree", "tree_select_row", |
| "GList *node", |
| "gint column"}, |
| {"GtkCTree", "tree_unselect_row", |
| "GList *node", |
| "gint column"}, |
| |
| {"GtkCTree", "tree_expand", |
| "GList *node"}, |
| {"GtkCTree", "tree_collapse", |
| "GList *node"}, |
| {"GtkCTree", "tree_move", |
| "GList *node", |
| "GList *new_parent", |
| "GList *new_sibling"}, |
| {"GtkCTree", "change_focus_row_expansion", |
| "GtkCTreeExpansionType expansion"}, |
| |
| {"GtkEditable", "insert_text", |
| "gchar *new_text", |
| "gint new_text_length", |
| "gint *position"}, |
| {"GtkEditable", "delete_text", |
| "gint start_pos", |
| "gint end_pos"}, |
| {"GtkEditable", "set_editable", |
| "gboolean is_editable"}, |
| {"GtkEditable", "move_cursor", |
| "gint x", |
| "gint y"}, |
| {"GtkEditable", "move_word", |
| "gint num_words"}, |
| {"GtkEditable", "move_page", |
| "gint x", |
| "gint y"}, |
| {"GtkEditable", "move_to_row", |
| "gint row"}, |
| {"GtkEditable", "move_to_column", |
| "gint column"}, |
| |
| {"GtkEditable", "kill_char", |
| "gint direction"}, |
| {"GtkEditable", "kill_word", |
| "gint direction"}, |
| {"GtkEditable", "kill_line", |
| "gint direction"}, |
| |
| |
| {"GtkInputDialog", "enable_device", |
| "gint deviceid"}, |
| {"GtkInputDialog", "disable_device", |
| "gint deviceid"}, |
| |
| {"GtkListItem", "extend_selection", |
| "GtkScrollType scroll_type", |
| "gfloat position", |
| "gboolean auto_start_selection"}, |
| {"GtkListItem", "scroll_vertical", |
| "GtkScrollType scroll_type", |
| "gfloat position"}, |
| {"GtkListItem", "scroll_horizontal", |
| "GtkScrollType scroll_type", |
| "gfloat position"}, |
| |
| {"GtkMenuShell", "move_current", |
| "GtkMenuDirectionType direction"}, |
| {"GtkMenuShell", "activate_current", |
| "gboolean force_hide"}, |
| |
| |
| {"GtkNotebook", "switch_page", |
| "GtkNotebookPage *page", |
| "gint page_num"}, |
| {"GtkStatusbar", "text_pushed", |
| "guint context_id", |
| "gchar *text"}, |
| {"GtkStatusbar", "text_popped", |
| "guint context_id", |
| "gchar *text"}, |
| {"GtkTipsQuery", "widget_entered", |
| "GtkWidget *widget", |
| "gchar *tip_text", |
| "gchar *tip_private"}, |
| {"GtkTipsQuery", "widget_selected", |
| "GtkWidget *widget", |
| "gchar *tip_text", |
| "gchar *tip_private", |
| "GdkEventButton *event"}, |
| {"GtkToolbar", "orientation_changed", |
| "GtkOrientation orientation"}, |
| {"GtkToolbar", "style_changed", |
| "GtkToolbarStyle style"}, |
| {"GtkWidget", "draw", |
| "GdkRectangle *area"}, |
| {"GtkWidget", "size_request", |
| "GtkRequisition *requisition"}, |
| {"GtkWidget", "size_allocate", |
| "GtkAllocation *allocation"}, |
| {"GtkWidget", "state_changed", |
| "GtkStateType state"}, |
| {"GtkWidget", "style_set", |
| "GtkStyle *previous_style"}, |
| |
| {"GtkWidget", "install_accelerator", |
| "gchar *signal_name", |
| "gchar key", |
| "gint modifiers"}, |
| |
| {"GtkWidget", "add_accelerator", |
| "guint accel_signal_id", |
| "GtkAccelGroup *accel_group", |
| "guint accel_key", |
| "GdkModifierType accel_mods", |
| "GtkAccelFlags accel_flags"}, |
| |
| {"GtkWidget", "parent_set", |
| "GtkObject *old_parent"}, |
| |
| {"GtkWidget", "remove_accelerator", |
| "GtkAccelGroup *accel_group", |
| "guint accel_key", |
| "GdkModifierType accel_mods"}, |
| {"GtkWidget", "debug_msg", |
| "gchar *message"}, |
| {"GtkWindow", "move_resize", |
| "gint *x", |
| "gint *y", |
| "gint width", |
| "gint height"}, |
| {"GtkWindow", "set_focus", |
| "GtkWidget *widget"}, |
| |
| {"GtkWidget", "selection_get", |
| "GtkSelectionData *data", |
| "guint info", |
| "guint time"}, |
| {"GtkWidget", "selection_received", |
| "GtkSelectionData *data", |
| "guint time"}, |
| |
| {"GtkWidget", "drag_begin", |
| "GdkDragContext *drag_context"}, |
| {"GtkWidget", "drag_end", |
| "GdkDragContext *drag_context"}, |
| {"GtkWidget", "drag_data_delete", |
| "GdkDragContext *drag_context"}, |
| {"GtkWidget", "drag_leave", |
| "GdkDragContext *drag_context", |
| "guint time"}, |
| {"GtkWidget", "drag_motion", |
| "GdkDragContext *drag_context", |
| "gint x", |
| "gint y", |
| "guint time"}, |
| {"GtkWidget", "drag_drop", |
| "GdkDragContext *drag_context", |
| "gint x", |
| "gint y", |
| "guint time"}, |
| {"GtkWidget", "drag_data_get", |
| "GdkDragContext *drag_context", |
| "GtkSelectionData *data", |
| "guint info", |
| "guint time"}, |
| {"GtkWidget", "drag_data_received", |
| "GdkDragContext *drag_context", |
| "gint x", |
| "gint y", |
| "GtkSelectionData *data", |
| "guint info", |
| "guint time"}, |
| |
| {NULL} |
| }; |
| |
| gint i; |
| |
| for (i = 0; GbArgTable[i][0]; i++) |
| { |
| if (!strcmp (type, GbArgTable[i][0]) |
| && !strcmp (signal_name, GbArgTable[i][1])) |
| return &GbArgTable[i][2]; |
| } |
| return NULL; |
| } |
| |
| |
| /* This outputs the hierarchy of all widgets which have been initialized, |
| i.e. by calling their XXX_get_type() initialization function. */ |
| static void |
| output_widget_hierarchy () |
| { |
| FILE *fp; |
| |
| fp = fopen (hierarchy_filename, "w"); |
| if (fp == NULL) |
| { |
| g_warning ("Couldn't open output file: %s", hierarchy_filename); |
| return; |
| } |
| output_hierarchy (fp, GTK_TYPE_OBJECT, 0); |
| fclose (fp); |
| } |
| |
| |
| /* This is called recursively to output the hierarchy of a widget. */ |
| static void |
| output_hierarchy (FILE *fp, |
| GtkType type, |
| gint level) |
| { |
| GList *list; |
| guint i; |
| |
| if (!type) |
| return; |
| |
| for (i = 0; i < level; i++) |
| fprintf (fp, " "); |
| fprintf (fp, gtk_type_name (type)); |
| fprintf (fp, "\n"); |
| |
| list = gtk_type_children_types (type); |
| |
| while (list) |
| { |
| GtkType child = (GtkType) list->data; |
| output_hierarchy (fp, child, level + 1); |
| list = list->next; |
| } |
| } |
| |
| |
| static void |
| output_args () |
| { |
| FILE *fp; |
| gint i; |
| |
| fp = fopen (args_filename, "w"); |
| if (fp == NULL) |
| { |
| g_warning ("Couldn't open output file: %s", args_filename); |
| return; |
| } |
| |
| for (i = 0; object_types[i]; i++) |
| output_widget_args (fp, object_types[i]); |
| |
| fclose (fp); |
| } |
| |
| |
| static void |
| output_widget_args (FILE *fp, GtkType object_type) |
| { |
| GtkObjectClass *class; |
| gchar *object_class_name; |
| GtkArg *args; |
| guint32 *arg_flags; |
| guint n_args; |
| gint arg; |
| gchar flags[16], *pos; |
| |
| class = gtk_type_class (object_type); |
| if (!class) |
| return; |
| |
| object_class_name = gtk_type_name (object_type); |
| |
| args = gtk_object_query_args (class->type, &arg_flags, &n_args); |
| |
| for (arg = 0; arg < n_args; arg++) |
| { |
| pos = flags; |
| /* We use one-character flags for simplicity. */ |
| if (arg_flags[arg] & GTK_ARG_READABLE) |
| *pos++ = 'r'; |
| if (arg_flags[arg] & GTK_ARG_WRITABLE) |
| *pos++ = 'w'; |
| if (arg_flags[arg] & GTK_ARG_CONSTRUCT) |
| *pos++ = 'x'; |
| if (arg_flags[arg] & GTK_ARG_CONSTRUCT_ONLY) |
| *pos++ = 'X'; |
| if (arg_flags[arg] & GTK_ARG_CHILD_ARG) |
| *pos++ = 'c'; |
| *pos = '\0'; |
| |
| fprintf (fp, "<ARG>\n<NAME>%s</NAME>\n<TYPE>%s</TYPE>\n<FLAGS>%s</FLAGS>\n", |
| args[arg].name, gtk_type_name (args[arg].type), flags); |
| |
| if (GTK_FUNDAMENTAL_TYPE(args[arg].type) == GTK_TYPE_ENUM) { |
| GtkEnumValue *values; |
| gint i=0; |
| |
| values = gtk_type_enum_get_values(args[arg].type); |
| |
| while (values[i].value_name) { |
| fprintf (fp, "<ENUM>\n<VALUE>%d</VALUE>\n<NICK>%s</NICK>\n</ENUM>\n", |
| values[i].value, values[i].value_nick); |
| i++; |
| } |
| } |
| |
| fprintf(fp, "</ARG>\n\n"); |
| } |
| |
| g_free (args); |
| g_free (arg_flags); |
| } |
| |
| |
| static void |
| output_pads () |
| { |
| FILE *fp; |
| gint i; |
| |
| fp = fopen (pads_filename, "w"); |
| if (fp == NULL) |
| { |
| g_warning ("Couldn't open output file: %s", pads_filename); |
| return; |
| } |
| |
| for (i = 0; elements[i]; i++) |
| output_widget_pads (fp, elements[i]); |
| |
| fclose (fp); |
| } |
| |
| static void |
| output_widget_pads (FILE *fp, GstElement *element) |
| { |
| GtkObjectClass *class; |
| GstElementFactory *factory; |
| GList *pads; |
| |
| class = GTK_OBJECT(element)->klass; |
| if (!class || !GST_IS_ELEMENT_CLASS(class)) |
| return; |
| |
| pads = gst_element_get_pad_list(element); |
| |
| factory = GST_ELEMENT_CLASS(class)->elementfactory; |
| |
| if (!factory) |
| return; |
| |
| while (pads) { |
| GstPad *pad = (GstPad *)pads->data; |
| GstType *type; |
| |
| //type = gst_type_find_by_id(pad->type); |
| type = gst_type_find_by_id(1); |
| |
| fprintf (fp, "<PAD>\n<NAME>%s::%s</NAME>\n", |
| gtk_type_name(factory->type), gst_object_get_name (GST_OBJECT (pad))); |
| |
| if (type) { |
| fprintf(fp, "<MIME>%s</MIME>\n", type->mime); |
| if (type->exts) |
| fprintf(fp, "<EXTS>%s</EXTS>\n", type->exts); |
| } |
| |
| fprintf(fp, "</PAD>\n\n"); |
| |
| pads = g_list_next(pads); |
| } |
| } |
| |
| EOT |
| |
| close OUTPUT; |
| |
| # Compile and run our file |
| |
| $CC = $ENV{CC} ? $ENV{CC} : "gcc"; |
| $LD = $ENV{LD} ? $ENV{LD} : $CC; |
| $CFLAGS = $ENV{CFLAGS} ? $ENV{CFLAGS} : ""; |
| $LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : ""; |
| |
| $command = "$CC $CFLAGS -c -o $MODULE-scan.o $MODULE-scan.c && $LD -o $MODULE-scan $MODULE-scan.o $LDFLAGS"; |
| |
| system($command) == 0 or die "Compilation of scanner failed\n"; |
| |
| system("./$MODULE-scan") == 0 or die "Scan failed\n"; |
| |
| unlink "./$MODULE-scan.c", "./$MODULE-scan", |