Re: Dumb question about GTK--




> Tero Pulkkinen <terop@students.cc.tut.fi> writes:
> > I think one thing that should be done is to check all integer arguments
> > in gtk and check that there isnt anything that could be enums or other
> > more restricted types! Integers in public interface where they dont
> > represent integer value are really bad..
> > 
> > or then, maybe there's something I've missed :)

Owen Taylor <owt1@cornell.edu> writes:
> I think you have. In C using enumerations for mask fields is fine (and
> I prefer it that way because it shows in the header what type:
> needed). But AFAIK, in C++,
> 
>   set_events (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK)
> 
> would be invalid if the argument was of type GdkEventMask. 

Yes, for that operator|, the compiler makes automatic conversion to integers
and uses integer operator| - which returns integer => error on passing the
argument.

But for C++, we should overload the operator| and operator& for those types.

Like this:

typedef enum
{
  GDK_EXPOSURE_MASK             = 1 << 1,
  GDK_POINTER_MOTION_MASK       = 1 << 2,
  GDK_POINTER_MOTION_HINT_MASK  = 1 << 3,
  GDK_BUTTON_MOTION_MASK        = 1 << 4,
  GDK_BUTTON1_MOTION_MASK       = 1 << 5,
  GDK_BUTTON2_MOTION_MASK       = 1 << 6,
  GDK_BUTTON3_MOTION_MASK       = 1 << 7,
  GDK_BUTTON_PRESS_MASK         = 1 << 8,
  GDK_BUTTON_RELEASE_MASK       = 1 << 9,
  GDK_KEY_PRESS_MASK            = 1 << 10,
  GDK_KEY_RELEASE_MASK          = 1 << 11,
  GDK_ENTER_NOTIFY_MASK         = 1 << 12,
  GDK_LEAVE_NOTIFY_MASK         = 1 << 13,
  GDK_FOCUS_CHANGE_MASK         = 1 << 14,
  GDK_STRUCTURE_MASK            = 1 << 15,
  GDK_PROPERTY_CHANGE_MASK      = 1 << 16,
  GDK_VISIBILITY_NOTIFY_MASK    = 1 << 17,
  GDK_PROXIMITY_IN_MASK         = 1 << 18,
  GDK_PROXIMITY_OUT_MASK        = 1 << 19,
  GDK_ALL_EVENTS_MASK           = 0x07FFFF
} GdkEventMask;

// the c++ magic to specify something that C does automatically for all enums.
#ifdef __cplusplus
GdkEventMask operator|(GdkEventMask a, GdkEventMask b) { 
    return (GdkEventMask)(a|b);
}
GdkEventMask operator&(GdkEventMask a, GdkEventMask b) { 
    return (GdkEventMask)(a&b);
}
#endif

This needs to be defined for each enum which is needed for a mask. After
that we can use them exactly like in C and we can put the enums back to
the interface. (which is *way* much better than how its done currently)

> [ That is, in C++, a enumeration variable can only be assigned one of
>   the values of the enumeration. ]
> 
> (But you're the C++ expert) So I think that's why guint's are used for
> mask fields in many places. (Though it isn't consistent right now)

We need to get these kind of holes in the type safety out from the
interface. (or at least make it less possible to break it)

-- 
-- Tero Pulkkinen -- terop@modeemi.cs.tut.fi --



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