~ubuntu-branches/ubuntu/natty/gst-entrans/natty

« back to all changes in this revision

Viewing changes to common/gstdoc-scangobj

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2010-09-13 19:49:29 UTC
  • Revision ID: james.westby@ubuntu.com-20100913194929-qz90a14xyxln9yfz
Tags: upstream-0.10.2
ImportĀ upstreamĀ versionĀ 0.10.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/perl -w
 
2
# -*- cperl -*-
 
3
#
 
4
# gtk-doc - GTK DocBook documentation generator.
 
5
# Copyright (C) 1998  Damon Chaplin
 
6
#
 
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.
 
11
#
 
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.
 
16
#
 
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.
 
20
#
 
21
 
 
22
#
 
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.
 
26
#
 
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.
 
30
 
 
31
use Getopt::Long;
 
32
 
 
33
unshift @INC, '/usr/share/gtk-doc/data/';
 
34
require "gtkdoc-common.pl";
 
35
 
 
36
# Options
 
37
 
 
38
# name of documentation module
 
39
my $MODULE;
 
40
my $OUTPUT_DIR;
 
41
my $PRINT_VERSION;
 
42
my $PRINT_HELP;
 
43
my $TYPE_INIT_FUNC="g_type_init ()";
 
44
 
 
45
# --nogtkinit is deprecated, as it is the default now anyway.
 
46
%optctl = (module => \$MODULE,
 
47
           source => \$SOURCE,
 
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);
 
54
           
 
55
GetOptions(\%optctl, "module=s", "source=s", "types:s", "output-dir:s", "nogtkinit", "type-init-func:s", "version", "help");
 
56
 
 
57
if ($NO_GTK_INIT) {
 
58
  # Do nothing. This just avoids a warning.
 
59
}
 
60
 
 
61
if ($PRINT_VERSION) {
 
62
    print "1.5\n";
 
63
    exit 0;
 
64
}
 
65
 
 
66
if (!$MODULE) {
 
67
    $PRINT_HELP = 1;
 
68
}
 
69
 
 
70
if ($PRINT_HELP) {
 
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";
 
79
    exit 0;
 
80
}
 
81
 
 
82
$OUTPUT_DIR = $OUTPUT_DIR ? $OUTPUT_DIR : ".";
 
83
 
 
84
# THOMAS: dynamic types; only use types file for headers
 
85
 $TYPES_FILE = $TYPES_FILE ? $TYPES_FILE : "$OUTPUT_DIR/$MODULE.types";
 
86
 
 
87
open (TYPES, $TYPES_FILE) || die "Cannot open $TYPES_FILE: $!\n";
 
88
open (OUTPUT, ">$MODULE-scan.c") || die "Cannot open $MODULE-scan.c: $!\n";
 
89
 
 
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";
 
100
 
 
101
# write a C program to scan the types
 
102
 
 
103
$includes = "";
 
104
#@types = ();
 
105
 
 
106
for (<TYPES>) {
 
107
    if (/^#include/) {
 
108
        $includes .= $_;
 
109
#    } elsif (/^%/) {
 
110
#       next;
 
111
#    } elsif (/^\s*$/) {
 
112
#       next;
 
113
#    } else {
 
114
#       chomp;
 
115
#       push @types, $_;
 
116
    }
 
117
}
 
118
 
 
119
#$ntypes = @types + 1;
 
120
 
 
121
print OUTPUT <<EOT;
 
122
#include <string.h>
 
123
#include <stdlib.h>
 
124
#include <stdio.h>
 
125
#include <errno.h>
 
126
 
 
127
$includes
 
128
#ifdef GTK_IS_WIDGET_CLASS
 
129
#include <gtk/gtkversion.h>
 
130
#endif
 
131
GType *object_types = NULL;
 
132
 
 
133
static GType *
 
134
get_object_types (void)
 
135
{
 
136
    GList *plugins = NULL;
 
137
    GList *factories = NULL;
 
138
    GList *l;
 
139
    GstElementFactory *factory = NULL;
 
140
 
 
141
    gint i = 0;
 
142
 
 
143
    /* get a list of features from plugins in our source module */
 
144
    plugins = gst_registry_get_plugin_list (gst_registry_get_default());
 
145
 
 
146
    while (plugins) {
 
147
      GList *features;
 
148
      GstPlugin *plugin;
 
149
      const gchar *source;
 
150
 
 
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) {
 
156
        continue;
 
157
      }
 
158
 
 
159
      features =
 
160
          gst_registry_get_feature_list_by_plugin (gst_registry_get_default (),
 
161
          plugin->desc.name);
 
162
      while (features) {
 
163
        GstPluginFeature *feature;
 
164
        feature = GST_PLUGIN_FEATURE (features->data);
 
165
        feature = gst_plugin_feature_load (feature);
 
166
        if (!feature) {
 
167
          g_warning ("Could not load plugin feature %s",
 
168
                     gst_plugin_feature_get_name (feature));
 
169
        }
 
170
 
 
171
        if (GST_IS_ELEMENT_FACTORY (feature)) {
 
172
          factory = GST_ELEMENT_FACTORY (feature);
 
173
          factories = g_list_append (factories, factory);
 
174
        }
 
175
        features = g_list_next (features);
 
176
      }
 
177
    }
 
178
 
 
179
    g_message ("number of element factories: %d", g_list_length (factories));
 
180
 
 
181
    /* allocate the object_types array to hold them */
 
182
    object_types = g_new0 (GType, g_list_length (factories)+1);
 
183
 
 
184
    l = factories;
 
185
    i = 0;
 
186
 
 
187
    /* fill it */
 
188
    while (l) {
 
189
      GType type;
 
190
      factory = GST_ELEMENT_FACTORY (l->data);
 
191
      g_message ("adding type for factory %s", gst_element_factory_get_longname (factory));
 
192
      type = gst_element_factory_get_element_type (factory);
 
193
      g_message ("adding type %p", (void *) type);
 
194
      object_types[i] = type;
 
195
      i++;
 
196
      l = g_list_next (l);
 
197
    }
 
198
    object_types[i] = 0;
 
199
EOT
 
200
 
 
201
print OUTPUT <<EOT;
 
202
 
 
203
    /* Need to make sure all the types are loaded in and initialize
 
204
     * their signals and properties.
 
205
     */
 
206
    for (i=0; object_types[i]; i++) {
 
207
      if (G_TYPE_IS_CLASSED (object_types[i]))
 
208
        g_type_class_ref (object_types[i]);
 
209
    }
 
210
 
 
211
    return object_types;
 
212
}
 
213
 
 
214
/*
 
215
 * This uses GObject type functions to output signal prototypes and the object
 
216
 * hierarchy.
 
217
 */
 
218
 
 
219
/* The output files */
 
220
const gchar *signals_filename = "$new_signals_filename";
 
221
const gchar *hierarchy_filename = "$new_hierarchy_filename";
 
222
const gchar *interfaces_filename = "$new_interfaces_filename";
 
223
const gchar *prerequisites_filename = "$new_prerequisites_filename";
 
224
const gchar *args_filename = "$new_args_filename";
 
225
 
 
226
 
 
227
static void output_signals (void);
 
228
static void output_object_signals (FILE *fp,
 
229
                                   GType object_type);
 
230
static void output_object_signal (FILE *fp,
 
231
                                  const gchar *object_class_name,
 
232
                                  guint signal_id);
 
233
static const gchar * get_type_name (GType type,
 
234
                                    gboolean * is_pointer);
 
235
static const gchar * get_gdk_event (const gchar * signal_name);
 
236
static const gchar ** lookup_signal_arg_names (const gchar * type,
 
237
                                               const gchar * signal_name);
 
238
 
 
239
static void output_object_hierarchy (void);
 
240
static void output_hierarchy (FILE *fp,
 
241
                              GType type,
 
242
                              guint level);
 
243
 
 
244
static void output_object_interfaces (void);
 
