]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - dialog.h
Support for Windows PuTTY connecting straight to a local serial port
[PuTTY.git] / dialog.h
1 /*
2  * Exports and types from dialog.c.
3  */
4
5 /*
6  * This will come in handy for generic control handlers. Anyone
7  * knows how to make this more portable, let me know :-)
8  */
9 #define ATOFFSET(data, offset) ( (void *) ( (char *)(data) + (offset) ) )
10
11 /*
12  * This is the big union which defines a single control, of any
13  * type.
14  * 
15  * General principles:
16  *  - _All_ pointers in this structure are expected to point to
17  *    dynamically allocated things, unless otherwise indicated.
18  *  - `char' fields giving keyboard shortcuts are expected to be
19  *    NO_SHORTCUT if no shortcut is desired for a particular control.
20  *  - The `label' field can often be NULL, which will cause the
21  *    control to not have a label at all. This doesn't apply to
22  *    checkboxes and push buttons, in which the label is not
23  *    separate from the control.
24  */
25
26 #define NO_SHORTCUT '\0'
27
28 enum {
29     CTRL_TEXT,                         /* just a static line of text */
30     CTRL_EDITBOX,                      /* label plus edit box */
31     CTRL_RADIO,                        /* label plus radio buttons */
32     CTRL_CHECKBOX,                     /* checkbox (contains own label) */
33     CTRL_BUTTON,                       /* simple push button (no label) */
34     CTRL_LISTBOX,                      /* label plus list box */
35     CTRL_COLUMNS,                      /* divide window into columns */
36     CTRL_FILESELECT,                   /* label plus filename selector */
37     CTRL_FONTSELECT,                   /* label plus font selector */
38     CTRL_TABDELAY                      /* see `tabdelay' below */
39 };
40
41 /*
42  * Many controls have `intorptr' unions for storing user data,
43  * since the user might reasonably want to store either an integer
44  * or a void * pointer. Here I define a union, and two convenience
45  * functions to create that union from actual integers or pointers.
46  * 
47  * The convenience functions are declared as inline if possible.
48  * Otherwise, they're declared here and defined when this header is
49  * included with DEFINE_INTORPTR_FNS defined. This is a total pain,
50  * but such is life.
51  */
52 typedef union { void *p; int i; } intorptr;
53
54 #ifndef INLINE
55 intorptr I(int i);
56 intorptr P(void *p);
57 #endif
58
59 #if defined DEFINE_INTORPTR_FNS || defined INLINE
60 #ifdef INLINE
61 #define PREFIX INLINE
62 #else
63 #define PREFIX
64 #endif
65 PREFIX intorptr I(int i) { intorptr ret; ret.i = i; return ret; }
66 PREFIX intorptr P(void *p) { intorptr ret; ret.p = p; return ret; }
67 #undef PREFIX
68 #endif
69
70 /*
71  * Each control has an `int' field specifying which columns it
72  * occupies in a multi-column part of the dialog box. These macros
73  * pack and unpack that field.
74  * 
75  * If a control belongs in exactly one column, just specifying the
76  * column number is perfectly adequate.
77  */
78 #define COLUMN_FIELD(start, span) ( (((span)-1) << 16) + (start) )
79 #define COLUMN_START(field) ( (field) & 0xFFFF )
80 #define COLUMN_SPAN(field) ( (((field) >> 16) & 0xFFFF) + 1 )
81
82 union control;
83
84 /*
85  * The number of event types is being deliberately kept small, on
86  * the grounds that not all platforms might be able to report a
87  * large number of subtle events. We have:
88  *  - the special REFRESH event, called when a control's value
89  *    needs setting
90  *  - the ACTION event, called when the user does something that
91  *    positively requests action (double-clicking a list box item,
92  *    or pushing a push-button)
93  *  - the VALCHANGE event, called when the user alters the setting
94  *    of the control in a way that is usually considered to alter
95  *    the underlying data (toggling a checkbox or radio button,
96  *    moving the items around in a drag-list, editing an edit
97  *    control)
98  *  - the SELCHANGE event, called when the user alters the setting
99  *    of the control in a more minor way (changing the selected
100  *    item in a list box).
101  *  - the CALLBACK event, which happens after the handler routine
102  *    has requested a subdialog (file selector, font selector,
103  *    colour selector) and it has come back with information.
104  */
105 enum {
106     EVENT_REFRESH,
107     EVENT_ACTION,
108     EVENT_VALCHANGE,
109     EVENT_SELCHANGE,
110     EVENT_CALLBACK
111 };
112 typedef void (*handler_fn)(union control *ctrl, void *dlg,
113                            void *data, int event);
114
115 #define STANDARD_PREFIX \
116         int type; \
117         char *label; \
118         int tabdelay; \
119         int column; \
120         handler_fn handler; \
121         intorptr context; \
122         intorptr helpctx
123
124 union control {
125     /*
126      * The first possibility in this union is the generic header
127      * shared by all the structures, which we are therefore allowed
128      * to access through any one of them.
129      */
130     struct {
131         int type;
132         /*
133          * Every control except CTRL_COLUMNS has _some_ sort of
134          * label. By putting it in the `generic' union as well as
135          * everywhere else, we avoid having to have an irritating
136          * switch statement when we go through and deallocate all
137          * the memory in a config-box structure.
138          * 
139          * Yes, this does mean that any non-NULL value in this
140          * field is expected to be dynamically allocated and
141          * freeable.
142          * 
143          * For CTRL_COLUMNS, this field MUST be NULL.
144          */
145         char *label;
146         /*
147          * If `tabdelay' is non-zero, it indicates that this
148          * particular control should not yet appear in the tab
149          * order. A subsequent CTRL_TABDELAY entry will place it.
150          */
151         int tabdelay;
152         /*
153          * Indicate which column(s) this control occupies. This can
154          * be unpacked into starting column and column span by the
155          * COLUMN macros above.
156          */
157         int column;
158         /*
159          * Most controls need to provide a function which gets
160          * called when that control's setting is changed, or when
161          * the control's setting needs initialising.
162          * 
163          * The `data' parameter points to the writable data being
164          * modified as a result of the configuration activity; for
165          * example, the PuTTY `Config' structure, although not
166          * necessarily.
167          * 
168          * The `dlg' parameter is passed back to the platform-
169          * specific routines to read and write the actual control
170          * state.
171          */
172         handler_fn handler;
173         /*
174          * Almost all of the above functions will find it useful to
175          * be able to store a piece of `void *' or `int' data.
176          */
177         intorptr context;
178         /*
179          * For any control, we also allow the storage of a piece of
180          * data for use by context-sensitive help. For example, on
181          * Windows you can click the magic question mark and then
182          * click a control, and help for that control should spring
183          * up. Hence, here is a slot in which to store per-control
184          * data that a particular platform-specific driver can use
185          * to ensure it brings up the right piece of help text.
186          */
187         intorptr helpctx;
188     } generic;
189     struct {
190         STANDARD_PREFIX;
191         union control *ctrl;
192     } tabdelay;
193     struct {
194         STANDARD_PREFIX;
195     } text;
196     struct {
197         STANDARD_PREFIX;
198         char shortcut;                 /* keyboard shortcut */
199         /*
200          * Percentage of the dialog-box width used by the edit box.
201          * If this is set to 100, the label is on its own line;
202          * otherwise the label is on the same line as the box
203          * itself.
204          */
205         int percentwidth;
206         int password;                  /* details of input are hidden */
207         /*
208          * A special case of the edit box is the combo box, which
209          * has a drop-down list built in. (Note that a _non_-
210          * editable drop-down list is done as a special case of a
211          * list box.)
212          */
213         int has_list;
214         /*
215          * Edit boxes tend to need two items of context, so here's
216          * a spare.
217          */
218         intorptr context2;
219     } editbox;
220     struct {
221         STANDARD_PREFIX;
222         /*
223          * `shortcut' here is a single keyboard shortcut which is
224          * expected to select the whole group of radio buttons. It
225          * can be NO_SHORTCUT if required, and there is also a way
226          * to place individual shortcuts on each button; see below.
227          */
228         char shortcut;
229         /*
230          * There are separate fields for `ncolumns' and `nbuttons'
231          * for several reasons.
232          * 
233          * Firstly, we sometimes want the last of a set of buttons
234          * to have a longer label than the rest; we achieve this by
235          * setting `ncolumns' higher than `nbuttons', and the
236          * layout code is expected to understand that the final
237          * button should be given all the remaining space on the
238          * line. This sounds like a ludicrously specific special
239          * case (if we're doing this sort of thing, why not have
240          * the general ability to have a particular button span
241          * more than one column whether it's the last one or not?)
242          * but actually it's reasonably common for the sort of
243          * three-way control you get a lot of in PuTTY: `yes'
244          * versus `no' versus `some more complex way to decide'.
245          * 
246          * Secondly, setting `nbuttons' higher than `ncolumns' lets
247          * us have more than one line of radio buttons for a single
248          * setting. A very important special case of this is
249          * setting `ncolumns' to 1, so that each button is on its
250          * own line.
251          */
252         int ncolumns;
253         int nbuttons;
254         /*
255          * This points to a dynamically allocated array of `char *'
256          * pointers, each of which points to a dynamically
257          * allocated string.
258          */
259         char **buttons;                /* `nbuttons' button labels */
260         /*
261          * This points to a dynamically allocated array of `char'
262          * giving the individual keyboard shortcuts for each radio
263          * button. The array may be NULL if none are required.
264          */
265         char *shortcuts;               /* `nbuttons' shortcuts; may be NULL */
266         /*
267          * This points to a dynamically allocated array of
268          * intorptr, giving helpful data for each button.
269          */
270         intorptr *buttondata;          /* `nbuttons' entries; may be NULL */
271     } radio;
272     struct {
273         STANDARD_PREFIX;
274         char shortcut;
275     } checkbox;
276     struct {
277         STANDARD_PREFIX;
278         char shortcut;
279         /*
280          * At least Windows has the concept of a `default push
281          * button', which gets implicitly pressed when you hit
282          * Return even if it doesn't have the input focus.
283          */
284         int isdefault;
285         /*
286          * Also, the reverse of this: a default cancel-type button,
287          * which is implicitly pressed when you hit Escape.
288          */
289         int iscancel;
290     } button;
291     struct {
292         STANDARD_PREFIX;
293         char shortcut;                 /* keyboard shortcut */
294         /*
295          * Height of the list box, in approximate number of lines.
296          * If this is zero, the list is a drop-down list.
297          */
298         int height;                    /* height in lines */
299         /*
300          * If this is set, the list elements can be reordered by
301          * the user (by drag-and-drop or by Up and Down buttons,
302          * whatever the per-platform implementation feels
303          * comfortable with). This is not guaranteed to work on a
304          * drop-down list, so don't try it!
305          */
306         int draglist;
307         /*
308          * If this is non-zero, the list can have more than one
309          * element selected at a time. This is not guaranteed to
310          * work on a drop-down list, so don't try it!
311          * 
312          * Different non-zero values request slightly different
313          * types of multi-selection (this may well be meaningful
314          * only in GTK, so everyone else can ignore it if they
315          * want). 1 means the list box expects to have individual
316          * items selected, whereas 2 means it expects the user to
317          * want to select a large contiguous range at a time.
318          */
319         int multisel;
320         /*
321          * Percentage of the dialog-box width used by the list box.
322          * If this is set to 100, the label is on its own line;
323          * otherwise the label is on the same line as the box
324          * itself. Setting this to anything other than 100 is not
325          * guaranteed to work on a _non_-drop-down list, so don't
326          * try it!
327          */
328         int percentwidth;
329         /*
330          * Some list boxes contain strings that contain tab
331          * characters. If `ncols' is greater than 0, then
332          * `percentages' is expected to be non-zero and to contain
333          * the respective widths of `ncols' columns, which together
334          * will exactly fit the width of the list box. Otherwise
335          * `percentages' must be NULL.
336          */
337         int ncols;                     /* number of columns */
338         int *percentages;              /* % width of each column */
339     } listbox;
340     struct {
341         STANDARD_PREFIX;
342         char shortcut;
343         /*
344          * `filter' dictates what type of files will be selected by
345          * default; for example, when selecting private key files
346          * the file selector would do well to only show .PPK files
347          * (on those systems where this is the chosen extension).
348          * 
349          * The precise contents of `filter' are platform-defined,
350          * unfortunately. The special value NULL means `all files'
351          * and is always a valid fallback.
352          * 
353          * Unlike almost all strings in this structure, this value
354          * is NOT expected to require freeing (although of course
355          * you can always use ctrl_alloc if you do need to create
356          * one on the fly). This is because the likely mode of use
357          * is to define string constants in a platform-specific
358          * header file, and directly reference those. Or worse, a
359          * particular platform might choose to cast integers into
360          * this pointer type...
361          */
362         char const *filter;
363         /*
364          * Some systems like to know whether a file selector is
365          * choosing a file to read or one to write (and possibly
366          * create).
367          */
368         int for_writing;
369         /*
370          * On at least some platforms, the file selector is a
371          * separate dialog box, and contains a user-settable title.
372          * 
373          * This value _is_ expected to require freeing.
374          */
375         char *title;
376     } fileselect;
377     struct {
378         /* In this variant, `label' MUST be NULL. */
379         STANDARD_PREFIX;
380         int ncols;                     /* number of columns */
381         int *percentages;              /* % width of each column */
382         /*
383          * Every time this control type appears, exactly one of
384          * `ncols' and the previous number of columns MUST be one.
385          * Attempting to allow a seamless transition from a four-
386          * to a five-column layout, for example, would be way more
387          * trouble than it was worth. If you must lay things out
388          * like that, define eight unevenly sized columns and use
389          * column-spanning a lot. But better still, just don't.
390          * 
391          * `percentages' may be NULL if ncols==1, to save space.
392          */
393     } columns;
394     struct {
395         STANDARD_PREFIX;
396         char shortcut;
397     } fontselect;
398 };
399
400 #undef STANDARD_PREFIX
401
402 /*
403  * `controlset' is a container holding an array of `union control'
404  * structures, together with a panel name and a title for the whole
405  * set. In Windows and any similar-looking GUI, each `controlset'
406  * in the config will be a container box within a panel.
407  * 
408  * Special case: if `boxname' is NULL, the control set gives an
409  * overall title for an entire panel of controls.
410  */
411 struct controlset {
412     char *pathname;                    /* panel path, e.g. "SSH/Tunnels" */
413     char *boxname;                     /* internal short name of controlset */
414     char *boxtitle;                    /* title of container box */
415     int ncolumns;                      /* current no. of columns at bottom */
416     int ncontrols;                     /* number of `union control' in array */
417     int ctrlsize;                      /* allocated size of array */
418     union control **ctrls;             /* actual array */
419 };
420
421 /*
422  * This is the container structure which holds a complete set of
423  * controls.
424  */
425 struct controlbox {
426     int nctrlsets;                     /* number of ctrlsets */
427     int ctrlsetsize;                   /* ctrlset size */
428     struct controlset **ctrlsets;      /* actual array of ctrlsets */
429     int nfrees;
430     int freesize;
431     void **frees;                      /* array of aux data areas to free */
432 };
433
434 struct controlbox *ctrl_new_box(void);
435 void ctrl_free_box(struct controlbox *);
436
437 /*
438  * Standard functions used for populating a controlbox structure.
439  */
440
441 /* Set up a panel title. */
442 struct controlset *ctrl_settitle(struct controlbox *,
443                                  char *path, char *title);
444 /* Retrieve a pointer to a controlset, creating it if absent. */
445 struct controlset *ctrl_getset(struct controlbox *,
446                                char *path, char *name, char *boxtitle);
447 void ctrl_free_set(struct controlset *);
448
449 void ctrl_free(union control *);
450
451 /*
452  * This function works like `malloc', but the memory it returns
453  * will be automatically freed when the controlbox is freed. Note
454  * that a controlbox is a dialog-box _template_, not an instance,
455  * and so data allocated through this function is better not used
456  * to hold modifiable per-instance things. It's mostly here for
457  * allocating structures to be passed as control handler params.
458  */
459 void *ctrl_alloc(struct controlbox *b, size_t size);
460
461 /*
462  * Individual routines to create `union control' structures in a controlset.
463  * 
464  * Most of these routines allow the most common fields to be set
465  * directly, and put default values in the rest. Each one returns a
466  * pointer to the `union control' it created, so that final tweaks
467  * can be made.
468  */
469
470 /* `ncolumns' is followed by that many percentages, as integers. */
471 union control *ctrl_columns(struct controlset *, int ncolumns, ...);
472 union control *ctrl_editbox(struct controlset *, char *label, char shortcut,
473                             int percentage, intorptr helpctx,
474                             handler_fn handler,
475                             intorptr context, intorptr context2);
476 union control *ctrl_combobox(struct controlset *, char *label, char shortcut,
477                              int percentage, intorptr helpctx,
478                              handler_fn handler,
479                              intorptr context, intorptr context2);
480 /*
481  * `ncolumns' is followed by (alternately) radio button titles and
482  * intorptrs, until a NULL in place of a title string is seen. Each
483  * title is expected to be followed by a shortcut _iff_ `shortcut'
484  * is NO_SHORTCUT.
485  */
486 union control *ctrl_radiobuttons(struct controlset *, char *label,
487                                  char shortcut, int ncolumns,
488                                  intorptr helpctx,
489                                  handler_fn handler, intorptr context, ...);
490 union control *ctrl_pushbutton(struct controlset *,char *label,char shortcut,
491                                intorptr helpctx,
492                                handler_fn handler, intorptr context);
493 union control *ctrl_listbox(struct controlset *,char *label,char shortcut,
494                             intorptr helpctx,
495                             handler_fn handler, intorptr context);
496 union control *ctrl_droplist(struct controlset *, char *label, char shortcut,
497                              int percentage, intorptr helpctx,
498                              handler_fn handler, intorptr context);
499 union control *ctrl_draglist(struct controlset *,char *label,char shortcut,
500                              intorptr helpctx,
501                              handler_fn handler, intorptr context);
502 union control *ctrl_filesel(struct controlset *,char *label,char shortcut,
503                             char const *filter, int write, char *title,
504                             intorptr helpctx,
505                             handler_fn handler, intorptr context);
506 union control *ctrl_fontsel(struct controlset *,char *label,char shortcut,
507                             intorptr helpctx,
508                             handler_fn handler, intorptr context);
509 union control *ctrl_text(struct controlset *, char *text, intorptr helpctx);
510 union control *ctrl_checkbox(struct controlset *, char *label, char shortcut,
511                              intorptr helpctx,
512                              handler_fn handler, intorptr context);
513 union control *ctrl_tabdelay(struct controlset *, union control *);
514
515 /*
516  * Standard handler routines to cover most of the common cases in
517  * the config box.
518  */
519 /*
520  * The standard radio-button handler expects the main `context'
521  * field to contain the `offsetof' of an int field in the structure
522  * pointed to by `data', and expects each of the individual button
523  * data to give a value for that int field.
524  */
525 void dlg_stdradiobutton_handler(union control *ctrl, void *dlg,
526                                 void *data, int event);
527 /*
528  * The standard checkbox handler expects the main `context' field
529  * to contain the `offsetof' an int field in the structure pointed
530  * to by `data', optionally ORed with CHECKBOX_INVERT to indicate
531  * that the sense of the datum is opposite to the sense of the
532  * checkbox.
533  */
534 #define CHECKBOX_INVERT (1<<30)
535 void dlg_stdcheckbox_handler(union control *ctrl, void *dlg,
536                              void *data, int event);
537 /*
538  * The standard edit-box handler expects the main `context' field
539  * to contain the `offsetof' a field in the structure pointed to by
540  * `data'. The secondary `context2' field indicates the type of
541  * this field:
542  * 
543  *  - if context2 > 0, the field is a char array and context2 gives
544  *    its size.
545  *  - if context2 == -1, the field is an int and the edit box is
546  *    numeric.
547  *  - if context2 < -1, the field is an int and the edit box is
548  *    _floating_, and (-context2) gives the scale. (E.g. if
549  *    context2 == -1000, then typing 1.2 into the box will set the
550  *    field to 1200.)
551  */
552 void dlg_stdeditbox_handler(union control *ctrl, void *dlg,
553                             void *data, int event);
554 /*
555  * The standard file-selector handler expects the main `context'
556  * field to contain the `offsetof' a Filename field in the
557  * structure pointed to by `data'.
558  */
559 void dlg_stdfilesel_handler(union control *ctrl, void *dlg,
560                             void *data, int event);
561 /*
562  * The standard font-selector handler expects the main `context'
563  * field to contain the `offsetof' a Font field in the structure
564  * pointed to by `data'.
565  */
566 void dlg_stdfontsel_handler(union control *ctrl, void *dlg,
567                             void *data, int event);
568
569 /*
570  * Routines the platform-independent dialog code can call to read
571  * and write the values of controls.
572  */
573 void dlg_radiobutton_set(union control *ctrl, void *dlg, int whichbutton);
574 int dlg_radiobutton_get(union control *ctrl, void *dlg);
575 void dlg_checkbox_set(union control *ctrl, void *dlg, int checked);
576 int dlg_checkbox_get(union control *ctrl, void *dlg);
577 void dlg_editbox_set(union control *ctrl, void *dlg, char const *text);
578 void dlg_editbox_get(union control *ctrl, void *dlg, char *buffer, int length);
579 /* The `listbox' functions can also apply to combo boxes. */
580 void dlg_listbox_clear(union control *ctrl, void *dlg);
581 void dlg_listbox_del(union control *ctrl, void *dlg, int index);
582 void dlg_listbox_add(union control *ctrl, void *dlg, char const *text);
583 /*
584  * Each listbox entry may have a numeric id associated with it.
585  * Note that some front ends only permit a string to be stored at
586  * each position, which means that _if_ you put two identical
587  * strings in any listbox then you MUST not assign them different
588  * IDs and expect to get meaningful results back.
589  */
590 void dlg_listbox_addwithid(union control *ctrl, void *dlg,
591                            char const *text, int id);
592 int dlg_listbox_getid(union control *ctrl, void *dlg, int index);
593 /* dlg_listbox_index returns <0 if no single element is selected. */
594 int dlg_listbox_index(union control *ctrl, void *dlg);
595 int dlg_listbox_issel(union control *ctrl, void *dlg, int index);
596 void dlg_listbox_select(union control *ctrl, void *dlg, int index);
597 void dlg_text_set(union control *ctrl, void *dlg, char const *text);
598 void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn);
599 void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn);
600 void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec fn);
601 void dlg_fontsel_get(union control *ctrl, void *dlg, FontSpec *fn);
602 /*
603  * Bracketing a large set of updates in these two functions will
604  * cause the front end (if possible) to delay updating the screen
605  * until it's all complete, thus avoiding flicker.
606  */
607 void dlg_update_start(union control *ctrl, void *dlg);
608 void dlg_update_done(union control *ctrl, void *dlg);
609 /*
610  * Set input focus into a particular control.
611  */
612 void dlg_set_focus(union control *ctrl, void *dlg);
613 /*
614  * Change the label text on a control.
615  */
616 void dlg_label_change(union control *ctrl, void *dlg, char const *text);
617 /*
618  * Return the `ctrl' structure for the most recent control that had
619  * the input focus apart from the one mentioned. This is NOT
620  * GUARANTEED to work on all platforms, so don't base any critical
621  * functionality on it!
622  */
623 union control *dlg_last_focused(union control *ctrl, void *dlg);
624 /*
625  * During event processing, you might well want to give an error
626  * indication to the user. dlg_beep() is a quick and easy generic
627  * error; dlg_error() puts up a message-box or equivalent.
628  */
629 void dlg_beep(void *dlg);
630 void dlg_error_msg(void *dlg, char *msg);
631 /*
632  * This function signals to the front end that the dialog's
633  * processing is completed, and passes an integer value (typically
634  * a success status).
635  */
636 void dlg_end(void *dlg, int value);
637
638 /*
639  * Routines to manage a (per-platform) colour selector.
640  * dlg_coloursel_start() is called in an event handler, and
641  * schedules the running of a colour selector after the event
642  * handler returns. The colour selector will send EVENT_CALLBACK to
643  * the control that spawned it, when it's finished;
644  * dlg_coloursel_results() fetches the results, as integers from 0
645  * to 255; it returns nonzero on success, or zero if the colour
646  * selector was dismissed by hitting Cancel or similar.
647  * 
648  * dlg_coloursel_start() accepts an RGB triple which is used to
649  * initialise the colour selector to its starting value.
650  */
651 void dlg_coloursel_start(union control *ctrl, void *dlg,
652                          int r, int g, int b);
653 int dlg_coloursel_results(union control *ctrl, void *dlg,
654                           int *r, int *g, int *b);
655
656 /*
657  * This routine is used by the platform-independent code to
658  * indicate that the value of a particular control is likely to
659  * have changed. It triggers a call of the handler for that control
660  * with `event' set to EVENT_REFRESH.
661  * 
662  * If `ctrl' is NULL, _all_ controls in the dialog get refreshed
663  * (for loading or saving entire sets of settings).
664  */
665 void dlg_refresh(union control *ctrl, void *dlg);
666
667 /*
668  * It's perfectly possible that individual controls might need to
669  * allocate or store per-dialog-instance data, so here's a
670  * mechanism.
671  * 
672  * `dlg_get_privdata' and `dlg_set_privdata' allow the user to get
673  * and set a void * pointer associated with the control in
674  * question. `dlg_alloc_privdata' will allocate memory, store a
675  * pointer to that memory in the private data field, and arrange
676  * for it to be automatically deallocated on dialog cleanup.
677  */
678 void *dlg_get_privdata(union control *ctrl, void *dlg);
679 void dlg_set_privdata(union control *ctrl, void *dlg, void *ptr);
680 void *dlg_alloc_privdata(union control *ctrl, void *dlg, size_t size);
681
682 /*
683  * Standard helper functions for reading a controlbox structure.
684  */
685
686 /*
687  * Find the index of next controlset in a controlbox for a given
688  * path, or -1 if no such controlset exists. If -1 is passed as
689  * input, finds the first. Intended usage is something like
690  * 
691  *      for (index=-1; (index=ctrl_find_path(ctrlbox, index, path)) >= 0 ;) {
692  *          ... process this controlset ...
693  *      }
694  */
695 int ctrl_find_path(struct controlbox *b, char *path, int index);
696 int ctrl_path_elements(char *path);
697 /* Return the number of matching path elements at the starts of p1 and p2,
698  * or INT_MAX if the paths are identical. */
699 int ctrl_path_compare(char *p1, char *p2);