OSDN Git Service

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