245
static void output_interfaces (FILE *fp,
 
246
                               GType type);
 
247
 
 
248
static void output_interface_prerequisites (void);
 
249
static void output_prerequisites (FILE *fp,
 
250
                                  GType type);
 
251
 
 
252
static void output_args (void);
 
253
static void output_object_args (FILE *fp, GType object_type);
 
254
 
 
255
int
 
256
main (int argc, char *argv[])
 
257
{
 
258
  /* Silence the compiler: */
 
259
  if (argv != argv) argc = argc;
 
260
 
 
261
  $TYPE_INIT_FUNC;
 
262
 
 
263
  get_object_types ();
 
264
 
 
265
  output_signals ();
 
266
  output_object_hierarchy ();
 
267
  output_object_interfaces ();
 
268
  output_interface_prerequisites ();
 
269
  output_args ();
 
270
 
 
271
  return 0;
 
272
}
 
273
 
 
274
 
 
275
static void
 
276
output_signals (void)
 
277
{
 
278
  FILE *fp;
 
279
  gint i;
 
280
 
 
281
  fp = fopen (signals_filename, "w");
 
282
  if (fp == NULL)
 
283
    {
 
284
      g_warning ("Couldn't open output file: %s : %s", signals_filename, strerror(errno));
 
285
      return;
 
286
    }
 
287
 
 
288
  for (i = 0; object_types[i]; i++)
 
289
    output_object_signals (fp, object_types[i]);
 
290
 
 
291
  fclose (fp);
 
292
}
 
293
 
 
294
static gint
 
295
compare_signals (const void *a, const void *b)
 
296
{
 
297
  const guint *signal_a = a;
 
298
  const guint *signal_b = b;
 
299
 
 
300
  return strcmp (g_signal_name (*signal_a), g_signal_name (*signal_b));
 
301
}
 
302
 
 
303
/* This outputs all the signals of one object. */
 
304
static void
 
305
output_object_signals (FILE *fp, GType object_type)
 
306
{
 
307
  const gchar *object_class_name;
 
308
  guint *signals, n_signals;
 
309
  guint sig;
 
310
 
 
311
  if (G_TYPE_IS_INSTANTIATABLE (object_type) ||
 
312
      G_TYPE_IS_INTERFACE (object_type))
 
313
    {
 
314
 
 
315
      object_class_name = g_type_name (object_type);
 
316
 
 
317
      signals = g_signal_list_ids (object_type, &n_signals);
 
318
      qsort (signals, n_signals, sizeof (guint), compare_signals);
 
319
 
 
320
      for (sig = 0; sig < n_signals; sig++)
 
321
        {
 
322
           output_object_signal (fp, object_class_name, signals[sig]);
 
323
        }
 
324
      g_free (signals);
 
325
   }
 
326
}
 
327
 
 
328
 
 
329
/* This outputs one signal. */
 
330
static void
 
331
output_object_signal (FILE *fp,
 
332
                      const gchar *object_name,
 
333
                      guint signal_id)
 
334
{
 
335
  GSignalQuery query_info;
 
336
  const gchar *type_name, *ret_type, *object_arg, *arg_name;
 
337
  gchar *pos, *object_arg_lower;
 
338
  gboolean is_pointer;
 
339
  gchar ret_type_buffer[1024], buffer[1024];
 
340
  guint i, param;
 
341
  const gchar **arg_names;
 
342
  gint param_num, widget_num, event_num, callback_num;
 
343
  gint *arg_num;
 
344
  gchar signal_name[128];
 
345
  gchar flags[16];
 
346
 
 
347
  /*  g_print ("Object: %s Signal: %u\\n", object_name, signal_id);*/
 
348
 
 
349
  param_num = 1;
 
350
  widget_num = event_num = callback_num = 0;
 
351
 
 
352
  g_signal_query (signal_id, &query_info);
 
353
 
 
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 ? "*" : "");
 
357
 
 
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. */
 
361
  pos = buffer;
 
362
  sprintf (pos, "%s ", object_name);
 
363
  pos += strlen (pos);
 
364
 
 
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;
 
369
  else
 
370
      object_arg = object_name;
 
371
 
 
372
  object_arg_lower = g_ascii_strdown (object_arg, -1);
 
373
  sprintf (pos, "*%s\\n", object_arg_lower);
 
374
  pos += strlen (pos);
 
375
  if (!strncmp (object_arg_lower, "widget", 6))
 
376
    widget_num = 2;
 
377
  g_free(object_arg_lower);
 
378
 
 
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++)
 
382
    {
 
383
      if (signal_name[i] == '-')
 
384
        signal_name[i] = '_';
 
385
    }
 
386
 
 
387
  /* Output the signal parameters. */
 
388
  arg_names = lookup_signal_arg_names (object_name, signal_name);
 
389
 
 
390
  for (param = 0; param < query_info.n_params; param++)
 
391
    {
 
392
      if (arg_names)
 
393
        {
 
394
          sprintf (pos, "%s\\n", arg_names[param]);
 
395
          pos += strlen (pos);
 
396
        }
 
397
      else
 
398
        {
 
399
          type_name = get_type_name (query_info.param_types[param] & ~G_SIGNAL_TYPE_STATIC_SCOPE, &is_pointer);
 
400
 
 
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"))
 
406
            {
 
407
              arg_name = "widget";
 
408
              arg_num = &widget_num;
 
409
            }
 
410
          else if (!strcmp (type_name, "GdkEvent"))
 
411
            {
 
412
              type_name = get_gdk_event (signal_name);
 
413
              arg_name = "event";
 
414
              arg_num = &event_num;
 
415
              is_pointer = TRUE;
 
416
            }
 
417
          else if (!strcmp (type_name, "GtkCallback")
 
418
                   || !strcmp (type_name, "GtkCCallback"))
 
419
            {
 
420
              arg_name = "callback";
 
421
              arg_num = &callback_num;
 
422
            }
 
423
          else
 
424
            {
 
425
              arg_name = "arg";
 
426
              arg_num = &param_num;
 
427
            }
 
428
          sprintf (pos, "%s ", type_name);
 
429
          pos += strlen (pos);
 
430
 
 
431
          if (!arg_num || *arg_num == 0)
 
432
            sprintf (pos, "%s%s\\n", is_pointer ? "*" : " ", arg_name);
 
433
          else
 
434
            sprintf (pos, "%s%s%i\\n", is_pointer ? "*" : " ", arg_name,
 
435
                     *arg_num);
 
436
          pos += strlen (pos);
 
437
 
 
438
          if (arg_num)
 
439
            {
 
440
              if (*arg_num == 0)
 
441
                *arg_num = 2;
 
442
              else
 
443
                *arg_num += 1;
 
444
            }
 
445
        }
 
446
    }
 
447
 
 
448
  pos = flags;
 
449
  /* We use one-character flags for simplicity. */
 
450
  if (query_info.signal_flags & G_SIGNAL_RUN_FIRST)
 
451
    *pos++ = 'f';
 
452
  if (query_info.signal_flags & G_SIGNAL_RUN_LAST)
 
453
    *pos++ = 'l';
 
454
  if (query_info.signal_flags & G_SIGNAL_RUN_CLEANUP)
 
455
    *pos++ = 'c';
 
456
  if (query_info.signal_flags & G_SIGNAL_NO_RECURSE)
 
457
    *pos++ = 'r';
 
458
  if (query_info.signal_flags & G_SIGNAL_DETAILED)
 
459
    *pos++ = 'd';
 
460
  if (query_info.signal_flags & G_SIGNAL_ACTION)
 
461
    *pos++ = 'a';
 
462
  if (query_info.signal_flags & G_SIGNAL_NO_HOOKS)
 
463
    *pos++ = 'h';
 
464
  *pos = 0;
 
465
 
 
466
  fprintf (fp,
 
467
           "<SIGNAL>\\n<NAME>%s::%s</NAME>\\n<RETURNS>%s</RETURNS>\\n<FLAGS>%s</FLAGS>\\n%s</SIGNAL>\\n\\n",
 
468
           object_name, query_info.signal_name, ret_type_buffer, flags, buffer);
 
