Events and Event Registration
Event registration and processing is where most of the work gets done when
running a Cvo application. Events are generated when something happens, such
as the user pressing a mouse button, or typing a key, or exposing a window.
Other events are generated by objects themselves, such as an event to state
that an object is about to be destroyed, or it has become visible, or the
data in it has changed. Traditional toolkits have used both Events, refering
to events generated by the X server as well as Callbacks, refering to
actions caused by an object itself. Cvo has merged these two similar concepts
into a single item called an Event. Events are either generated asynchronously
by the X server, and serialized in an event processing loop, or are generated
synchronously by an object and processed immediately.
Events are registered for on the object that will recieve them. For instance,
if you need to do processing whenever the "obj" object has a new child created
on it, you might say:
obj->Register(CvoCreatedChildEvent, my_handler);
Where "my_handler" is the function which will be called when a new child is
created.
The full range of possiblities for registration by an application are:
Register(event, [mask,] function, [client_data])
RegisterKey(key, [mask,] function, [client_data])
Where
CARD32 event The event to registered for. The event may either
be a standard X11 event, or an internal Cvo event.
KeySym key The key to be registered for. This should be one
of the XK_ symbols found in .
CARD16 mask An optional mask of modifiers that must be present
in order to call the handler function. Possibilities
are ShiftMask, LockMask, ControlMask, Mod[1-5]Mask,
Button[1-5]Mask.
void (*function)(Cvo_Object *, XEvent *, void *)
The function to be called when the event happend.
The function will be passed a pointer to the object
on which the registration was made, a pointer to the
actual event, and a pointer to the client_data that
was optionally passed at the time of registration.
void (Cvo_Class::*function)(XEvent *, void *)
It is also possible to pass in a pointer to member
function of the object. In this case, the object
need not be passed to the function as it is implied.
This form of registration is reserved for member
functions of the objects class and cannot be called
publicly.
void *client_data Optional data that will be passed to the handler
function when called. If not provided, 0 will be
passed.
A very simple example of an event handler is the Cvo_MenuDismiss() function.
This function is used to dismiss (delete) an object and all of its ancestors
(except for the root window of the display, naturally). The code is simply:
void
Cvo_MenuDismiss(Cvo_Object *w, XEvent *, void *)
{
delete w->RootObject();
}
A program fragment that might call it would be:
Cvo_Button *b = new Cvo_Button("dismiss", parent, "Dismiss");
b->Register(CvoButtonUpEvent, Cvo_MenuDismiss);
When writing an object that is derived from the Cvo_Object class, you may
create member functions which are called when events happen. An example
class declaration is:
class MyClass : public Cvo_Window {
protected:
void _Init();
CVO_DEFINE_REGISTER_FUNCTIONS(MyClass)
public:
CONSTRUCDECL(MyClass)
void event_handler(XEvent *, void *);
}
CONSTRUCTORS(MyClass, Cvo_Window, "MyClass")
CVO_CREATE_REGISTER_FUNCTIONS(MyClass)
void
MyClass::event_handler(XEvent *event, void *data)
{
...
}
void
MyClass::_Init()
{
...
Register(Expose, event_handler);
...
}
The 4 macros used are:
CVO_DEFINE_REGISTER_FUNCTIONS(MyClass)
Declare the various incantations of the Register() and RegisterKey()
functions. Both for handlers which are member functions and those
which are global. The class name must be passed.
CONSTRUCDECL(MyClass)
Declare the default constructors for the class. The class name must
be passed.
CVO_CREATE_REGISTER_FUNCTIONS(MyClass)
Expands to the actual Register() functions. The class name must be
passed.
CONSTRUCTORS(MyClass, Cvo_Window, "MyClass")
Expands to the actual constructor functions. The class name, the
parent class name, and the X Resource class name of the object
must be passed.