File: hc-objectargs.html

package info (click to toggle)
ebook-dev-ggad 199908-2
  • links: PTS
  • area: main
  • in suites: woody
  • size: 2,264 kB
  • ctags: 1,163
  • sloc: sh: 44; makefile: 35
file content (777 lines) | stat: -rw-r--r-- 29,469 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
  <head>
    <title>
      Object Arguments
    </title>
    <meta name="GENERATOR" content=
    "Modular DocBook HTML Stylesheet Version 1.45">
    <link rel="HOME" title="GTK+ / Gnome Application Development"
    href="ggad.html">
    <link rel="UP" title="The GTK+ Object and Type System" href= 
    "cha-objects.html">
    <link rel="PREVIOUS" title="GtkArg and the Type System" href= 
    "sec-gtkarg.html">
    <link rel="NEXT" title="Signals" href="z109.html">
  </head>
  <body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink= 
  "#840084" alink="#0000FF">
    <div class="NAVHEADER">
      <table width="100%" border="0" bgcolor="#ffffff" cellpadding= 
      "1" cellspacing="0">
        <tr>
          <th colspan="4" align="center">
            <font color="#000000" size="2">GTK+ / Gnome Application
            Development</font>
          </th>
        </tr>
        <tr>
          <td width="25%" bgcolor="#ffffff" align="left">
            <a href="sec-gtkarg.html"><font color="#0000ff" size=
            "2"><b>&lt;&lt;&lt; Previous</b></font></a>
          </td>
          <td width="25%" colspan="2" bgcolor="#ffffff" align= 
          "center">
            <font color="#0000ff" size="2"><b><a href="ggad.html">
            <font color="#0000ff" size="2"><b>
            Home</b></font></a></b></font>
          </td>
          <td width="25%" bgcolor="#ffffff" align="right">
            <a href="z109.html"><font color="#0000ff" size="2"><b>
            Next &gt;&gt;&gt;</b></font></a>
          </td>
        </tr>
      </table>
    </div>
    <div class="SECT1">
      <h1 class="SECT1">
        <a name="HC-OBJECTARGS">Object Arguments</a>
      </h1>
      <p>
        <i class="FIRSTTERM">Arguments</i> are one of the most
        interesting features of <span class="STRUCTNAME">
        GtkObject</span>. Arguments are a mechanism for handling
        what CORBA's Interface Definition Language (IDL) calls an
        <i class="FIRSTTERM">attribute</i>: a value with a "getter"
        and a "setter." In concrete terms, object arguments pair a
        key (which is a string) with a value (represented as a
        <span class="STRUCTNAME">GtkArg</span>). Each <span class= 
        "STRUCTNAME">GtkObject</span> subclass can register
        permissible keys and the <span class="STRUCTNAME">
        GtkType</span>s of their associated values.
      </p>
      <p>
        Using object arguments, one can discover at runtime what
        attributes an object has, and then get or set their values.
        This is very useful for people implementing GUI builders,
        since some of the widget configuration dialogs can be
        automated. Similarly, it makes it much easier to write GTK+
        bindings for scripting languages. It can also be convenient
        for programmers, since they can avoid writing all the
        get/set functions---the <tt class="CLASSNAME">
        GnomeCanvas</tt>, for example, uses object arguments for
        almost all of its API. Finally, object arguments may be
        configurable via the <tt class="FILENAME">gtkrc</tt>
        configuration mechanism in a future version of GTK+, making
        it possible for users to extensively customize GTK+
        software.
      </p>
      <div class="SECT2">
        <h2 class="SECT2">
          <a name="Z106">Setting Object Arguments</a>
        </h2>
        <p>
          Most commonly, arguments are used as an API to set
          attributes of widgets. However, not all of the GTK+ API
          has been exported via arguments, so it is not always
          possible.
        </p>
        <p>
          To set widget attributes, the most convenient interface
          is <tt class="FUNCTION">gtk_object_set()</tt>. Here's an
          example:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;   gtk_object_set(GTK_OBJECT(vbox), 
                  "GtkContainer::border_width", (gulong) 10,
                  NULL);&#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          The above code is identical in effect to:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;   gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);&#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          It's up to you which to use; it depends on the context.
          Typically, you would use the argument mechanism if you
          have a reason to, i.e. if you are using its dynamic,
          runtime-oriented features. However, if you are setting
          several attributes, it may be easier to type and read.
        </p>
        <p>
          <tt class="FUNCTION">gtk_object_set()</tt> takes a <span
          class="STRUCTNAME">GtkObject</span> as the first
          argument, followed by any number of key-value pairs. If a
          key is not defined for the object you pass in, a runtime
          error will be triggered. The list of key-value pairs must
          be terminated with a <span class="STRUCTNAME">NULL</span>
          key. When a <span class="STRUCTNAME">GtkObject</span>
          registers itself with GTK+, it tells GTK+ what type of
          value to expect after each key. For the aggregate
          fundamental types <tt class="FUNCTION">
          gtk_object_set()</tt> will expect more than one C
          function argument after the key. For example, first a
          signal function and then a user data pointer will be
          expected after <span class="STRUCTNAME">
          GTK_TYPE_SIGNAL</span> arguments. (<a href= 
          "sec-gtkarg.html#TABLE-FUNDTYPES">Table 1 in the section
          called <i><span class="STRUCTNAME">GtkArg</span> and the
          Type System</i></a> gives the types of the expected
          arguments.)
        </p>
        <p>
          It is permissible to leave off the object class portion
          of an argument name---<span class=
          "STRUCTNAME">"GtkContainer::border_width"</span> can be
          simply <span class="STRUCTNAME">"border_width"</span>:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;   gtk_object_set(GTK_OBJECT(vbox), 
                  "border_width", (gulong) 10,
                  NULL);&#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          If you do not specify the class name as part of the
          argument name, GTK+ will start with the real type of the
          object and look up the argument name in the argument
          table for each superclass until it finds the right one
          (<tt class="CLASSNAME">GtkContainer</tt> in this case).
          If you do specify the class name, GTK+ will only look for
          the argument in the specified class's argument table.
        </p>
        <p>
          Since <tt class="FUNCTION">gtk_object_set()</tt> uses C
          variable argument lists, it has limited type safety. This
          can be a real problem in your code. You may have noticed
          the cast to <span class="STRUCTNAME">gulong</span> in the
          sample call to <tt class="FUNCTION">
          gtk_object_set()</tt>. The argument <span class= 
          "STRUCTNAME">GtkContainer::border_width</span> has type
          <span class="STRUCTNAME">GTK_TYPE_ULONG</span>. GTK+ will
          extract <span class="STRUCTNAME">sizeof(gulong)</span>
          bytes from the argument list when it encounters this
          argument. If you leave out the cast, C will probably pass
          only <span class="STRUCTNAME">sizeof(gint)</span> bytes
          to the function. As you might imagine, this causes memory
          corruption on many platforms. A similar problem arises
          with arguments of type <span class="STRUCTNAME">
          GTK_TYPE_DOUBLE</span>; if you type <span class= 
          "STRUCTNAME">5</span> instead of <span class=
          "STRUCTNAME">5.0</span>, C will pass an integer to <tt
          class="FUNCTION">gtk_object_set()</tt>. These bugs are
          very hard to find, once you introduce them.
        </p>
        <p>
          <tt class="FUNCTION">gtk_object_set()</tt> is syntactic
          sugar for a more fundamental function call, <tt class= 
          "FUNCTION">gtk_object_setv()</tt>. <tt class="FUNCTION">
          gtk_object_setv()</tt> takes a vector of <span class= 
          "STRUCTNAME">GtkArg</span> (<tt class=
          "FUNCTION">gtk_object_set()</tt> converts each key-value
          pair in its argument list to <span class="STRUCTNAME">
          GtkArg</span> internally).
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;   GtkArg args[1];
   args[0].name = "GtkContainer::border_width";
   args[0].type = GTK_TYPE_ULONG;
   GTK_VALUE_ULONG(args[0]) = 10;
   gtk_object_setv(GTK_OBJECT(button), 
                   1,
                   args);&#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          The second argument to <tt class="FUNCTION">
          gtk_object_setv()</tt> is the length of the array of
          <span class="STRUCTNAME">GtkArg</span>. <tt class= 
          "FUNCTION">gtk_object_set()</tt> is plainly easier to use
          when you are typing the code in manually, but <tt class= 
          "FUNCTION">gtk_object_setv()</tt> can be passed a
          dynamically-constructed argument array---which is
          convenient if you're exporting GTK+ functionality to an
          interpreted environment.
        </p>
        <p>
          It is also possible to set object arguments when objects
          are created. You can create most objects using the <tt
          class="FUNCTION">gtk_object_new()</tt> function, and most
          widgets with the <tt class="FUNCTION">
          gtk_widget_new()</tt> function. The routines take a <span
          class="STRUCTNAME">GtkType</span> as their first
          argument, and create an object or widget of that type.
          They then take a list of argument-value pairs, just as
          <tt class="FUNCTION">gtk_object_set()</tt> does. There
          are also <tt class="FUNCTION">gtk_object_newv()</tt> and
          <tt class="FUNCTION">gtk_widget_newv()</tt> variants.
        </p>
      </div>
      <div class="SECT2">
        <h2 class="SECT2">
          <a name="Z107">Reading Object Arguments</a>
        </h2>
        <p>
          To get the value of one or more arguments, you simply
          create an array of <span class="STRUCTNAME">
          GtkArg</span>, filling in the <span class="STRUCTNAME">
          name</span> field of each <span class="STRUCTNAME">
          GtkArg</span>. <tt class="FUNCTION">
          gtk_object_getv()</tt> fills in the <span class= 
          "STRUCTNAME">type</span> fields and the argument values.
          If an error occurs, the <span class="STRUCTNAME">
          type</span> field is set to <span class="STRUCTNAME">
          GTK_TYPE_INVALID</span>. If the fundamental type of the
          returned value is <span class="STRUCTNAME">
          GTK_TYPE_STRING</span>, <span class="STRUCTNAME">
          GTK_TYPE_BOXED</span>, or <span class="STRUCTNAME">
          GTK_TYPE_ARGS</span>, you are responsible for freeing it.
        </p>
        <p>
          Here's a simple example:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;  GtkArg args[2];
    
  args[0].name = "GtkContainer::border_width";
  args[1].name = "GtkContainer::resize_mode";
  gtk_object_getv(GTK_OBJECT(button), 
                  2, 
                  args);

  g_assert(args[0].type == GTK_TYPE_ULONG);
  g_assert(args[1].type == GTK_TYPE_RESIZE_MODE);
  g_assert(GTK_FUNDAMENTAL_TYPE(args[1].type) == GTK_TYPE_ENUM);

  printf("Border width: %lu Resize mode: %d\n", 
         GTK_VALUE_ULONG(args[0]), GTK_VALUE_ENUM(args[1]));&#13;