469
}
 
470
 
 
471
 
 
472
/* Returns the type name to use for a signal argument or return value, given
 
473
   the GtkType from the signal info. It also sets is_pointer to TRUE if the
 
474
   argument needs a '*' since it is a pointer. */
 
475
static const gchar *
 
476
get_type_name (GType type, gboolean * is_pointer)
 
477
{
 
478
  const gchar *type_name;
 
479
 
 
480
  *is_pointer = FALSE;
 
481
  type_name = g_type_name (type);
 
482
 
 
483
  switch (type) {
 
484
  case G_TYPE_NONE:
 
485
  case G_TYPE_CHAR:
 
486
  case G_TYPE_UCHAR:
 
487
  case G_TYPE_BOOLEAN:
 
488
  case G_TYPE_INT:
 
489
  case G_TYPE_UINT:
 
490
  case G_TYPE_LONG:
 
491
  case G_TYPE_ULONG:
 
492
  case G_TYPE_FLOAT:
 
493
  case G_TYPE_DOUBLE:
 
494
  case G_TYPE_POINTER:
 
495
    /* These all have normal C type names so they are OK. */
 
496
    return type_name;
 
497
 
 
498
  case G_TYPE_STRING:
 
499
    /* A GtkString is really a gchar*. */
 
500
    *is_pointer = TRUE;
 
501
    return "gchar";
 
502
 
 
503
  case G_TYPE_ENUM:
 
504
  case G_TYPE_FLAGS:
 
505
    /* We use a gint for both of these. Hopefully a subtype with a decent
 
506
       name will be registered and used instead, as GTK+ does itself. */
 
507
    return "gint";
 
508
 
 
509
  case G_TYPE_BOXED:
 
510
    /* The boxed type shouldn't be used itself, only subtypes. Though we
 
511
       return 'gpointer' just in case. */
 
512
    return "gpointer";
 
513
 
 
514
  case G_TYPE_PARAM:
 
515
    /* A GParam is really a GParamSpec*. */
 
516
    *is_pointer = TRUE;
 
517
    return "GParamSpec";
 
518
 
 
519
  default:
 
520
    break;
 
521
  }
 
522
 
 
523
  /* For all GObject subclasses we can use the class name with a "*",
 
524
     e.g. 'GtkWidget *'. */
 
525
  if (g_type_is_a (type, G_TYPE_OBJECT))
 
526
    *is_pointer = TRUE;
 
527
 
 
528
  if (G_TYPE_IS_CLASSED (type))
 
529
    *is_pointer = TRUE;
 
530
 
 
531
  /* All boxed subtypes will be pointers as well. */
 
532
  if (g_type_is_a (type, G_TYPE_BOXED))
 
533
    *is_pointer = TRUE;
 
534
 
 
535
  /* All pointer subtypes will be pointers as well. */
 
536
  if (g_type_is_a (type, G_TYPE_POINTER))
 
537
    *is_pointer = TRUE;
 
538
 
 
539
  return type_name;
 
540
}
 
541
 
 
542
 
 
543
static const gchar *
 
544
get_gdk_event (const gchar * signal_name)
 
545
{
 
546
  static const gchar *GbGDKEvents[] =
 
547
  {
 
548
    "button_press_event", "GdkEventButton",
 
549
    "button_release_event", "GdkEventButton",
 
550
    "motion_notify_event", "GdkEventMotion",
 
551
    "delete_event", "GdkEvent",
 
552
    "destroy_event", "GdkEvent",
 
553
    "expose_event", "GdkEventExpose",
 
554
    "key_press_event", "GdkEventKey",
 
555
    "key_release_event", "GdkEventKey",
 
556
    "enter_notify_event", "GdkEventCrossing",
 
557
    "leave_notify_event", "GdkEventCrossing",
 
558
    "configure_event", "GdkEventConfigure",
 
559
    "focus_in_event", "GdkEventFocus",
 
560
    "focus_out_event", "GdkEventFocus",
 
561
    "map_event", "GdkEvent",
 
562
    "unmap_event", "GdkEvent",
 
563
    "property_notify_event", "GdkEventProperty",
 
564
    "selection_clear_event", "GdkEventSelection",
 
565
    "selection_request_event", "GdkEventSelection",
 
566
    "selection_notify_event", "GdkEventSelection",
 
567
    "proximity_in_event", "GdkEventProximity",
 
568
    "proximity_out_event", "GdkEventProximity",
 
569
    "drag_begin_event", "GdkEventDragBegin",
 
570
    "drag_request_event", "GdkEventDragRequest",
 
571
    "drag_end_event", "GdkEventDragRequest",
 
572
    "drop_enter_event", "GdkEventDropEnter",
 
573
    "drop_leave_event", "GdkEventDropLeave",
 
574
    "drop_data_available_event", "GdkEventDropDataAvailable",
 
575
    "other_event", "GdkEventOther",
 
576
    "client_event", "GdkEventClient",
 
577
    "no_expose_event", "GdkEventNoExpose",
 
578
    "visibility_notify_event", "GdkEventVisibility",
 
579
    "window_state_event", "GdkEventWindowState",
 
580
    "scroll_event", "GdkEventScroll",
 
581
    NULL
 
582
  };
 
583
 
 
584
  gint i;
 
585
 
 
586
  for (i = 0; GbGDKEvents[i]; i += 2)
 
587
    {
 
588
      if (!strcmp (signal_name, GbGDKEvents[i]))
 
589
        return GbGDKEvents[i + 1];
 
590
    }
 
591
  return "GdkEvent";
 
592
}
 
593
 
 
594
 
 
595
/* This returns argument names to use for some known GTK signals.
 
596
    It is passed a widget name, e.g. 'GtkCList' and a signal name, e.g.
 
597
    'select_row' and it returns a pointer to an array of argument types and
 
598
    names. */
 
599
static const gchar **
 
600
lookup_signal_arg_names (const gchar * type, const gchar * signal_name)
 
