File: part1_getting_started.texi

package info (click to toggle)
libforms 1.0.93sp1-1
  • links: PTS
  • area: main
  • in suites: squeeze
  • size: 11,548 kB
  • ctags: 9,107
  • sloc: ansic: 97,227; sh: 9,236; makefile: 858
file content (339 lines) | stat: -rw-r--r-- 11,934 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
@node Part I Getting Started
@chapter Getting Started

This chapter introduces the typographical conventions used throughout
the manual and then continues with showing a few, simple examples on
using the Forms Library. It concludes with a short resumee of the
programming model typically found in programs using the library.

@ifnottex

@menu
* Naming Conventions::
* Some Examples::
* Programming Model::
@end menu

@end ifnottex


@node Naming Conventions
@section Naming Conventions

The names of all Forms Library functions and user-accessible data
structures begin with @code{fl_} or @code{FL_}, and use an
"underscore-between-words" convention, that is when function and
variable names are composed of more than one word, an underscore is
inserted between each word. For example,
@example
fl_state
fl_set_object_label()
fl_show_form()
@end example

All Forms Library macros, constants and types also follow this
convention, except that (at least) the first two letters are
capitalized. For example,
@example
FL_min()
FL_NORMAL_BUTTON
FL_OBJECT
@end example

The term "form" often can be taken to mean a window of your
application. But be aware that there are also can be forms that
themselves contain further forms, so "form" and "window" aren't
necessarily synonyms.

The only exceptions from the above convention are names of functions
related to image manipulations - they start with @code{flimage_}. And
then there's a single function called @code{@ref{flps_init()}} that
allows customization of the way hardcopies are created from an existing
user interface.


@node Some Examples
@section Some Examples

Before using forms for interaction with the user you first have to
define them. Next you can display them and perform interaction with
them. Both stages are simple. Before explaining all the details let us
first look at some examples. A very simple form definition would look
as
@example
FL_FORM *simpleform;
simpleform = fl_bgn_form(FL_UP_BOX, 230, 160);
fl_add_button(FL_NORMAL_BUTTON, 40, 50, 150, 60, "Push Me");
fl_end_form();
@end example

The first line indicates the start of the form definition.
@code{simpleform} will later be used to identify the form. The type of
the form is @code{FL_UP_BOX}. This means that the background of the
form is a raised box that looks like it is coming out of the screen.
The form has a size of 230 by 160 pixels. Next we add a button to the
form. The type of the button is @code{FL_NORMAL_BUTTON} which will be
explained below in detail. It is positioned in the form by virtue of
the button geometry supplied and has "Push Me" as its label. After
having defined the form we can display it using the call
@example
fl_show_form(simpleform, FL_PLACE_MOUSE, FL_NOBORDER,
             "SimpleForm");
@end example

@ifhtml
@center @image{images/pushme}
@end ifhtml
@ifnothtml
@center @image{images/pushme,5cm}
@end ifnothtml

This will show the form on the screen at the mouse position. (The
third argument indicates whether the form gets window manager's
decoration and the fourth is the window title.)

Next we give the control over the interaction to the Forms Library's
main event loop by calling
@example
fl_do_forms();
@end example
@noindent
This will handle interaction with the form until you press and release
the button with the mouse, at which moment control is returned to the
program. Now the form can be removed from the screen (and have its
associated window destroyed) using
@example
fl_hide_form(simpleform);
@end example
@noindent
The complete program is given in the file @file{pushme.c} in the
subdirectory @file{demos}. All demonstration programs can be found in
this directory. Studying them is a good way of learning how the
library works.

Compile and run it to see the effect. To compile a program using the
Forms Library use the following command or something similar
@example
cc -o pushme pushme.c -lforms
@end example
@noindent
Please note that linking against the Forms library requires some
other libraries to be istalled, at least the @code{X11} and the
@code{Xpm} library. Some applications may also require the @code{JPEG}
and/or the @code{GL} library. These libraries don't need to be
specified explicitely in the linker command but must be available
since the Forms library depends on them. If not installed contact
your systems administrator.

This simple example is, of course, of little use. Let us look at a
slightly more complicated one (the program can be found
in @file{yesno.c}.)
@example
#include <forms.h>

int main(int argc, char *argv[]) @{
    FL_FORM *form;
    FL_OBJECT *yes,
              *no,
              *but;

    fl_initialize(&argc, argv, "FormDemo", 0, 0);

    form = fl_bgn_form(FL_UP_BOX, 320, 120);
    fl_add_box(FL_NO_BOX, 160, 40, 0, 0, "Do you want to Quit?");
    yes = fl_add_button(FL_NORMAL_BUTTON, 40, 70, 80, 30, "Yes");
    no = fl_add_button(FL_NORMAL_BUTTON, 200, 70, 80, 30, "No");
    fl_end_form();

    fl_show_form(form, FL_PLACE_MOUSE, FL_TRANSIENT, "Question");

     while ((but = fl_do_forms()) != yes)
         /* empty */ ;

     fl_finish();
     return 0;
@}
@end example
@noindent
It creates a form with a simple text and two buttons. After displaying
the form @code{@ref{fl_do_forms()}} is called. This routine returns
the object being pushed. Simply checking whether this is object
@code{yes} determines whether we should quit.

@ifhtml
@center @image{images/yesno}
@end ifhtml
@ifnothtml
@center @image{images/yesno,6cm}
@end ifnothtml