</pre>
            </td>
          </tr>
        </table>
      </div>
      <div class="SECT2">
        <h2 class="SECT2">
          <a name="SEC-GETSETARG">Using Object Arguments in Your
          Own <span class="STRUCTNAME">GtkObject</span>
          Subclass</a>
        </h2>
        <p>
          If you're writing a custom <span class="STRUCTNAME">
          GtkObject</span> or a custom subclass of some existing
          object, you can register your own object arguments in the
          class initialization function, at the same time you
          register your object's signals. To do this, call <tt
          class="FUNCTION">gtk_object_add_arg_type()</tt>---here's
          an example from <tt class="CLASSNAME">GtkContainer</tt>:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;    gtk_object_add_arg_type("GtkContainer::border_width", 
                            GTK_TYPE_ULONG, 
                            GTK_ARG_READWRITE, 
                            ARG_BORDER_WIDTH);
  
</pre>
            </td>
          </tr>
        </table>
        <p>
          The first argument must be a static string constant,
          because GTK+ does not copy it. It must also begin with
          the name of your new class, separated from the name of
          the argument by two colons (reminiscent of the C++ scope
          operator). The second argument should be the type of the
          argument; this can be any <span class="STRUCTNAME">
          GtkType</span> GTK+ knows about.
        </p>
        <p>
          The third argument contains one or more flags, defined in
          <tt class="FILENAME">gtk/gtkobject.h</tt>. The available
          flags are:
        </p>
        <ul>
          <li>
            <p>
              <span class="STRUCTNAME">GTK_ARG_READABLE</span>
              means the argument's value can be read, using <tt
              class="FUNCTION">gtk_object_getv()</tt>.&#13;
            </p>
          </li>
          <li>
            <p>
              <span class="STRUCTNAME">GTK_ARG_WRITABLE</span>
              means the argument's value can be written, using <tt
              class="FUNCTION">gtk_object_set()</tt> or <tt class= 
              "FUNCTION">gtk_object_setv()</tt>&#13;
            </p>
          </li>
          <li>
            <p>
              <span class="STRUCTNAME">GTK_ARG_CONSTRUCT</span>
              means the argument should be initialized with a
              default value. This applies to numeric and pointer
              types; they are set to <span class="STRUCTNAME">
              0</span> or <span class="STRUCTNAME">NULL</span>,
              respectively. (This happens within <tt class=
              "FUNCTION">gtk_object_new()</tt> or <tt class= 
              "FUNCTION">gtk_widget_new()</tt>, which call <tt
              class="FUNCTION">
              gtk_object_default_construct()</tt>.) &#13;
            </p>
          </li>
          <li>
            <p>
              <span class="STRUCTNAME">
              GTK_ARG_CONSTRUCT_ONLY</span> means the argument is
              <i class="EMPHASIS">only</i> used for object
              construction; it cannot be read or written later.
              That is, you can't use these arguments with <tt
              class="FUNCTION">gtk_object_set()</tt>. &#13;
            </p>
          </li>
          <li>
            <p>
              <span class="STRUCTNAME">GTK_ARG_CHILD_ARG</span> is
              used by subclasses of <tt class="CLASSNAME">
              GtkContainer</tt>; <tt class="CLASSNAME">
              GtkContainer</tt> implements a specialized variation
              on the argument system to permit setting the
              attributes of child-container pairs (such as packing
              flags for <tt class="CLASSNAME">GtkBox</tt>---the
              flags are not a property of the child or the
              container, but of the pair). You will only use this
              flag if you're writing a new type of container, or
              some other kind of object with similar semantics.
              &#13;
            </p>
          </li>
          <li>
            <p>
              <span class="STRUCTNAME">GTK_ARG_READWRITE</span> is
              shorthand for <span class="STRUCTNAME">
              (GTK_ARG_READABLE | GTK_ARG_WRITABLE)</span>.&#13;
            </p>
          </li>
        </ul>
        <p>
          There are some limitations on which flags can be used.
        </p>
        <ul>
          <li>
            <p>
              All arguments must be either readable or
              writable.&#13;
            </p>
          </li>
          <li>
            <p>
              <span class="STRUCTNAME">GTK_ARG_CONSTRUCT</span>
              arguments must be both readable and writable.&#13;
            </p>
          </li>
          <li>
            <p>
              <span class="STRUCTNAME">
              GTK_ARG_CONSTRUCT_ONLY</span> arguments must be
              writable.&#13;
            </p>
          </li>
          <li>
            <p>
              <span class="STRUCTNAME">GTK_ARG_CHILD_ARG</span>
              should not be used outside of container-style object
              implementations; it is used internally by the <span
              class="STRUCTNAME">GtkContainer</span> child argument
              functions.&#13;
            </p>
          </li>
        </ul>
        <p>
          The fourth and final argument to <tt class="FUNCTION">
          gtk_object_add_arg_type()</tt> is an argument ID to be
          used by the object subclass to identify this argument.
          This can be any integer except <span class="STRUCTNAME">
          0</span>, but it is customary to use a private
          enumeration in the object implementation's <tt class= 
          "APPLICATION">.c</tt> file. <span class="STRUCTNAME">
          GtkObject</span> has two class functions any subclass
          with arguments must implement: one to get arguments
          specific to the subclass, and one to set them. These
          functions are passed the argument ID, so they know which
          argument to get or set. Argument IDs reduce the need for
          string comparisons, increasing the efficiency of argument
          manipulation.
        </p>
        <p>
          For example, <tt class="CLASSNAME">GtkContainer</tt>
          defines these functions:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
 