601
{
 
602
  /* Each arg array starts with the object type name and the signal name,
 
603
     and then signal arguments follow. */
 
604
  static const gchar *GbArgTable[][16] =
 
605
  {
 
606
    {"GtkCList", "select_row",
 
607
     "gint             row",
 
608
     "gint             column",
 
609
     "GdkEventButton  *event"},
 
610
    {"GtkCList", "unselect_row",
 
611
     "gint             row",
 
612
     "gint             column",
 
613
     "GdkEventButton  *event"},
 
614
    {"GtkCList", "click_column",
 
615
     "gint             column"},
 
616
 
 
617
    {"GtkCList", "resize_column",
 
618
     "gint             column",
 
619
     "gint             width"},
 
620
 
 
621
    {"GtkCList", "extend_selection",
 
622
     "GtkScrollType    scroll_type",
 
623
     "gfloat           position",
 
624
     "gboolean         auto_start_selection"},
 
625
    {"GtkCList", "scroll_vertical",
 
626
     "GtkScrollType    scroll_type",
 
627
     "gfloat           position"},
 
628
    {"GtkCList", "scroll_horizontal",
 
629
     "GtkScrollType    scroll_type",
 
630
     "gfloat           position"},
 
631
 
 
632
    {"GtkCTree", "tree_select_row",
 
633
     "GtkCTreeNode    *node",
 
634
     "gint             column"},
 
635
    {"GtkCTree", "tree_unselect_row",
 
636
     "GtkCTreeNode    *node",
 
637
     "gint             column"},
 
638
    {"GtkCTree", "tree_expand",
 
639
     "GtkCTreeNode    *node"},
 
640
    {"GtkCTree", "tree_collapse",
 
641
     "GtkCTreeNode    *node"},
 
642
    {"GtkCTree", "tree_move",
 
643
     "GtkCTreeNode    *node",
 
644
     "GtkCTreeNode    *new_parent",
 
645
     "GtkCTreeNode    *new_sibling"},
 
646
    {"GtkCTree", "change_focus_row_expansion",
 
647
     "GtkCTreeExpansionType expansion"},
 
648
 
 
649
    {"GtkEditable", "insert_text",
 
650
     "gchar           *new_text",
 
651
     "gint             new_text_length",
 
652
     "gint            *position"},
 
653
    {"GtkEditable", "delete_text",
 
654
     "gint             start_pos",
 
655
     "gint             end_pos"},
 
656
    {"GtkEditable", "set_editable",
 
657
     "gboolean         is_editable"},
 
658
    {"GtkEditable", "move_cursor",
 
659
     "gint             x",
 
660
     "gint             y"},
 
661
    {"GtkEditable", "move_word",
 
662
     "gint             num_words"},
 
663
    {"GtkEditable", "move_page",
 
664
     "gint             x",
 
665
     "gint             y"},
 
666
    {"GtkEditable", "move_to_row",
 
667
     "gint             row"},
 
668
    {"GtkEditable", "move_to_column",
 
669
     "gint             column"},
 
670
 
 
671
    {"GtkEditable", "kill_char",
 
672
     "gint             direction"},
 
673
    {"GtkEditable", "kill_word",
 
674
     "gint             direction"},
 
675
    {"GtkEditable", "kill_line",
 
676
     "gint             direction"},
 
677
 
 
678
 
 
679
    {"GtkInputDialog", "enable_device",
 
680
     "GdkDevice       *deviceid"},
 
681
    {"GtkInputDialog", "disable_device",
 
682
     "GdkDevice       *deviceid"},
 
683
 
 
684
    {"GtkListItem", "extend_selection",
 
685
     "GtkScrollType    scroll_type",
 
686
     "gfloat           position",
 
687
     "gboolean         auto_start_selection"},
 
688
    {"GtkListItem", "scroll_vertical",
 
689
     "GtkScrollType    scroll_type",
 
690
     "gfloat           position"},
 
691
    {"GtkListItem", "scroll_horizontal",
 
692
     "GtkScrollType    scroll_type",
 
693
     "gfloat           position"},
 
694
 
 
695
    {"GtkMenuShell", "move_current",
 
696
     "GtkMenuDirectionType direction"},
 
697
    {"GtkMenuShell", "activate_current",
 
698
     "gboolean         force_hide"},
 
699
 
 
700
 
 
701
    {"GtkNotebook", "switch_page",
 
702
     "GtkNotebookPage *page",
 
703
     "guint            page_num"},
 
704
    {"GtkStatusbar", "text_pushed",
 
705
     "guint            context_id",
 
706
     "gchar           *text"},
 
707
    {"GtkStatusbar", "text_popped",
 
708
     "guint            context_id",
 
709
     "gchar           *text"},
 
710
    {"GtkTipsQuery", "widget_entered",
 
711
     "GtkWidget       *widget",
 
712
     "gchar           *tip_text",
 
713
     "gchar           *tip_private"},
 
714
    {"GtkTipsQuery", "widget_selected",
 
715
     "GtkWidget       *widget",
 
716
     "gchar           *tip_text",
 
717
     "gchar           *tip_private",
 
718
     "GdkEventButton  *event"},
 
719
    {"GtkToolbar", "orientation_changed",
 
720
     "GtkOrientation   orientation"},
 
721
    {"GtkToolbar", "style_changed",
 
722
     "GtkToolbarStyle  style"},
 
723
    {"GtkWidget", "draw",
 
724
     "GdkRectangle    *area"},
 
725
    {"GtkWidget", "size_request",
 
726
     "GtkRequisition  *requisition"},
 
727
    {"GtkWidget", "size_allocate",
 
728
     "GtkAllocation   *allocation"},
 
729
    {"GtkWidget", "state_changed",
 
730
     "GtkStateType     state"},
 
731
    {"GtkWidget", "style_set",
 
732
     "GtkStyle        *previous_style"},
 
733
 
 
734
    {"GtkWidget", "install_accelerator",
 
735
     "gchar           *signal_name",
 
736
     "gchar            key",
 
737
     "gint             modifiers"},
 
738
 
 
739
    {"GtkWidget", "add_accelerator",
 
740
     "guint            accel_signal_id",
 
741
     "GtkAccelGroup   *accel_group",
 
742
     "guint            accel_key",
 
743
     "GdkModifierType  accel_mods",
 
744
     "GtkAccelFlags    accel_flags"},
 
745
 
 
746
    {"GtkWidget", "parent_set",
 
747
     "GtkObject       *old_parent"},
 
748
 
 
749
    {"GtkWidget", "remove_accelerator",
 
750
     "GtkAccelGroup   *accel_group",
 
751
     "guint            accel_key",
 
752
     "GdkModifierType  accel_mods"},
 
753
    {"GtkWidget", "debug_msg",
 
754
     "gchar           *message"},
 
755
    {"GtkWindow", "move_resize",
 
756
     "gint            *x",
 
757
     "gint            *y",
 
758
     "gint             width",
 
759
     "gint             height"},
 
760
    {"GtkWindow", "set_focus",
 
761
     "GtkWidget       *widget"},
 
762
 
 
763
    {"GtkWidget", "selection_get",
 
764
     "GtkSelectionData *data",
 
765
     "guint            info",
 
766
     "guint            time"},
 
767
    {"GtkWidget", "selection_received",
 
768
     "GtkSelectionData *data",
 
769
     "guint            time"},
 
770
 
 
771
    {"GtkWidget", "drag_begin",
 
772
     "GdkDragContext  *drag_context"},
 
773
    {"GtkWidget", "drag_end",
 
774
     "GdkDragContext  *drag_context"},
 
775
    {"GtkWidget", "drag_data_delete",
 
776
     "GdkDragContext  *drag_context"},
 
777
    {"GtkWidget", "drag_leave",
 
778
     "GdkDragContext  *drag_context",
 
779
     "guint            time"},
 
780
    {"GtkWidget", "drag_motion",
 
781
     "GdkDragContext  *drag_context",
 
782
     "gint             x",
 
783
     "gint             y",
 
784
     "guint            time"},
 
785
    {"GtkWidget", "drag_drop",
 
786
     "GdkDragContext  *drag_context",
 
787
     "gint             x",
 
788
     "gint             y",
 
789
     "guint            time"},
 
790
    {"GtkWidget", "drag_data_get",
 
791
     "GdkDragContext  *drag_context",
 
792
     "GtkSelectionData *data",
 
793
     "guint            info",
 
794
     "guint            time"},
 
795
    {"GtkWidget", "drag_data_received",
 
796
     "GdkDragContext  *drag_context",
 
797
     "gint             x",
 
798
     "gint             y",
 
799
     "GtkSelectionData *data",
 
800
     "guint            info",
 
801
     "guint            time"},
 
802
 
 
803
    {NULL}
 
804
  };
 
805
 
 
806
  gint i;
 
807
 
 
808
  for (i = 0; GbArgTable[i][0]; i++)
 
809
    {
 
810
#if 1
 
811
      if (!strcmp (type, GbArgTable[i][0])
 
812
          && !strcmp (signal_name, GbArgTable[i][1]))
 
813
        return &GbArgTable[i][2];
 
814
#endif
 
815
    }
 
816
  return NULL;
 
817
}
 
818
 
 
819
/* This outputs the hierarchy of all objects which have been initialized,
 
820
   i.e. by calling their XXX_get_type() initialization function. */
 
821
static void
 
822
output_object_hierarchy (void)
 
