Cvo allows the use of translations to cause an action to happen when
some event occurs. For example, you might want some particular
behavior when the <Return>
key is pressed. Cvo
event translations operate virtually identically to standard X11
event translations.
In the normal course of writing an object, it is possible to set up mappings between "translations" and member functions. Default mappings are also provided. For instance, the {*}[INPUT] object has the following code:
static char *trans = "\
<Key>Delete: Delete() \n\
<Key>BackSpace: Delete() \n\
<Key>Enter: Accept() \n\
<Key>Return: Accept() \n\
<Key>Linefeed: Accept() \n\
<Key>KP_Enter: Accept() \n\
Ctrl<Key>j: Accept() \n\
Ctrl<Key>m: Accept() \n\
<Key>Left: Backward() \n\
<Key>Right: Forward() \n\
Ctrl<Key>u: EraseLine() \n\
Ctrl<Key>w: EraseWord() \n\
<Key>: Insert() \n\
~Ctrl<Btn2Up>:insert-selection(PRIMARY, CUT_BUFFER0) \n\
";
and in Cvo_Input::_Init()
there is the statement:
AddTranslations(trans);
to actually install the mapping. Suppose, however, you wanted to
also map <CTRL-A>
to cause the entry to be
accepted. One method would be to rewrite the {*}[INPUT] object (bad
idea). A prefered method would be to add some code something like:
static char *mytranslations = "\
Ctrl<Key>a: Accept() \n\
";
and then after creating the {*}[INPUT] object, assuming it is
called input
, adding the code:
input->AddTranslations(mytranslations, XLATE_OVERRIDE)
Which will cause your translation to be added to the current list of translations. The three options are:
XLATE_REPLACE
: Destroy the old translations.XLATE_OVERRIDE
: Add new translations, overriding any old translation in conflict.XLATE_AUGMENT
: Add new translations that do not conflict with the old translations.If you wish to add a new function handler, you will need to do a couple things. First, you must define an action handler of the form:
void handler({*}[OBJECT] *, XEvent *, int, char **);
The first two arguments are the object on which the translation
happened and the event that caused it. The last two provide a
standard argc, argv
style pair of arguments which point
to the arguments passed to the handler. For instance, the
translation:
~Ctrl<Btn2Up>:insert-selection(PRIMARY, CUT_BUFFER0)
would cause the value 2
to be passed in the integer
argument, and the array { "PRIMARY", "CUT_BUFFER0", 0 }
to be passed in the char **
argument.
To insert this translation the easiest thing to do is to use the
Cvo_EXTHANDLER
macro as follows:
Cvo_EXTHANDLER(object, "MyFunction", myhandler)
This actually translates to:
{
void myhandler({*}[OBJECT] *, XEvent *, int, char **);
static Cvo_ExtHandleFunction _handler("MyFunction", myhandler);
Cvo_Register(object, CvoBindEvent, _Cvo_ObjectAddBinding, &_handler);
}
Which declares the handler, creates storage for it (statically)
and then requests that it be bound when the other translations are
bound. Note that Cvo_EXTHANDLER
should not be used with a variable
for either of its last two arguments (due the the static
initialization). This implies it is not useful in a loop.