static void gtk_container_get_arg(GtkObject* object,
                                  GtkArg* arg,
                                  guint arg_id);
static void gtk_container_set_arg(GtkObject* object,
                                  GtkArg* arg,
                                  guint arg_id);&#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          It uses this enumeration to create its argument IDs:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;enum {
  ARG_0,              /* Skip 0, an invalid argument ID */
  ARG_BORDER_WIDTH,
  ARG_RESIZE_MODE,
  ARG_CHILD
};&#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          It registers its arguments in <tt class="FUNCTION">
          gtk_container_class_init()</tt> as follows:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;  gtk_object_add_arg_type("GtkContainer::border_width",
                          GTK_TYPE_ULONG, 
                          GTK_ARG_READWRITE, 
                          ARG_BORDER_WIDTH);
  gtk_object_add_arg_type("GtkContainer::resize_mode", 
                          GTK_TYPE_RESIZE_MODE, 
                          GTK_ARG_READWRITE, 
                          ARG_RESIZE_MODE);
  gtk_object_add_arg_type("GtkContainer::child", 
                          GTK_TYPE_WIDGET, 
                          GTK_ARG_WRITABLE, 
                          ARG_CHILD);&#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          <tt class="FUNCTION">gtk_container_set_arg()</tt> and <tt
          class="FUNCTION">gtk_container_get_arg()</tt> are
          installed in the class struct:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;  object_class-&gt;get_arg = gtk_container_get_arg;
  object_class-&gt;set_arg = gtk_container_set_arg;&#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          <tt class="FUNCTION">gtk_container_set_arg()</tt> and <tt
          class="FUNCTION">gtk_container_get_arg()</tt> are then
          implemented like this:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;static void