823
{
 
824
  FILE *fp;
 
825
  gint i;
 
826
 
 
827
  fp = fopen (hierarchy_filename, "w");
 
828
  if (fp == NULL)
 
829
    {
 
830
      g_warning ("Couldn't open output file: %s : %s", hierarchy_filename, strerror(errno));
 
831
      return;
 
832
    }
 
833
  output_hierarchy (fp, G_TYPE_OBJECT, 0);
 
834
  output_hierarchy (fp, G_TYPE_INTERFACE, 0);
 
835
  
 
836
  for (i=0; object_types[i]; i++) {
 
837
    if (!g_type_parent (object_types[i]) &&
 
838
      (object_types[i] != G_TYPE_OBJECT) &&
 
839
      (object_types[i] != G_TYPE_INTERFACE)
 
840
    ) {
 
841
      output_hierarchy (fp, object_types[i], 0);
 
842
    }
 
843
  }
 
844
 
 
845
  fclose (fp);
 
846
}
 
847
 
 
848
/* This is called recursively to output the hierarchy of a widget. */
 
849
static void
 
850
output_hierarchy (FILE  *fp,
 
851
                  GType  type,
 
852
                  guint   level)
 
853
{
 
854
  guint i;
 
855
  GType *children;
 
856
  guint n_children;
 
857
 
 
858
  if (!type)
 
859
    return;
 
860
 
 
861
  for (i = 0; i < level; i++)
 
862
    fprintf (fp, "  ");
 
863
  fprintf (fp, g_type_name (type));
 
864
  fprintf (fp, "\\n");
 
865
 
 
866
  children = g_type_children (type, &n_children);
 
867
 
 
868
  for (i=0; i < n_children; i++)
 
869
    output_hierarchy (fp, children[i], level + 1);
 
870
 
 
871
  g_free (children);
 
872
}
 
873
 
 
874
static void output_object_interfaces (void)
 
875
{
 
876
  FILE *fp;
 
877
 
 
878
  fp = fopen (interfaces_filename, "w");
 
879
  if (fp == NULL)
 
880
    {
 
881
      g_warning ("Couldn't open output file: %s : %s", interfaces_filename, strerror(errno));
 
882
      return;
 
883
    }
 
884
  output_interfaces (fp, G_TYPE_OBJECT);
 
885
  fclose (fp);
 
886
}
 
887
 
 
888
static void
 
889
output_interfaces (FILE  *fp,
 
890
                   GType  type)
 
891
{
 
892
  guint i;
 
893
  GType *children, *interfaces;
 
894
  guint n_children, n_interfaces;
 
895
 
 
896
  if (!type)
 
897
    return;
 
898
 
 
899
  interfaces = g_type_interfaces (type, &n_interfaces);
 
900
 
 
901
  if (n_interfaces > 0)
 
902
    {
 
903
      fprintf (fp, g_type_name (type));
 
904
      for (i=0; i < n_interfaces; i++)
 
905
          fprintf (fp, " %s", g_type_name (interfaces[i]));
 
906
      fprintf (fp, "\\n");
 
907
     }
 
908
  g_free (interfaces);
 
909
 
 
910
  children = g_type_children (type, &n_children);
 
911
 
 
912
  for (i=0; i < n_children; i++)
 
913
    output_interfaces (fp, children[i]);
 
914
 
 
915
  g_free (children);
 
916
}
 
917
 
 
918
static void output_interface_prerequisites (void)
 
919
{
 
920
  FILE *fp;
 
921
 
 
922
  fp = fopen (prerequisites_filename, "w");
 
923
  if (fp == NULL)
 
924
    {
 
925
      g_warning ("Couldn't open output file: %s : %s", prerequisites_filename, strerror(errno));
 
926
      return;
 
927
    }
 
928
  output_prerequisites (fp, G_TYPE_INTERFACE);
 
929
  fclose (fp);
 
930
}
 
931
 
 
932
static void
 
933
output_prerequisites (FILE  *fp,
 
934
                      GType  type)
 
935
{
 
936
#if GLIB_CHECK_VERSION(2,1,0)
 
937
  guint i;
 
938
  GType *children, *prerequisites;
 
939
  guint n_children, n_prerequisites;
 
940
 
 
941
  if (!type)
 
942
    return;
 
943
 
 
944
  prerequisites = g_type_interface_prerequisites (type, &n_prerequisites);
 
945
 
 
946
  if (n_prerequisites > 0)
 
947
    {
 
948
      fprintf (fp, g_type_name (type));
 
949
      for (i=0; i < n_prerequisites; i++)
 
950
          fprintf (fp, " %s", g_type_name (prerequisites[i]));
 
951
      fprintf (fp, "\\n");
 
952
     }
 
953
  g_free (prerequisites);
 
954
 
 
955
  children = g_type_children (type, &n_children);
 
956
 
 
957
  for (i=0; i < n_children; i++)
 
958
    output_prerequisites (fp, children[i]);
 
959
 
 
960
  g_free (children);
 
961
#endif
 
962
}
 
963
 
 
964
static void
 
965
output_args (void)
 
966
{
 
967
  FILE *fp;
 
968
  gint i;
 
969
 
 
970
  fp = fopen (args_filename, "w");
 
971
  if (fp == NULL)
 
972
    {
 
973
      g_warning ("Couldn't open output file: %s : %s", args_filename, strerror(errno));
 
974
      return;
 
975
    }
 
976
 
 
977
  for (i = 0; object_types[i]; i++) {
 
978
    output_object_args (fp, object_types[i]);
 
979
  }
 
980
 
 
981
  fclose (fp);
 
982
}
 
983
 
 
984
static gint
 
985
compare_param_specs (const void *a, const void *b)
 
986
{
 
987
  GParamSpec *spec_a = *(GParamSpec **)a;
 
988
  GParamSpec *spec_b = *(GParamSpec **)b;
 
989
 
 
990
  return strcmp (g_param_spec_get_name (spec_a), g_param_spec_get_name (spec_b));
 
991
}
 
992
 
 
993
/* Its common to have unsigned properties restricted
 
994
 * to the signed range. Therefore we make this look
 
995
 * a bit nicer by spelling out the max constants.
 
996
 */
 
997
 
 
998
/* Don't use "==" with floats, it might trigger a gcc warning.  */
 
999
#define GTKDOC_COMPARE_FLOAT(x, y) (x <= y && x >= y)
 
1000
 
 
1001
static gchar*
 
1002
describe_double_constant (gdouble value)
 
1003
{
 
1004
  gchar *desc;
 
1005
 
 
1006
  if (GTKDOC_COMPARE_FLOAT (value, G_MAXDOUBLE))
 
1007
    desc = g_strdup ("G_MAXDOUBLE");
 
1008
  else if (GTKDOC_COMPARE_FLOAT (value, G_MINDOUBLE))
 
1009
    desc = g_strdup ("G_MINDOUBLE");
 
1010
  else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXDOUBLE))
 
1011
    desc = g_strdup ("-G_MAXDOUBLE");
 
1012
  else if (GTKDOC_COMPARE_FLOAT (value, G_MAXFLOAT))
 
1013
    desc = g_strdup ("G_MAXFLOAT");
 
1014
  else if (GTKDOC_COMPARE_FLOAT (value, G_MINFLOAT))
 
1015
    desc = g_strdup ("G_MINFLOAT");
 
1016
  else if (GTKDOC_COMPARE_FLOAT (value, -G_MAXFLOAT))
 
1017
    desc = g_strdup ("-G_MAXFLOAT");
 
1018
  else
 
1019
    desc = g_strdup_printf ("%lg", value);
 
1020
 
 
1021
  return desc;
 
1022
}
 
1023
 
 
1024
static gchar*
 
1025
describe_signed_constant (gint64 value)
 
1026
{
 
1027
  gchar *desc;
 
1028
 
 
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
 
1046
    desc = g_strdup_printf ("%" G_GINT64_FORMAT, value);
 
1047
 
 
1048
  return desc;
 
1049
}
 
1050
 
 
1051
static gchar*
 
1052
describe_unsigned_constant (guint64 value)
 
