Provided by: libgiigic1-dev_1.1.2-2.1_amd64 bug


       libgiigic-usage - LibGIIGIC Overview


       LibGIIGIC  is  intended  to  help  the game developer with a flexible input mapping system
       which enables the user to easily adjust the bindings between game actions  and  the  input
       device movements.


       Please  do  not  get  confused  by  the tons of API calls. Most are only useful if you are
       developing  new  configmanagers  or  applications  that  have  very  special  needs,  like
       reconfiguring their controlset on the fly.

       A  "normal" game will usually only use a very small subset of the LibGIIGIC API, depending
       if it wants to just use a given GIC configuration, or if it  also  wants  to  implement  a
       configuration manager.

       Actually it is a good idea, to at least allow the user to run his own config manager if he
       wants to.


       LibGIIGIC has its own terminology that describes how an application and the  actions  that
       can be triggered within it relate. This can be confusing at first, so please make sure you
       read this section carefully and refer to it, if unsure.

       From LibGIIGIC's point of view, an application is represented  as  a  "Head".   This  term
       stems  from  the  fact,  that  an  application  might serve multiple displays (heads) with
       different configurations. LibGGI will usually have its own inputs for each head, then.

       Within each head, applications will  usually  have  different  needs  for  input  mapping,
       depending  on  the  current  state  of  the  application.  In  LibGIIGIC  this is called a

       Each context (like "in game", "main menu", ...) will usually have several aspects that can
       be  controlled,  for example movement, weapon choice, etc.  This is what LibGIIGIC calls a

       Most  Controls  have  several  subunits.  For  example  movement  may  contain  "forward",
       "backward", "left" and "right". LibGIIGIC calls these "Features".

       Most  of  the  time,  one  feature  can  be controlled by a single keystroke, mouse-click,
       joystick movement, etc. However sometimes it makes sense to have multiple bindings for the
       same feature.

       Any such user input that is associated to a feature is called a "Recognizer".

       This hierarchy of types that builds the skeleton of LibGIIGIC.

       It  can be represented as a file. Look at programs/demos/configmanager.gic for an example.
       Such a ".gic-file" contains all the configuration info for a given head.

       Of course it is not enough to just recognize, that a feature has been  activated  by  some
       input. One usually wants to act on that.

       LibGIIGIC  allows to bind callback functions to features that get called when a Recognizer
       triggers. These are called "Actions".


       Now let's have a look at a very simple sample program - demo.c

       When working with LibGIIGIC, you first need to initialize  the  library.   Do  this  using
       gicInit().  When you don't need LibGIIGIC anymore, close it down using gicExit(). Don't be
       afraid to use that in higher level libraries.  LibGIIGIC is aware of being initialized and
       exited  multiple  times,  and  will  handle  it correctly, as long as the calls are nested

       These calls only initialize the  lib.  To  interact  with  it,  you  need  to  allocate  a
       gic_handle_t using gicOpen(NULL). The parameter is reserved for future expansion. When you
       are done with it, free the allocated handle using gicClose(handle).

       If you have an existing configuration file, you just read it:

       config = fopen("demo.gic", "r");
       head = gicHeadRead(handle, config);

       Simple - right?

       You can of course stuff your other data there, too. gicHeadRead(3) is aware  of  where  to
       stop, so you can store your data before and after the LibGIIGIC data to your liking.

       If  you  are  interested in rehearsing the terminoloy chapter, you may want to look at the
       demo.gic file yourself. It is human readable and you will find the hierarchy of objects in

       Now what you got back is an object "head" which is of type gic_head(3).

       However,  you  will  usually  work  with  contexts, as the application will normally enter
       different states associated with gic_context(3)'s.

       You can extract the contexts from the head like this:

       menu = gicHeadLookupContext(handle, head, "Menu context");

       Now we have one point that needs to be cleaned up: the file also stores actions, which are
       basically  callbacks.  However  how does one store function pointers in a config file in a
       way that does not break when moving the config file between platforms etc. ?

       You don't. The next step is to reestablish the "action mapping" - a connection  between  a
       symbolic name of the action, and the actual callback function. This mapping is stored in a
       variable of type gic_actionlist.

       A sample list would be:

       gic_actionlist actionmapping[]= {
             {NULL,"mynextaction",   my_action,      NULL},
             {NULL,"myprevaction",   my_action2,     (void *)0x12345678},

       The first element of each gic_actionlist-entry here is reserved for a chaining pointer and
       always NULL.

       The second element is the name of the action as it appears in the .gic-file.  The third is
       the callback function, and the fourth a void pointer to some private data  which  will  be
       given to the callback.

       The  fourth  entry allows to reuse the same callback function for multiple purposes, which
       makes a lot of sense, as many callback functions are usually very similar.

       You can now re-map the actions using this call:


       This will cause LibGIIGIC to iterate through the head and its child objects and  find  any
       actions  attached.  If  the  action  names  match  a  name  in the actionmapping list, the
       respective callbacks are set up.

       From then on, LibGIIGIC is ready to receive events. You  just  receive  a  gii_event  from
       LibGII  (or  LibGGI which uses LibGII for input), or build one yourself, if you insist not
       to use LibGII.

       You can then feed the event to LibGIIGIC using:

       gicContextHandleEvent(handle,menu, &event);

       Note, that it does not make sense to send an event to a head,  as  the  event  might  have
       different meanings depending on context. So you just feed it to the right context.

       Now  if  an event matches the description in the .gic file, the requested action callbacks
       will fire. We will discuss them in greater detail in the next section.

       When we are done with LibGIIGIC,  we  should  close  down  all  handles  we  opened  using
       gicClose(handle) and finally call gicExit().


       If  a  recognizer  triggers, it will activate the feature it is attached to, which will in
       turn call the actions bound to it.

       Action functions have the following prototype:

       void my_action(gic_handle_t hand, gic_actionlist *action,
             gic_feature *feature, gic_state newstate,gic_flag flag,
             int recnum);

       When it gets called, it is given a lot of data that allows to derive why it was called.

       First of all it gets the gic_handle_t that triggered the action. This is  useful,  if  you
       want to call LibGIIGIC functions within the callback.

       Then you get the gic_actionlist of the action that caused the callback to be actived. This
       datatype was already  covered  in  the  previous  section.   It's  most  common  uses  are
       differentiating calls to a common callback that serves multiple purposes. To achieve this,
       the most interesting entries are action->name and action->privdata, which will commonly be
       used  to  find  out which action triggered and to point to some common data structure that
       will be modified by the actions.

       The gic_feature(3) points to the feature that this action is bound to and can as  well  be
       used to differentiate when binding a single action function to multiple features.

       When  a  feature gets activated, it can have an "extent to which it is activated". This is
       used by features that don't only have on/off characteristics, but rather a  linear  notion
       of "how active they are".  An example for this is e.g. a control for turning. Simple input
       devices like keyboards can only say turn left/don't turn left, while mice or joysticks can
       say how fast or far to turn.

       gic_state   carries   this   information.   The   macros   GIC_STATE_MIN,   GIC_STATE_MAX,
       GIC_STATE_MIDDLE and GIC_NOACTION can be used  to  find  out  how  strong  the  respective
       measure of activation was.

       gic_flag  can  carry  additional  information about the action. If flags are set, that are
       within GIC_FLAG_MUSTKNOWMASK, you are expected to handle them.   Set  flags  outside  that
       bitmask are optional and can be ignored for application development.

       Up  to now, only one such flag is defined: GIC_FLAG_PULSE.  If set, it indicates, that the
       events triggering the action is of a "pulsed" type, i.e. it is  expected  to  be  released
       immediately after it was received, so you should handle it similar to the case of an event
       like the one you received, immediately followed by one of the  same  kind  with  gic_state
       containing GIC_STATE_MIN.

       The  integer  recnum gives the number of the recognizer that caused this event to trigger.
       This can be used when implementing "adding policies", like if turning  with  joystick  and
       mouse at the same time will add up, or will just use the highest value, or whatever.


       Many  simple  programs  will prefer not to use their own action callbacks, but rather just
       use this predefined callback system.

       For this to work, you have to bind all relevant actions you do not want to handle yourself
       to gicActionLazyAction(3).

       The privdata field must point to a gicActionLazyData(3) variable.

       When using the Lazy action helpers, you usually do something like this:

       ggiEventRead(vis,&event,emAll);               /* get an event. */
       /* Let LibGIC evaluate it for the menu context */
       gicContextHandleEvent(hand, menucon, &event);

       Now  the  gicActionLazyAction(3)  callbacks  are  run,  and  you  can  check  how much the
       individual gicActionLazyData(3) elements are active.

       For this, you do: gicActionLazyGetstate(&lazydata) which will return a gic_state  you  can
       evaluate.  (The  gicActionLazyAction(3)  callback implement a "max activation is returned"
       policy with respect to multiple active recognizers).

       This will also handle the case of pulsed inputs, which will be returned and then deleted.

       If you are unsure about the state of the variables (e.g. at startup  or  after  retraining
       the mappings), you can reset the variables using gicActionLazyReset(3).