gtk_container_set_arg (GtkObject    *object,
                       GtkArg       *arg,
                       guint         arg_id)
{
  GtkContainer *container;

  container = GTK_CONTAINER (object);

  switch (arg_id)
    {
    case ARG_BORDER_WIDTH:
      gtk_container_set_border_width (container, GTK_VALUE_ULONG (*arg));
      break;
    case ARG_RESIZE_MODE:
      gtk_container_set_resize_mode (container, GTK_VALUE_ENUM (*arg));
      break;
    case ARG_CHILD:
      gtk_container_add (container, GTK_WIDGET (GTK_VALUE_OBJECT (*arg)));
      break;
    default:
      break;
    }
}

static void
gtk_container_get_arg (GtkObject    *object,
                       GtkArg       *arg,
                       guint         arg_id)
{
  GtkContainer *container;

  container = GTK_CONTAINER (object);
  
  switch (arg_id)
    {
    case ARG_BORDER_WIDTH:
      GTK_VALUE_ULONG (*arg) = container-&gt;border_width;
      break;
    case ARG_RESIZE_MODE:
      GTK_VALUE_ENUM (*arg) = container-&gt;resize_mode;
      break;
    default:
      arg-&gt;type = GTK_TYPE_INVALID;
      break;
    }
}    &#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          Notice that the type must be set to <span class= 
          "STRUCTNAME">GTK_TYPE_INVALID</span> if your subclass
          doesn't understand the argument ID. This is used as an
          error indicator; users who call <tt class="FUNCTION">
          gtk_object_getv()</tt> will check for it.
        </p>
        <p>
          If you flip back to page XXXX and have another look at
          the <tt class="CLASSNAME">GtkButton</tt> class
          initialization function, you should now understand what
          is going on with respect to object arguments.
        </p>
      </div>
      <div class="SECT2">
        <h2 class="SECT2">
          <a name="Z108">Discovering the Available Object
          Arguments</a>
        </h2>
        <p>
          You can easily find out at runtime what arguments a given
          <span class="STRUCTNAME">GtkObject</span> understands,
          using the <tt class="FUNCTION">
          gtk_object_query_args()</tt>. Here is a nifty piece of
          code which prints out the arguments for the entire class
          hierarchy of a given <span class="STRUCTNAME">
          GtkObject</span>:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;void
