Re: [gtk-devel-list] Re: GtkType stuff



On 7 Sep 1998, Owen Taylor wrote:

> 
> Tim Janik <timj@gtk.org> writes:
> 
> > On 5 Sep 1998, Marius Vollmer wrote:
> > 
> > > Tim Janik <timj@gtk.org> writes:
> > > 
> > > > > GtkArgs are used to pass values to signal handlers.  Thus, as of now,
> > > > > signal handlers can only have signatures that are expressable with the
> > > > > current GtkArg structure.  Thus, there is no signal handler that has
> > > > > arguments with modes that are anything but "in".  Because the GtkArg
> > > > > structure can not express other modes.
> > > > 
> > > > hm, there at least have been some signal handlers like this, i.e. the
> > > > old GtkWindow::move_resize signal (still in the 1.0.x tree):
> > > >   gint (* move_resize) (GtkWindow *window,
> > > >                         gint      *x,
> > > >                         gint      *y,
> > > >                         gint       width,
> > > >                         gint       height);
> > > 
> > > Ah, I wasn't aware of this one, but I think there is a
> > > misunderstanding here.  I think calling the thing `modes' was a
> > > mistake and I will call them `flow hints' in the sequel.  C has modes
> > > and the way I want to define flow hints is not the same as modes in
> > > ADA, or the `var' keyword in Pascal.  The flow hints do not talk about
> > > whether we make a new variable when calling a function, or whether we
> > > reuse an existing one, but rather, what a function is allowed to do to
> > > the values that get passed to it.
> > > 
> > > Flow `in' means that it is not allowed to mutate that value.  This is
> > > different from not being allowed to change the variable (or argument)
> > > that happens to hold this value.  It's more like the `const'
> > > qualifier.  Actually, it's probably exactly like the `const'
> > > qualifier.  Hmm...
> > > 
> > > There is no way to mutate an integer, for example.  You can't write
> > > something like
> > > 
> > >     1 = 2;
> > > 
> > > Of course, you can write
> > > 
> > >     int x = 1, y = 1;
> > >     x = 2;
> > > 
> > > but that is only changing the object that x denotes.  The variable y
> > > is of course unaffected and still has 1 as its value.
> > > 
> > > So flow `in' is all that makes sense for integers, and for most of the
> > > other GTK_TYPE_ types defined so far (GTK_TYPE_OBJECT, GTK_TYPE_BOXED
> > > and GTK_TYPE_STRING being the exceptions).
> > > 
> > > But you *can* mutate an array.
> > > 
> > >     int array[1] = { 1 };
> > >     int *x = array, *y = array;
> > >     x[1] = 2;
> > > 
> > > This is actually modifiying the object, not merely making x denote
> > > some other object.  Since y denotes the same object, you can observe
> > > the mutation thru y.
> > > 
> > > The flow hints are intended to make this propagation of mutations work
> > > efficiently even across language barriers.
> > > 
> > > In short, it makes no sense to mark a GTK_TYPE_INT as `flowing out'
> > > because there is no way we could mutate the integer.  But we can
> > > mutate arrays, and thus, we should be using them for outward flowing
> > > information, exactly like C does.
> 
> My actual opinion is that if we want to go this route, we should go it
> all the way. The argument direction should act as in the CORBA C or
> C++ mapping - in that GTK_TYPE_INT | GTK_ARG_OUT gets mapped as int *,
> while "normal" GTK_TYPE_INT maps as before. Types that are already
> pointers do not get the extra reference.

that's basically what i proposed the GTK_REFERENCE_FLAG on GtkTypes
for.

> Anybody looking at this should definitely look the CORBA
> mapping. The CORBA mapping is rather complex, so we wouldn't
> want to copy it, but some concepts probably carry over.
> 
> The way I would do it is that the following get an extra
> reference when passed out or inout:
> 
>  - Objects that are passed by value in C - ints, floats, etc.
>  - Objects that are inherently passed by reference, such as
>    GtkObject, or GdkWindow. That is, an out GtkObject is
>    passed as an GtkObject **.
> 
> While things that are passed by reference in C, but are not
> conceptually always pass-by-reference, such as pointers 
> to fixed-length structs, do not get the extra reference.
> 
> In fact, there is nothing currently defined in gtk.defs that
> fits into the latter category, but there is a need for such.
> The prime candidate are things like the GtkRequisition argument
> to size_request.
> 
> Much more tricky is what to do if we provide some way of passing
> GLists (or GPtrArrays) as signal or function parameters. This is the
> area where the CORBA mapping gets ugly. Probably we should just
> forget the possibility of 'out/inout' GLists. 
> 
> > > > in general, "in" arguments are always a little questionable for signal
> > > 
> > > Don't you mean "out"?
> > 
> > of course.
> > 
> > > > handlers, because there is 1) no mechanism to check the returned values
> > > > for validity upon every handler invokation, and 2) it is not always clearly
> > > > defined when such modifications will take effect, i.e. does changing a
> > > > value that is passed by reference take effect if modified in an _after
> > > > handler?.
> > > 
> > > Yes, agreed.
> 
>  1) ???? For a intepreted languaged, the language binding makes sure
>     that they are valid, presumably.
> 
>  2) There is no problem for something like TYPE_INT. Each handler
>     can modify the return value if it so chooses. An OUT value
>     of, say, type GTK_TYPE_OBJECT faces the same problem as a return
>     value of GTK_TYPE_OBJECT, except in this case we can actually
>     solve the problem! We merely need to make the convention
>     that before emitting a such a signal, the caller must store
>     NULL in the value. And that any handlers that modify the
>     value must gtk_object_unref() the existing value if it
>     is not NULL.