1053
{
 
1054
  gchar *desc;
 
1055
 
 
1056
  if (value == G_MAXINT)
 
1057
    desc = g_strdup ("G_MAXINT");
 
1058
  else if (value == G_MININT)
 
1059
    desc = g_strdup ("G_MININT");
 
1060
  else if (value == G_MAXUINT)
 
1061
    desc = g_strdup ("G_MAXUINT");
 
1062
  else if (value == G_MAXLONG)
 
1063
    desc = g_strdup ("G_MAXLONG");
 
1064
  else if (value == G_MINLONG)
 
1065
    desc = g_strdup ("G_MINLONG");
 
1066
  else if (value == G_MAXULONG)
 
1067
    desc = g_strdup ("G_MAXULONG");
 
1068
  else if (value == G_MAXINT64)
 
1069
    desc = g_strdup ("G_MAXINT64");
 
1070
  else if (value == G_MININT64)
 
1071
    desc = g_strdup ("G_MININT64");
 
1072
  else if (value == G_MAXUINT64)
 
1073
    desc = g_strdup ("G_MAXUINT64");
 
1074
  else
 
1075
    desc = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
 
1076
 
 
1077
  return desc;
 
1078
}
 
1079
 
 
1080
static gchar*
 
1081
describe_type (GParamSpec *spec)
 
1082
{
 
1083
  gchar *desc;
 
1084
  gchar *lower;
 
1085
  gchar *upper;
 
1086
 
 
1087
  if (G_IS_PARAM_SPEC_CHAR (spec))
 
1088
    {
 
1089
      GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
 
1090
 
 
1091
      lower = describe_signed_constant (pspec->minimum);
 
1092
      upper = describe_signed_constant (pspec->maximum);
 
1093
      if (pspec->minimum == G_MININT8 && pspec->maximum == G_MAXINT8)
 
1094
        desc = g_strdup ("");
 
1095
      else if (pspec->minimum == G_MININT8)
 
1096
        desc = g_strdup_printf ("<= %s", upper);
 
1097
      else if (pspec->maximum == G_MAXINT8)
 
1098
        desc = g_strdup_printf (">= %s", lower);
 
1099
      else
 
1100
        desc = g_strdup_printf ("[%s,%s]", lower, upper);
 
1101
      g_free (lower);
 
1102
      g_free (upper);
 
1103
    }
 
1104
  else if (G_IS_PARAM_SPEC_UCHAR (spec))
 
1105
    {
 
1106
      GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
 
1107
 
 
1108
      lower = describe_unsigned_constant (pspec->minimum);
 
1109
      upper = describe_unsigned_constant (pspec->maximum);
 
1110
      if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT8)
 
1111
        desc = g_strdup ("");
 
1112
      else if (pspec->minimum == 0)
 
1113
        desc = g_strdup_printf ("<= %s", upper);
 
1114
      else if (pspec->maximum == G_MAXUINT8)
 
1115
        desc = g_strdup_printf (">= %s", lower);
 
1116
      else
 
1117
        desc = g_strdup_printf ("[%s,%s]", lower, upper);
 
1118
      g_free (lower);
 
1119
      g_free (upper);
 
1120
    }
 
1121
  else if (G_IS_PARAM_SPEC_INT (spec))
 
1122
    {
 
1123
      GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
 
1124
 
 
1125
      lower = describe_signed_constant (pspec->minimum);
 
1126
      upper = describe_signed_constant (pspec->maximum);
 
1127
      if (pspec->minimum == G_MININT && pspec->maximum == G_MAXINT)
 
1128
        desc = g_strdup ("");
 
1129
      else if (pspec->minimum == G_MININT)
 
1130
        desc = g_strdup_printf ("<= %s", upper);
 
1131
      else if (pspec->maximum == G_MAXINT)
 
1132
        desc = g_strdup_printf (">= %s", lower);
 
1133
      else
 
1134
        desc = g_strdup_printf ("[%s,%s]", lower, upper);
 
1135
      g_free (lower);
 
1136
      g_free (upper);
 
1137
    }
 
1138
  else if (G_IS_PARAM_SPEC_UINT (spec))
 
1139
    {
 
1140
      GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
 
1141
 
 
1142
      lower = describe_unsigned_constant (pspec->minimum);
 
1143
      upper = describe_unsigned_constant (pspec->maximum);
 
1144
      if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT)
 
1145
        desc = g_strdup ("");
 
1146
      else if (pspec->minimum == 0)
 
1147
        desc = g_strdup_printf ("<= %s", upper);
 
1148
      else if (pspec->maximum == G_MAXUINT)
 
1149
        desc = g_strdup_printf (">= %s", lower);
 
1150
      else
 
1151
        desc = g_strdup_printf ("[%s,%s]", lower, upper);
 
1152
      g_free (lower);
 
1153
      g_free (upper);
 
1154
    }
 
1155
  else if (G_IS_PARAM_SPEC_LONG (spec))
 
1156
    {
 
1157
      GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
 
1158
 
 
1159
      lower = describe_signed_constant (pspec->minimum);
 
1160
      upper = describe_signed_constant (pspec->maximum);
 
1161
      if (pspec->minimum == G_MINLONG && pspec->maximum == G_MAXLONG)
 
1162
        desc = g_strdup ("");
 
1163
      else if (pspec->minimum == G_MINLONG)
 
1164
        desc = g_strdup_printf ("<= %s", upper);
 
1165
      else if (pspec->maximum == G_MAXLONG)
 
1166
        desc = g_strdup_printf (">= %s", lower);
 
1167
      else
 
1168
        desc = g_strdup_printf ("[%s,%s]", lower, upper);
 
1169
      g_free (lower);
 
1170
      g_free (upper);
 
1171
    }
 
1172
  else if (G_IS_PARAM_SPEC_ULONG (spec))
 
1173
    {
 
1174
      GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
 
1175
      gchar *upper;
 
1176
 
 
1177
      lower = describe_unsigned_constant (pspec->minimum);
 
1178
      upper = describe_unsigned_constant (pspec->maximum);
 
1179
      if (pspec->minimum == 0 && pspec->maximum == G_MAXULONG)
 
1180
        desc = g_strdup ("");
 
1181
      else if (pspec->minimum == 0)
 
1182
        desc = g_strdup_printf ("<= %s", upper);
 
1183
      else if (pspec->maximum == G_MAXULONG)
 
1184
        desc = g_strdup_printf (">= %s", lower);
 
1185
      else
 
1186
        desc = g_strdup_printf ("[%s,%s]", lower, upper);
 
1187
      g_free (lower);
 
1188
      g_free (upper);
 
1189
    }
 
1190
  else if (G_IS_PARAM_SPEC_INT64 (spec))
 
1191
    {
 
1192
      GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
 
1193
 
 
1194
      lower = describe_signed_constant (pspec->minimum);
 
1195
      upper = describe_signed_constant (pspec->maximum);
 
1196
      if (pspec->minimum == G_MININT64 && pspec->maximum == G_MAXINT64)
 
1197
        desc = g_strdup ("");
 
1198
      else if (pspec->minimum == G_MININT64)
 
1199
        desc = g_strdup_printf ("<= %s", upper);
 
1200
      else if (pspec->maximum == G_MAXINT64)
 
1201
        desc = g_strdup_printf (">= %s", lower);
 
1202
      else
 
1203
        desc = g_strdup_printf ("[%s,%s]", lower, upper);
 
1204
      g_free (lower);
 
1205
      g_free (upper);
 
1206
    }
 
1207
  else if (G_IS_PARAM_SPEC_UINT64 (spec))
 
1208
    {
 
1209
      GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
 
1210
 
 
1211
      lower = describe_unsigned_constant (pspec->minimum);
 
1212
      upper = describe_unsigned_constant (pspec->maximum);
 
1213
      if (pspec->minimum == 0 && pspec->maximum == G_MAXUINT64)
 
1214
        desc = g_strdup ("");
 
1215
      else if (pspec->minimum == 0)
 
1216
        desc = g_strdup_printf ("<= %s", upper);
 
1217
      else if (pspec->maximum == G_MAXUINT64)
 
1218
        desc = g_strdup_printf (">= %s", lower);
 
1219
      else
 
1220
        desc = g_strdup_printf ("[%s,%s]", lower, upper);
 
1221
      g_free (lower);
 
1222
      g_free (upper);
 
1223
    }
 