As you see, the program starts by calling the routine
@code{@ref{fl_initialize()}}. This routine should be called before any
other calls to the library are made (except for
@code{@ref{fl_set_defaults()}}). One of the things this routine does
is to establish a connection to the X server and initialize a resource
database used by the X resource manager. It also does many other
things, such as parsing command line options and initializing internal
Forms Library structures. For now, it suffices to know that by calling
this routine, a program automatically recognizes the following command
line options
@multitable @columnfractions 0.3 0.3 0.4
@headitem Option
@tab Value type
@tab Meaning
@item 
@item @code{-display} @i{host:dpy}
@tab string
@tab Remote host
@item @code{-name} @i{appname}
@tab string
@tab change application name
@item @code{-visual} @i{class}
@tab string
@tab TrueColor, PseudoColor etc.
@item @code{-depth} @i{depth}
@tab integer
@tab Preferred visual depth
@item @code{-private}
@tab none
@tab Force a private colormap
@item @code{-shared}
@tab none
@tab Always share colormap
@item @code{-stdcmap}
@tab none
@tab Use standard colormap
@item @code{-fldebug} @i{level}
@tab integer
@tab Print some debug information
@item @code{-flhelp}
@tab none
@tab Print out these options
@item @code{-sync}
@tab none
@tab Force synchronous mode
@end multitable

Note that the executable name @code{argv[0]} should not contain period
or @code{*}. @xref{Part V Overview of Main Functions, , Overview of
Main Functions}, for further details. The above program can in fact be
made a lot simpler, using the goodies described in @ref{Part I
Goodies, , Goodies}. You can simply write:
@example
while (!fl_show_question("Do you want to Quit?", 0))
    /* empty */ ;
@end example
@noindent
It will have exactly the same effect. The above program only shows one
of the event handling methods provided by the library. The direct
method of event handling shown above is appropriate for simple
programs. For reasonably complicated ones, however, utilizing object
callback is strongly encouraged.

We demonstrate the use of object callbacks using the previous example
with some modifications so that event processing via callbacks is
utilized. It is recommended and also typical of a good XForms
application to separate the UI components and the application program
itself. Typically the UI components are generated by the bundled GUI
builder and the application program consists mostly of callbacks and
some glue that combines the UI and the program.

To use callbacks, a typical procedure would be to define all the
callback functions first, then register them with the system using
@code{@ref{fl_set_object_callback()}}. After the form is realized
(shown), control is handed to Forms Library's main loop
@code{@ref{fl_do_forms()}}, which responds to user events indefinitely
and never returns.

After modifications are made to utilize object callbacks, the simple
question example looks as follows:
@example
#include <stdio.h>
#include <stdlib.h>
#include <forms.h>

void yes_callback(FL_OBJECT *obj, long user_data) @{
    printf("Yes is pushed\n");
    fl_finish();
    exit(0);
@}

void no_callback(FL_OBJECT *obj, long user_data) @{
    printf("No is pushed\n");
@}

int main(int argc, char *argv[]) @{
    FL_FORM *form;
    FL_OBJECT *obj;

    fl_initialize(&argc, argv, "FormDemo", 0, 0);

    form = fl_bgn_form(FL_UP_BOX, 320, 120);
    fl_add_box(FL_NO_BOX, 160, 40, 0, 0, "Do you want to Quit?");
    obj = fl_add_button(FL_NORMAL_BUTTON, 40, 70, 80, 30,"Yes");
    fl_set_object_callback(obj, yes_callback, 0);
    obj = fl_add_button(FL_NORMAL_BUTTON, 200, 70, 80, 30,"No");
    fl_set_object_callback(obj, no_callback, 0);
    fl_end_form();

    fl_show_form(form, FL_PLACE_MOUSE, FL_TRANSIENT, "Question");
    fl_do_forms();

    return 0;
@}
@end example

In this example, callback routines for both the yes and no buttons are
first defined. Then they are registered with the system using
@code{@ref{fl_set_object_callback()}}. After the form is shown, the
event handling is again handed to the main loop in Forms Library via
@code{@ref{fl_do_forms()}}. In this case, whenever the buttons are
pushed, the callback routine is invoked with the object being pushed
as the first argument to the callback function, and
@code{@ref{fl_do_forms()}} never returns.

You might also notice that in this example, both buttons are made
anonymous, that is, it is not possible to reference the buttons
directly outside of the creation routine. This is often desirable when
callback functions are bound to objects as the objects themselves will
not be referenced except as callback arguments. By creating anonymous
objects, a program avoids littering itself with useless identifiers.

The callback model presented above is the preferred way of interaction
for typical programs and it is strongly recommended that all programs
using XForms be coded using object callbacks.


@node Programming Model
@section Programming Model

To summarize, every Forms Library application program must perform
several basic steps. These are
@table @asis
@item Initialize the Forms Library
This step establishes a connection to the X server, allocates
resources and otherwise initializes the Forms Library's internal
structures, which include visual selection, font initialization and
command line parsing.
@item Defining forms
Every program creates one or more forms and all the objects on them to
construct the user interface. This step may also include callback
registration and per object initialization such as setting bounds for
sliders etc.
@item Showing forms
This step makes the designed user interface visible by creating and
mapping the window (and subwindows) used by the forms.
@item Main loop
Most Forms Library applications are completely event-driven and are
designed to respond to user events indefinitely. The Forms Library
main loop, usually invoked by calling @code{@ref{fl_do_forms()}},
retrieves events from the X event queue, dispatches them to the
appropriate objects and notifies the application of what action, if
any, should be taken. The actual notification method depends on how
the interaction is set up, which could be done by calling an object
callback or by returning the object whose status has changed to the
application program.
@end table

The following chapters will lead you through each step of the process
with more details.