print_arguments(GtkObject* object)
{
  GtkType type;

  type = GTK_OBJECT_TYPE(object);

  do {
    GtkArg* args;
    guint32* flags;
    guint n_args;
    guint i;

    args = gtk_object_query_args(type,
                                 &amp;flags, 
                                 &amp;n_args);
  
    printf("Displaying arguments for object type `%s'\n",
           gtk_type_name(type));

    i = 0;
    while (i &lt; n_args)
      {
        printf(" - Argument %u is called `%s' and has type `%s'\n",
               i, 
               args[i].name, 
               gtk_type_name(args[i].type));
      
        ++i;
      }

    g_free(args);
    g_free(flags);

    type = gtk_type_parent(type);
  } 
  while (type != GTK_TYPE_INVALID);
}&#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          Notice that a type's parent type can be obtained using
          the <tt class="FUNCTION">gtk_type_parent()</tt> function,
          and that you can extract the <span class="STRUCTNAME">
          GtkType</span> tag from a <span class="STRUCTNAME">
          GtkObject</span> using the <tt class="FUNCTION">
          GTK_OBJECT_TYPE()</tt> macro. <tt class="FUNCTION">
          GTK_OBJECT_TYPE()</tt> is defined as follows:
        </p>
        <table border="0" bgcolor="#E0E0E0" width="100%">
          <tr>
            <td>
