Next: Example, Up: Part I Free Objects [Contents][Index]

### 5.1 Free Object

To add a free object to a form use the call

    FL_OBJECT *fl_add_free(int type, FL_Coord x, FL_Coord y,
                           FL_Coord w, FL_Coord h,
                           const char *label, int (*handle)());

`type` indicates the type of free object, see below for a list and their meaning. `x`, `y`, `w` and `h` are the bounding box. The `label` is normally not drawn unless the `handle` routine takes care of this. `handle` is the routine that does the redrawing and handles the interaction with the free object. The application program must supply this routine.

This routine `handle` is called by the library whenever an action has to be performed. The routine should have the form:

    int handle(FL_OBJECT *obj, int event, FL_Coord mx, FL_Coord my,
               int key, void *xev);

where `obj` is the object to which the event applies. `event` indicates what has to happen to the object. See below for a list of possible events. `mx` and `my` indicate the position of the mouse (only meaningful with mouse related events) relative to the form origin and `key` is the KeySym of the key typed in by the user (only for `FL_KEYPRESS` events). `xev` is the (cast) XEvent that causes the invocation of this handler. `event` and `xev->type` can both be used to obtain the event types. The routine should return whether the status of the object has changed, i.e., whether `fl_do_forms()` or `fl_check_forms()` should return this object.

The following types of events exist for which the routine must take action:

`FL_DRAW`

  The object has to be redrawn. To figure out the size of the object you can use the fields `obj->x`, `obj->y`, `obj->w` and `obj->h`. Some other aspects might also influence the way the object has to be drawn. E.g., you might want to draw the object differently when the mouse is on top of it or when the mouse is pressed on it. This can be figured out as follows. The field `obj->belowmouse` indicates whether the object is below the mouse. The field `obj->pushed` indicates whether the object is currently being pushed with the mouse. Finally, `obj->focus` indicates whether input focus is directed towards this object. When required, the label should also be drawn. This label can be found in the field `obj->label`. The drawing should be done such that it works correctly in the visual/depth the current form is in. Complete information is available on the state of the current form as well as several routines that will help you to tackle the trickiest (also the most tedious) part of X programming. In particular, the return value of `fl_get_vclass()` can be used as an index into a table of structures, `fl_state[]`, from which all information about current active visual can be obtained. See Drawing Objects, for details on drawing objects and the routines.

`FL_DRAWLABEL`

  This event is not always generated. It typically follows `FL_DRAW` and indicates the object label needs to be (re)drawn. You can ignore this event if (a) the object handler always draws the label upon receiving `FL_DRAW` or (b) the object label is not drawn at all9.

`FL_ENTER`

  This event is sent when the mouse has entered the bounding box. This might require some action. Note that also the field `belowmouse` in the object is being set. If entering only changes the appearance redrawing the object normally suffices. Don’t do this directly! Always redraw the object using the routine `fl_redraw_object()`. It will send an `FL_DRAW` event to the object but also does some other things (like setting window id’s, taking care of double buffering and some other bookkeeping tasks).

`FL_LEAVE`

  The mouse has left the bounding box. Again, normally a redraw is enough (or nothing at all).

`FL_MOTION`

  A motion event is sent between `FL_ENTER` and `FL_LEAVE` events when the mouse position changes on the object. The mouse position is given with the routine.

`FL_PUSH`

  The user has pushed a mouse button in the object. Normally this requires some action.

`FL_RELEASE`

  The user has released the mouse button. This event is only sent if a `FL_PUSH` event was sent earlier.

`FL_DBLCLICK`

  The user has pushed a mouse button twice within a certain time limit (`FL_CLICK_TIMEOUT`), which by default is about 400 msec.

`FL_TRPLCLICK`

  The user has pushed a mouse button three times within a certain time window between each push. This event is sent after a `FL_DBLCLICK`, `FL_PUSH`, `FL_RELEASE` sequence.

`FL_UPDATE`

  The mouse position has changed. This event is sent to an object between an `FL_PUSH` and an `FL_RELEASE` event (actually this event is sent periodically, even if mouse has not moved). The mouse position is given as the parameter `mx` and `my` and action can be taken based on the position.

`FL_FOCUS`

  Input got focussed to this object. This event and the next two are only sent to a free object of type `FL_INPUT_FREE` (see below).

`FL_UNFOCUS`

  Input is no longer focussed on this object.

`FL_KEYPRESS`

  A key was pressed. The KeySym is given with the routine. This event only happens between `FL_FOCUS` and `FL_UNFOCUS` events.

`FL_STEP`

  A step event is sent all the time (at most 50 times per second but often less because of time consuming redraw operations) to a free object of type `FL_CONTINUOUS_FREE` such that it can update its state or appearance.

`FL_SHORTCUT`

  Hotkeys for the object have been triggered. Typically this should result in the returning of the free object.

`FL_FREEMEM`

  Upon receiving this event, the handler should free all object class specific memory allocated.

`FL_OTHER`

  Some other events typically caused by window manager events or inter-client events. All information regarding the details of the events is in `xev`.

Many of these events might make it necessary to (partially) redraw the object. Always do this using the routine `fl_redraw_object()`.

As indicated above not all events are sent to all free objects. It depends on their types. The following types exist (all objects are sent `FL_OTHER` when it occurs):

`FL_NORMAL_FREE`

  The object will receive the events `FL_DRAW`, `FL_ENTER`, `FL_LEAVE`, `FL_MOTION`, `FL_PUSH`, `FL_RELEASE` and `FL_MOUSE`.

`FL_INACTIVE_FREE`

  The object only receives `FL_DRAW` events. This should be used for objects without interaction (e.g., a picture).

`FL_INPUT_FREE`

  Same as `FL_NORMAL_FREE` but the object also receives `FL_FOCUS`, `FL_UNFOCUS` and `FL_KEYPRESS` events. The `obj->wantkey` is by default set to `FL_KEY_NORMAL`, i.e., the free object will receive all normal keys (0-255) except `<Tab>` and `<Return>` key. If you’re interested in `<Tab>` or `<Return>` key, you need to change `obj->wantkey` to `FL_KEY_TAB` or `FL_KEY_ALL`. See Events, for details.

`FL_CONTINUOUS_FREE`

  Same as `FL_NORMAL_FREE` but the object also receives `FL_STEP` events. This should be used for objects that change themselves continuously.

`FL_ALL_FREE`

  The object receives all types of events.

See `free1.c` for a (terrible) example of the use of free objects. See also `freedraw.c`, which is a nicer example of the use of free objects.

Free objects provide all the generality you want from the Forms Library. Because free objects behave a lot like new object classes it is recommended that you also read part IV of this documentation before designing free objects.

#### Footnotes

### (9)

Label for free objects can’t be drawn outside of the bounding box because of the clippings by the dispatcher.

Next: Example, Up: Part I Free Objects [Contents][Index]