1224
  else if (G_IS_PARAM_SPEC_FLOAT (spec))
 
1225
    {
 
1226
      GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
 
1227
 
 
1228
      lower = describe_double_constant (pspec->minimum);
 
1229
      upper = describe_double_constant (pspec->maximum);
 
1230
      if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXFLOAT))
 
1231
        {
 
1232
          if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
 
1233
            desc = g_strdup ("");
 
1234
          else
 
1235
            desc = g_strdup_printf ("<= %s", upper);
 
1236
        }
 
1237
      else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXFLOAT))
 
1238
        desc = g_strdup_printf (">= %s", lower);
 
1239
      else
 
1240
        desc = g_strdup_printf ("[%s,%s]", lower, upper);
 
1241
      g_free (lower);
 
1242
      g_free (upper);
 
1243
    }
 
1244
  else if (G_IS_PARAM_SPEC_DOUBLE (spec))
 
1245
    {
 
1246
      GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
 
1247
 
 
1248
      lower = describe_double_constant (pspec->minimum);
 
1249
      upper = describe_double_constant (pspec->maximum);
 
1250
      if (GTKDOC_COMPARE_FLOAT (pspec->minimum, -G_MAXDOUBLE))
 
1251
        {
 
1252
          if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
 
1253
            desc = g_strdup ("");
 
1254
          else
 
1255
            desc = g_strdup_printf ("<= %s", upper);
 
1256
        }
 
1257
      else if (GTKDOC_COMPARE_FLOAT (pspec->maximum, G_MAXDOUBLE))
 
1258
        desc = g_strdup_printf (">= %s", lower);
 
1259
      else
 
1260
        desc = g_strdup_printf ("[%s,%s]", lower, upper);
 
1261
      g_free (lower);
 
1262
      g_free (upper);
 
1263
    }
 
1264
  else
 
1265
    {
 
1266
      desc = g_strdup ("");
 
1267
    }
 
1268
 
 
1269
  return desc;
 
1270
}
 
1271
 
 
1272
static gchar*
 
1273
describe_default (GParamSpec *spec)
 
1274
{
 
1275
  gchar *desc;
 
1276
 
 
1277
  if (G_IS_PARAM_SPEC_CHAR (spec))
 
1278
    {
 
1279
      GParamSpecChar *pspec = G_PARAM_SPEC_CHAR (spec);
 
1280
 
 
1281
      desc = g_strdup_printf ("%d", pspec->default_value);
 
1282
    }
 
1283
  else if (G_IS_PARAM_SPEC_UCHAR (spec))
 
1284
    {
 
1285
      GParamSpecUChar *pspec = G_PARAM_SPEC_UCHAR (spec);
 
1286
 
 
1287
      desc = g_strdup_printf ("%u", pspec->default_value);
 
1288
    }
 
1289
  else if (G_IS_PARAM_SPEC_BOOLEAN (spec))
 
1290
    {
 
1291
      GParamSpecBoolean *pspec = G_PARAM_SPEC_BOOLEAN (spec);
 
1292
 
 
1293
      desc = g_strdup_printf ("%s", pspec->default_value ? "TRUE" : "FALSE");
 
1294
    }
 
1295
  else if (G_IS_PARAM_SPEC_INT (spec))
 
1296
    {
 
1297
      GParamSpecInt *pspec = G_PARAM_SPEC_INT (spec);
 
1298
 
 
1299
      desc = g_strdup_printf ("%d", pspec->default_value);
 
1300
    }
 
1301
  else if (G_IS_PARAM_SPEC_UINT (spec))
 
1302
    {
 
1303
      GParamSpecUInt *pspec = G_PARAM_SPEC_UINT (spec);
 
1304
 
 
1305
      desc = g_strdup_printf ("%u", pspec->default_value);
 
1306
    }
 
1307
  else if (G_IS_PARAM_SPEC_LONG (spec))
 
1308
    {
 
1309
      GParamSpecLong *pspec = G_PARAM_SPEC_LONG (spec);
 
1310
 
 
1311
      desc = g_strdup_printf ("%ld", pspec->default_value);
 
1312
    }
 
1313
  else if (G_IS_PARAM_SPEC_LONG (spec))
 
1314
    {
 
1315
      GParamSpecULong *pspec = G_PARAM_SPEC_ULONG (spec);
 
1316
 
 
1317
      desc = g_strdup_printf ("%lu", pspec->default_value);
 
1318
    }
 
1319
  else if (G_IS_PARAM_SPEC_INT64 (spec))
 
1320
    {
 
1321
      GParamSpecInt64 *pspec = G_PARAM_SPEC_INT64 (spec);
 
1322
 
 
1323
      desc = g_strdup_printf ("%" G_GINT64_FORMAT, pspec->default_value);
 
1324
    }
 
1325
  else if (G_IS_PARAM_SPEC_UINT64 (spec))
 
1326
    {
 
1327
      GParamSpecUInt64 *pspec = G_PARAM_SPEC_UINT64 (spec);
 
1328
 
 
1329
      desc = g_strdup_printf ("%" G_GUINT64_FORMAT, pspec->default_value);
 
1330
    }
 
1331
  else if (G_IS_PARAM_SPEC_UNICHAR (spec))
 
1332
    {
 
1333
      GParamSpecUnichar *pspec = G_PARAM_SPEC_UNICHAR (spec);
 
1334
 
 
1335
      if (g_unichar_isprint (pspec->default_value))
 
1336
        desc = g_strdup_printf ("'%c'", pspec->default_value);
 
1337
      else
 
1338
        desc = g_strdup_printf ("%u", pspec->default_value);
 
1339
    }
 
1340
  else if (G_IS_PARAM_SPEC_ENUM (spec))
 
1341
    {
 
1342
      GParamSpecEnum *pspec = G_PARAM_SPEC_ENUM (spec);
 
1343
 
 
1344
      GEnumValue *value = g_enum_get_value (pspec->enum_class, pspec->default_value);
 
1345
      if (value)
 
1346
        desc = g_strdup_printf ("%s", value->value_name);
 
1347
      else
 
1348
        desc = g_strdup_printf ("%d", pspec->default_value);
 
1349
    }
 
1350
  else if (G_IS_PARAM_SPEC_FLAGS (spec))
 
1351
    {
 
1352
      GParamSpecFlags *pspec = G_PARAM_SPEC_FLAGS (spec);
 
1353
      guint default_value;
 
1354
      GString *acc;
 
1355
 
 
1356
      default_value = pspec->default_value;
 
1357
      acc = g_string_new ("");
 
1358
 
 
1359
      while (default_value)
 
1360
        {
 
1361
          GFlagsValue *value = g_flags_get_first_value (pspec->flags_class, default_value);
 
1362
 
 
1363
          if (!value)
 
1364
            break;
 
1365
 
 
1366
          if (acc->len > 0)
 
1367
            g_string_append (acc, "|");
 
1368
          g_string_append (acc, value->value_name);
 
1369
 
 
1370
          default_value &= ~value->value;
 
1371
        }
 
1372
 
 
1373
      if (default_value == 0)
 
1374
        desc = g_string_free (acc, FALSE);
 
1375
      else
 
1376
        {
 
1377
          desc = g_strdup_printf ("%d", pspec->default_value);
 
1378
          g_string_free (acc, TRUE);
 
1379
        }
 
1380
    }
 
1381
  else if (G_IS_PARAM_SPEC_FLOAT (spec))
 
1382
    {
 
1383
      GParamSpecFloat *pspec = G_PARAM_SPEC_FLOAT (spec);
 
1384
 
 
1385
      desc = g_strdup_printf ("%g", pspec->default_value);
 
1386
    }
 
1387
  else if (G_IS_PARAM_SPEC_DOUBLE (spec))
 
1388
    {
 
1389
      GParamSpecDouble *pspec = G_PARAM_SPEC_DOUBLE (spec);
 
1390
 
 
1391
      desc = g_strdup_printf ("%lg", pspec->default_value);
 
1392
    }
 
1393
  else if (G_IS_PARAM_SPEC_STRING (spec))
 
1394
    {
 
1395
      GParamSpecString *pspec = G_PARAM_SPEC_STRING (spec);
 
1396
 
 
1397
      if (pspec->default_value)
 
1398
        {
 
1399
          gchar *esc = g_strescape (pspec->default_value, NULL);
 
1400
 
 
1401
          desc = g_strdup_printf ("\\"%s\\"", esc);
 
1402
 
 
1403
          g_free (esc);
 
1404
        }
 
1405
      else
 
1406
        desc = g_strdup_printf ("NULL");
 
1407
    }
 
1408
  else
 
1409
    {
 
1410
      desc = g_strdup ("");
 
1411
    }
 
1412
 
 
1413
  return desc;
 
1414
}
 