ok, looks fine to me.

[...]

> > > That's 1.5 bits, but it's of no fundemental importance whether we need
> > > 1 or 2 bits to encode the flow hints, right?
> > > 
> > > > for one thing we could, while preserving the current _GtkArg struct
> > > > size, reduce the actuall type information to 31 bits and have
> > > > another one, indicating "inout" behaviour:
> > > > 
> > > > struct _GtkArg
> > > > {
> > > >   guint type : 31;
> > > >   guint is_inout : 1;
> > > >   gchar *name;
> > > >     
> > > >   union {
> > > >   [...]
> > > >   } d;
> > > > };
> > > > 
> > > > but this seems somewhat hackish, and i'm not sure that we do need
> > > > this at all, since the destinction can already be made through the
> > > > fundamental type anyways.
> >
> > > Yes, agreed.
> 
> I don't. The direction of the argument is not fixed for a single
> fundemental type, or even a single type. Now if you want to say that
> the type argument to gtk_signal_new is the bitwise or of a type and
> some flags, that might make sense.

again, that's what i suggested GTK_REFERENCE_FLAG for.

[...]

> > some of the above GTK_FLOW_* flags needs to indicate the C language
> > pass-by-reference behaviour, even if you don't intend that as a meaning
> > for the "flow-type" concept. otherwise, we'd be pretty much forced to change
> > all GtkType handling code in existance.
> > 
> > > > with this, for the above mentioned ::move_resize signal, you'd actually do:
> > > >     gtk_signal_new ("move_resize",
> > > >                     GTK_RUN_LAST,
> > > >                     object_class->type,
> > > >                     GTK_SIGNAL_OFFSET (GtkWindowClass, move_resize),
> > > >                     gtk_window_marshal_signal_1,
> > > >                     GTK_TYPE_BOOL, 4,
> > > >                     GTK_REFERENCE_TYPE (GTK_TYPE_INT),
> > > >                     GTK_REFERENCE_TYPE (GTK_TYPE_INT),
> > > 
> > >                       GTK_TYPE_SET_FLOW (gtk_type_get_fvec (GTK_TYPE_INT,
> > >                                                             GTK_FLOW_INOUT)),
> > 
> > so this would become
> >                         GTK_TYPE_SET_FLAGS (GTK_TYPE_INT, GTK_FLOW_INOUT),
> >                         GTK_TYPE_SET_FLAGS (GTK_TYPE_INT, GTK_FLOW_INOUT),
> >                         [...]
> 
> How about simply:
> 
>  GTK_TYPE_INT | GTK_DIRECTION_INOUT

that was the intention of the GTK_REFERENCE_TYPE() macro, it would
actually be

#define GTK_REFERENCE_TYPE(t) ((t) | GTK_REFERENCE_FLAG)

i think GTK_REFERENCE_FLAG works somewhat better as a name here, since
that actually indicates what we have to care about on the C (and thus:
implementation) side of this stuff.

> > > [ Declarations in header files ]
> > > 
> > > > > I think the same, but I don't want to stop at being close.  I want to
> > > > > get there.
> > > > 
> > > > that's what i intended the comment-enclosed hints for, just like
> > > > owen did for enums.
> > > 
> > > Yes, but ommitting these hints would make the system err on the
> > > dangerous side, not on the safe side.  When someone writes a new
> > > function and does not provide the necessary hints (because he doesn't
> > > know or care anbout them), we get incorrect behaviour.
> > > 
> > > That is, I don't want to have the possibility for introducing bugs by
> > > not knowing about the *.defs system.  I can live with incomplete
> > > functionality, tho.
>  
> > i'd be interested in hearing owen's comments on this issue, since we
> > seem to be stuck wrt the amount of headaches we want to cause for
> > the intermediate gtk programmer (occasional widget writers).
> 
> I don't want to go the route of having GTK+ written in some
> hybrid of scheme and C. If a widget writer doesn't get the
> comment enclosed hints right, then C will still work right,
> it will just happen that language bindings may not. But
> then it is an opportunity for somebody to submit patches.
> 
> I think that most C programmers will feel more comfortable with:
> 
> GdkWindow*    gdk_window_get_pointer	 (GdkWindow	  *window,
> 					  gint		  *x,   /*< out >*/
> 					  gint		  *y,   /*< out >*/
> 					  GdkModifierType *mask /*< out >*/);
>  
> Then with:
> 
> (define-func gdk_window_get_pointer
>   GdkWindow window
>   ((GdkWindow window)
>    (out int x)
>    (out int y)
>    (out GdkModifierType mask)))
> 
> In fact, I'm sure of it.

same here.

> 
> Regards,
>                                         Owen

---
ciaoTJ



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]