<pre class="PROGRAMLISTING">
&#13;#define GTK_OBJECT_TYPE(obj) (GTK_OBJECT (obj)-&gt;klass-&gt;type)&#13;
</pre>
            </td>
          </tr>
        </table>
        <p>
          An object's type is stored in its class structure, and a
          pointer to an object's class structure is stored in each
          instance of the object. (The class structure pointer is
          called <span class="STRUCTNAME">klass</span> rather than
          <span class="STRUCTNAME">class</span> to avoid confusing
          C++ compilers.)
        </p>
        <p>
          <a href="hc-objectargs.html#FL-OBJARGS">Figure 3</a>
          summarizes the functions for reading, writing, and
          querying object arguments.
        </p>
        <div class="FIGURE">
          <a name="FL-OBJARGS"></a>
          <div class="FUNCSYNOPSIS">
            <a name="FL-OBJARGS.SYNOPSIS"></a>
            <table border="0" bgcolor="#E0E0E0" width="100%">
              <tr>
                <td>
<pre class="FUNCSYNOPSISINFO">
#include &lt;gtk/gtkobject.h&gt;
</pre>
                </td>
              </tr>
            </table>
            <p>
              <code><code class="FUNCDEF">void <tt class=
              "FUNCTION">gtk_object_getv</tt></code>(GtkObject* <tt
              class="PARAMETER"><i>object</i></tt>, guint <tt
              class="PARAMETER"><i>n_args</i></tt>, GtkArg* <tt
              class="PARAMETER"><i>args</i></tt>);</code>
            </p>
            <p>
              <code><code class="FUNCDEF">void <tt class=
              "FUNCTION">gtk_object_set</tt></code>(GtkObject* <tt
              class="PARAMETER"><i>object</i></tt>, const gchar*
              <tt class="PARAMETER"><i>first_arg_name</i></tt>, <tt
              class="PARAMETER"><i>...</i></tt>);</code>
            </p>
            <p>
              <code><code class="FUNCDEF">void <tt class=
              "FUNCTION">gtk_object_setv</tt></code>(GtkObjec* <tt
              class="PARAMETER"><i>object</i></tt>, guint <tt
              class="PARAMETER"><i>n_args</i></tt>, GtkArg* <tt
              class="PARAMETER"><i>args</i></tt>);</code>
            </p>
            <p>
              <code><code class="FUNCDEF">void <tt class=
              "FUNCTION">gtk_object_add_arg_type</tt></code>(const
              gchar* <tt class="PARAMETER"><i>arg_name</i></tt>,
              GtkType <tt class="PARAMETER"><i>arg_type</i></tt>,
              guint <tt class="PARAMETER"><i>arg_flags</i></tt>,
              guint <tt class="PARAMETER"><i>
              arg_id</i></tt>);</code>
            </p>
            <p>
              <code><code class="FUNCDEF">GtkArg* <tt class= 
              "FUNCTION">gtk_object_query_args</tt></code>(GtkType
              <tt class="PARAMETER"><i>class_type</i></tt>,
              guint32** <tt class="PARAMETER"><i>
              arg_flags</i></tt>, guint* <tt class="PARAMETER"><i>
              n_args</i></tt>);</code>
            </p>
          </div>
          <p>
            <b>Figure 3. Manipulating Object Arguments</b>
          </p>
        </div>
      </div>
    </div>
    <div class="NAVFOOTER">
      <br>
      <br>
      <table width="100%" border="0" bgcolor="#ffffff" cellpadding= 
      "1" cellspacing="0">
        <tr>
          <td width="25%" bgcolor="#ffffff" align="left">
            <a href="sec-gtkarg.html"><font color="#0000ff" size=
            "2"><b>&lt;&lt;&lt; Previous</b></font></a>
          </td>
          <td width="25%" colspan="2" bgcolor="#ffffff" align= 
          "center">
            <font color="#0000ff" size="2"><b><a href="ggad.html">
            <font color="#0000ff" size="2"><b>
            Home</b></font></a></b></font>
          </td>
          <td width="25%" bgcolor="#ffffff" align="right">
            <a href="z109.html"><font color="#0000ff" size="2"><b>
            Next &gt;&gt;&gt;</b></font></a>
          </td>
        </tr>
        <tr>
          <td colspan="2" align="left">
            <font color="#000000" size="2"><b><span class= 
            "STRUCTNAME">GtkArg</span> and the Type
            System</b></font>
          </td>
          <td colspan="2" align="right">
            <font color="#000000" size="2"><b>Signals</b></font>
          </td>
        </tr>
      </table>
    </div>
  </body>
</html>