1415
 
 
1416
 
 
1417
static void
 
1418
output_object_args (FILE *fp, GType object_type)
 
1419
{
 
1420
  gpointer class;
 
1421
  const gchar *object_class_name;
 
1422
  guint arg;
 
1423
  gchar flags[16], *pos;
 
1424
  GParamSpec **properties;
 
1425
  guint n_properties;
 
1426
  gboolean child_prop;
 
1427
  gboolean style_prop;
 
1428
  gchar *type_desc;
 
1429
  gchar *default_value;
 
1430
 
 
1431
  if (G_TYPE_IS_CLASSED (object_type))
 
1432
    {
 
1433
      class = g_type_class_peek (object_type);
 
1434
      if (!class)
 
1435
        return;
 
1436
 
 
1437
      properties = g_object_class_list_properties (class, &n_properties);
 
1438
    }
 
1439
#if GLIB_MAJOR_VERSION > 2 || (GLIB_MAJOR_VERSION == 2 && GLIB_MINOR_VERSION >= 3)
 
1440
  else if (G_TYPE_IS_INTERFACE (object_type))
 
1441
    {
 
1442
      class = g_type_default_interface_ref (object_type);
 
1443
 
 
1444
      if (!class)
 
1445
        return;
 
1446
 
 
1447
      properties = g_object_interface_list_properties (class, &n_properties);
 
1448
    }
 
1449
#endif
 
1450
  else
 
1451
    return;
 
1452
 
 
1453
  object_class_name = g_type_name (object_type);
 
1454
 
 
1455
  child_prop = FALSE;
 
1456
  style_prop = FALSE;
 
1457
 
 
1458
  while (TRUE) {
 
1459
    qsort (properties, n_properties, sizeof (GParamSpec *), compare_param_specs);
 
1460
    for (arg = 0; arg < n_properties; arg++)
 
1461
      {
 
1462
        GParamSpec *spec = properties[arg];
 
1463
        const gchar *nick, *blurb, *dot;
 
1464
 
 
1465
        if (spec->owner_type != object_type)
 
1466
          continue;
 
1467
 
 
1468
        pos = flags;
 
1469
        /* We use one-character flags for simplicity. */
 
1470
        if (child_prop && !style_prop)
 
1471
          *pos++ = 'c';
 
1472
        if (style_prop)
 
1473
          *pos++ = 's';
 
1474
        if (spec->flags & G_PARAM_READABLE)
 
1475
          *pos++ = 'r';
 
1476
        if (spec->flags & G_PARAM_WRITABLE)
 
1477
          *pos++ = 'w';
 
1478
        if (spec->flags & G_PARAM_CONSTRUCT)
 
1479
          *pos++ = 'x';
 
1480
        if (spec->flags & G_PARAM_CONSTRUCT_ONLY)
 
1481
          *pos++ = 'X';
 
1482
        *pos = 0;
 
1483
 
 
1484
        nick = g_param_spec_get_nick (spec);
 
1485
        blurb = g_param_spec_get_blurb (spec);
 
1486
 
 
1487
        dot = "";
 
1488
        if (blurb) {
 
1489
          int str_len = strlen (blurb);
 
1490
          if (str_len > 0  && blurb[str_len - 1] != '.')
 
1491
            dot = ".";
 
1492
        }
 
1493
 
 
1494
        type_desc = describe_type (spec);
 
1495
        default_value = describe_default (spec);
 
1496
        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",
 
1497
                 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);
 
1498
        g_free (type_desc);
 
1499
        g_free (default_value);
 
1500
      }
 
1501
 
 
1502
    g_free (properties);
 
1503
 
 
1504
#ifdef GTK_IS_CONTAINER_CLASS
 
1505
    if (!child_prop && GTK_IS_CONTAINER_CLASS (class)) {
 
1506
      properties = gtk_container_class_list_child_properties (class, &n_properties);
 
1507
      child_prop = TRUE;
 
1508
      continue;
 
1509
    }
 
1510
#endif
 
1511
 
 
1512
#ifdef GTK_IS_WIDGET_CLASS
 
1513
#if GTK_CHECK_VERSION(2,1,0)
 
1514
    if (!style_prop && GTK_IS_WIDGET_CLASS (class)) {
 
1515
      properties = gtk_widget_class_list_style_properties (GTK_WIDGET_CLASS (class), &n_properties);
 
1516
      style_prop = TRUE;
 
1517
      continue;
 
1518
    }
 
1519
#endif
 
1520
#endif
 
1521
 
 
1522
    break;
 
1523
  }
 
1524
}
 
1525
EOT
 
1526
 
 
1527
close OUTPUT;
 
1528
 
 
1529
# Compile and run our file
 
1530
 
 
1531
$CC = $ENV{CC} ? $ENV{CC} : "gcc";
 
1532
$LD = $ENV{LD} ? $ENV{LD} : $CC;
 
1533
$CFLAGS = $ENV{CFLAGS} ? "$ENV{CFLAGS} -Wall -g" : "-Wall -g";
 
1534
$LDFLAGS = $ENV{LDFLAGS} ? $ENV{LDFLAGS} : "";
 
1535
 
 
1536
my $o_file;
 
1537
if ($CC =~ /libtool/) {
 
1538
  $o_file  = "$MODULE-scan.lo"
 
1539
} else {
 
1540
  $o_file = "$MODULE-scan.o"
 
1541
}
 
1542
 
 
1543
print "gtk-doc: Compiling scanner\n";
 
1544
$command = "$CC $CFLAGS -c -o $o_file $MODULE-scan.c";
 
1545
system($command) == 0 or die "Compilation of scanner failed: $!\n";
 
1546
 
 
1547
print "gtk-doc: Linking scanner\n";
 
1548
$command = "$LD -o $MODULE-scan $o_file $LDFLAGS";
 
1549
system($command) == 0 or die "Linking of scanner failed: $!\n";
 
1550
 
 
1551
print "gtk-doc: Running scanner $MODULE-scan\n";
 
1552
system("sh -c ./$MODULE-scan") == 0 or die "Scan failed: $!\n";
 
1553
 
 
1554
unlink "./$MODULE-scan.c", "./$MODULE-scan.o", "./$MODULE-scan.lo", "./$MODULE-scan";
 
1555
 
 
1556
#&UpdateFileIfChanged ($old_signals_filename, $new_signals_filename, 0);
 
1557
#&UpdateFileIfChanged ($old_hierarchy_filename, $new_hierarchy_filename, 0);
 
1558
#&UpdateFileIfChanged ($old_interfaces_filename, $new_interfaces_filename, 0);
 
1559
#&UpdateFileIfChanged ($old_prerequisites_filename, $new_prerequisites_filename, 0);
 
1560
#&UpdateFileIfChanged ($old_args_filename, $new_args_filename, 0);
 
1561
 
 
1562