fe8abbf4 |
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 | |
c6f21f1b |
54 | #ifndef INLINE |
55 | intorptr I(int i); |
56 | intorptr P(void *p); |
57 | #endif |
58 | |
fe8abbf4 |
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 |
fe8abbf4 |
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 |
4a693cfc |
165 | * example, the PuTTY `Conf' structure, although not |
fe8abbf4 |
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.) |
f160b7b8 |
212 | * |
213 | * Don't try setting has_list and password on the same |
214 | * control; front ends are not required to support that |
215 | * combination. |
fe8abbf4 |
216 | */ |
217 | int has_list; |
218 | /* |
219 | * Edit boxes tend to need two items of context, so here's |
220 | * a spare. |
221 | */ |
222 | intorptr context2; |
223 | } editbox; |
224 | struct { |
225 | STANDARD_PREFIX; |
226 | /* |
227 | * `shortcut' here is a single keyboard shortcut which is |
228 | * expected to select the whole group of radio buttons. It |
229 | * can be NO_SHORTCUT if required, and there is also a way |
230 | * to place individual shortcuts on each button; see below. |
231 | */ |
232 | char shortcut; |
233 | /* |
234 | * There are separate fields for `ncolumns' and `nbuttons' |
235 | * for several reasons. |
236 | * |
237 | * Firstly, we sometimes want the last of a set of buttons |
238 | * to have a longer label than the rest; we achieve this by |
239 | * setting `ncolumns' higher than `nbuttons', and the |
240 | * layout code is expected to understand that the final |
241 | * button should be given all the remaining space on the |
242 | * line. This sounds like a ludicrously specific special |
243 | * case (if we're doing this sort of thing, why not have |
244 | * the general ability to have a particular button span |
245 | * more than one column whether it's the last one or not?) |
246 | * but actually it's reasonably common for the sort of |
247 | * three-way control you get a lot of in PuTTY: `yes' |
248 | * versus `no' versus `some more complex way to decide'. |
249 | * |
250 | * Secondly, setting `nbuttons' higher than `ncolumns' lets |
251 | * us have more than one line of radio buttons for a single |
252 | * setting. A very important special case of this is |
253 | * setting `ncolumns' to 1, so that each button is on its |
254 | * own line. |
255 | */ |
256 | int ncolumns; |
257 | int nbuttons; |
258 | /* |
259 | * This points to a dynamically allocated array of `char *' |
260 | * pointers, each of which points to a dynamically |
261 | * allocated string. |
262 | */ |
263 | char **buttons; /* `nbuttons' button labels */ |
264 | /* |
265 | * This points to a dynamically allocated array of `char' |
266 | * giving the individual keyboard shortcuts for each radio |
267 | * button. The array may be NULL if none are required. |
268 | */ |
269 | char *shortcuts; /* `nbuttons' shortcuts; may be NULL */ |
270 | /* |
271 | * This points to a dynamically allocated array of |
272 | * intorptr, giving helpful data for each button. |
273 | */ |
274 | intorptr *buttondata; /* `nbuttons' entries; may be NULL */ |
275 | } radio; |
276 | struct { |
277 | STANDARD_PREFIX; |
278 | char shortcut; |
279 | } checkbox; |
280 | struct { |
281 | STANDARD_PREFIX; |
282 | char shortcut; |
283 | /* |
284 | * At least Windows has the concept of a `default push |
285 | * button', which gets implicitly pressed when you hit |
286 | * Return even if it doesn't have the input focus. |
287 | */ |
288 | int isdefault; |
0bd8d76d |
289 | /* |
290 | * Also, the reverse of this: a default cancel-type button, |
291 | * which is implicitly pressed when you hit Escape. |
292 | */ |
293 | int iscancel; |
fe8abbf4 |
294 | } button; |
295 | struct { |
296 | STANDARD_PREFIX; |
297 | char shortcut; /* keyboard shortcut */ |
298 | /* |
299 | * Height of the list box, in approximate number of lines. |
300 | * If this is zero, the list is a drop-down list. |
301 | */ |
302 | int height; /* height in lines */ |
303 | /* |
304 | * If this is set, the list elements can be reordered by |
305 | * the user (by drag-and-drop or by Up and Down buttons, |
306 | * whatever the per-platform implementation feels |
307 | * comfortable with). This is not guaranteed to work on a |
308 | * drop-down list, so don't try it! |
309 | */ |
310 | int draglist; |
311 | /* |
8eed910d |
312 | * If this is non-zero, the list can have more than one |
313 | * element selected at a time. This is not guaranteed to |
314 | * work on a drop-down list, so don't try it! |
315 | * |
316 | * Different non-zero values request slightly different |
317 | * types of multi-selection (this may well be meaningful |
318 | * only in GTK, so everyone else can ignore it if they |
319 | * want). 1 means the list box expects to have individual |
320 | * items selected, whereas 2 means it expects the user to |
321 | * want to select a large contiguous range at a time. |
fe8abbf4 |
322 | */ |
323 | int multisel; |
324 | /* |
325 | * Percentage of the dialog-box width used by the list box. |
326 | * If this is set to 100, the label is on its own line; |
327 | * otherwise the label is on the same line as the box |
328 | * itself. Setting this to anything other than 100 is not |
329 | * guaranteed to work on a _non_-drop-down list, so don't |
330 | * try it! |
331 | */ |
332 | int percentwidth; |
333 | /* |
334 | * Some list boxes contain strings that contain tab |
335 | * characters. If `ncols' is greater than 0, then |
336 | * `percentages' is expected to be non-zero and to contain |
337 | * the respective widths of `ncols' columns, which together |
338 | * will exactly fit the width of the list box. Otherwise |
339 | * `percentages' must be NULL. |
f160b7b8 |
340 | * |
341 | * There should never be more than one column in a |
342 | * drop-down list (one with height==0), because front ends |
343 | * may have to implement it as a special case of an |
344 | * editable combo box. |
fe8abbf4 |
345 | */ |
346 | int ncols; /* number of columns */ |
347 | int *percentages; /* % width of each column */ |
348 | } listbox; |
349 | struct { |
350 | STANDARD_PREFIX; |
351 | char shortcut; |
352 | /* |
353 | * `filter' dictates what type of files will be selected by |
354 | * default; for example, when selecting private key files |
355 | * the file selector would do well to only show .PPK files |
356 | * (on those systems where this is the chosen extension). |
357 | * |
358 | * The precise contents of `filter' are platform-defined, |
359 | * unfortunately. The special value NULL means `all files' |
360 | * and is always a valid fallback. |
361 | * |
362 | * Unlike almost all strings in this structure, this value |
363 | * is NOT expected to require freeing (although of course |
364 | * you can always use ctrl_alloc if you do need to create |
365 | * one on the fly). This is because the likely mode of use |
366 | * is to define string constants in a platform-specific |
367 | * header file, and directly reference those. Or worse, a |
368 | * particular platform might choose to cast integers into |
369 | * this pointer type... |
370 | */ |
371 | char const *filter; |
372 | /* |
373 | * Some systems like to know whether a file selector is |
374 | * choosing a file to read or one to write (and possibly |
375 | * create). |
376 | */ |
377 | int for_writing; |
378 | /* |
379 | * On at least some platforms, the file selector is a |
380 | * separate dialog box, and contains a user-settable title. |
381 | * |
382 | * This value _is_ expected to require freeing. |
383 | */ |
384 | char *title; |
385 | } fileselect; |
386 | struct { |
387 | /* In this variant, `label' MUST be NULL. */ |
388 | STANDARD_PREFIX; |
389 | int ncols; /* number of columns */ |
390 | int *percentages; /* % width of each column */ |
391 | /* |
392 | * Every time this control type appears, exactly one of |
393 | * `ncols' and the previous number of columns MUST be one. |
394 | * Attempting to allow a seamless transition from a four- |
395 | * to a five-column layout, for example, would be way more |
396 | * trouble than it was worth. If you must lay things out |
397 | * like that, define eight unevenly sized columns and use |
398 | * column-spanning a lot. But better still, just don't. |
399 | * |
400 | * `percentages' may be NULL if ncols==1, to save space. |
401 | */ |
402 | } columns; |
403 | struct { |
404 | STANDARD_PREFIX; |
405 | char shortcut; |
406 | } fontselect; |
407 | }; |
408 | |
409 | #undef STANDARD_PREFIX |
410 | |
411 | /* |
412 | * `controlset' is a container holding an array of `union control' |
413 | * structures, together with a panel name and a title for the whole |
414 | * set. In Windows and any similar-looking GUI, each `controlset' |
415 | * in the config will be a container box within a panel. |
416 | * |
417 | * Special case: if `boxname' is NULL, the control set gives an |
418 | * overall title for an entire panel of controls. |
419 | */ |
420 | struct controlset { |
421 | char *pathname; /* panel path, e.g. "SSH/Tunnels" */ |
422 | char *boxname; /* internal short name of controlset */ |
423 | char *boxtitle; /* title of container box */ |
424 | int ncolumns; /* current no. of columns at bottom */ |
425 | int ncontrols; /* number of `union control' in array */ |
426 | int ctrlsize; /* allocated size of array */ |
427 | union control **ctrls; /* actual array */ |
428 | }; |
429 | |
f0ee0238 |
430 | typedef void (*ctrl_freefn_t)(void *); /* used by ctrl_alloc_with_free */ |
431 | |
fe8abbf4 |
432 | /* |
433 | * This is the container structure which holds a complete set of |
434 | * controls. |
435 | */ |
436 | struct controlbox { |
437 | int nctrlsets; /* number of ctrlsets */ |
438 | int ctrlsetsize; /* ctrlset size */ |
439 | struct controlset **ctrlsets; /* actual array of ctrlsets */ |
440 | int nfrees; |
441 | int freesize; |
442 | void **frees; /* array of aux data areas to free */ |
f0ee0238 |
443 | ctrl_freefn_t *freefuncs; /* parallel array of free functions */ |
fe8abbf4 |
444 | }; |
445 | |
446 | struct controlbox *ctrl_new_box(void); |
447 | void ctrl_free_box(struct controlbox *); |
448 | |
449 | /* |
450 | * Standard functions used for populating a controlbox structure. |
451 | */ |
452 | |
453 | /* Set up a panel title. */ |
454 | struct controlset *ctrl_settitle(struct controlbox *, |
455 | char *path, char *title); |
456 | /* Retrieve a pointer to a controlset, creating it if absent. */ |
457 | struct controlset *ctrl_getset(struct controlbox *, |
458 | char *path, char *name, char *boxtitle); |
459 | void ctrl_free_set(struct controlset *); |
460 | |
461 | void ctrl_free(union control *); |
462 | |
463 | /* |
464 | * This function works like `malloc', but the memory it returns |
465 | * will be automatically freed when the controlbox is freed. Note |
466 | * that a controlbox is a dialog-box _template_, not an instance, |
467 | * and so data allocated through this function is better not used |
468 | * to hold modifiable per-instance things. It's mostly here for |
469 | * allocating structures to be passed as control handler params. |
f0ee0238 |
470 | * |
471 | * ctrl_alloc_with_free also allows you to provide a function to free |
472 | * the structure, in case there are other dynamically allocated bits |
473 | * and pieces dangling off it. |
fe8abbf4 |
474 | */ |
475 | void *ctrl_alloc(struct controlbox *b, size_t size); |
f0ee0238 |
476 | void *ctrl_alloc_with_free(struct controlbox *b, size_t size, |
477 | ctrl_freefn_t freefunc); |
fe8abbf4 |
478 | |
479 | /* |
480 | * Individual routines to create `union control' structures in a controlset. |
481 | * |
482 | * Most of these routines allow the most common fields to be set |
483 | * directly, and put default values in the rest. Each one returns a |
484 | * pointer to the `union control' it created, so that final tweaks |
485 | * can be made. |
486 | */ |
487 | |
488 | /* `ncolumns' is followed by that many percentages, as integers. */ |
489 | union control *ctrl_columns(struct controlset *, int ncolumns, ...); |
490 | union control *ctrl_editbox(struct controlset *, char *label, char shortcut, |
491 | int percentage, intorptr helpctx, |
492 | handler_fn handler, |
493 | intorptr context, intorptr context2); |
494 | union control *ctrl_combobox(struct controlset *, char *label, char shortcut, |
495 | int percentage, intorptr helpctx, |
496 | handler_fn handler, |
497 | intorptr context, intorptr context2); |
498 | /* |
499 | * `ncolumns' is followed by (alternately) radio button titles and |
500 | * intorptrs, until a NULL in place of a title string is seen. Each |
501 | * title is expected to be followed by a shortcut _iff_ `shortcut' |
502 | * is NO_SHORTCUT. |
503 | */ |
504 | union control *ctrl_radiobuttons(struct controlset *, char *label, |
505 | char shortcut, int ncolumns, |
506 | intorptr helpctx, |
507 | handler_fn handler, intorptr context, ...); |
508 | union control *ctrl_pushbutton(struct controlset *,char *label,char shortcut, |
509 | intorptr helpctx, |
510 | handler_fn handler, intorptr context); |
511 | union control *ctrl_listbox(struct controlset *,char *label,char shortcut, |
512 | intorptr helpctx, |
513 | handler_fn handler, intorptr context); |
514 | union control *ctrl_droplist(struct controlset *, char *label, char shortcut, |
515 | int percentage, intorptr helpctx, |
516 | handler_fn handler, intorptr context); |
517 | union control *ctrl_draglist(struct controlset *,char *label,char shortcut, |
518 | intorptr helpctx, |
519 | handler_fn handler, intorptr context); |
520 | union control *ctrl_filesel(struct controlset *,char *label,char shortcut, |
521 | char const *filter, int write, char *title, |
522 | intorptr helpctx, |
523 | handler_fn handler, intorptr context); |
524 | union control *ctrl_fontsel(struct controlset *,char *label,char shortcut, |
525 | intorptr helpctx, |
526 | handler_fn handler, intorptr context); |
527 | union control *ctrl_text(struct controlset *, char *text, intorptr helpctx); |
528 | union control *ctrl_checkbox(struct controlset *, char *label, char shortcut, |
529 | intorptr helpctx, |
530 | handler_fn handler, intorptr context); |
531 | union control *ctrl_tabdelay(struct controlset *, union control *); |
532 | |
533 | /* |
fe8abbf4 |
534 | * Routines the platform-independent dialog code can call to read |
535 | * and write the values of controls. |
536 | */ |
537 | void dlg_radiobutton_set(union control *ctrl, void *dlg, int whichbutton); |
538 | int dlg_radiobutton_get(union control *ctrl, void *dlg); |
539 | void dlg_checkbox_set(union control *ctrl, void *dlg, int checked); |
540 | int dlg_checkbox_get(union control *ctrl, void *dlg); |
541 | void dlg_editbox_set(union control *ctrl, void *dlg, char const *text); |
4a693cfc |
542 | char *dlg_editbox_get(union control *ctrl, void *dlg); /* result must be freed by caller */ |
fe8abbf4 |
543 | /* The `listbox' functions can also apply to combo boxes. */ |
544 | void dlg_listbox_clear(union control *ctrl, void *dlg); |
545 | void dlg_listbox_del(union control *ctrl, void *dlg, int index); |
546 | void dlg_listbox_add(union control *ctrl, void *dlg, char const *text); |
547 | /* |
548 | * Each listbox entry may have a numeric id associated with it. |
549 | * Note that some front ends only permit a string to be stored at |
550 | * each position, which means that _if_ you put two identical |
551 | * strings in any listbox then you MUST not assign them different |
552 | * IDs and expect to get meaningful results back. |
553 | */ |
4eaff8d4 |
554 | void dlg_listbox_addwithid(union control *ctrl, void *dlg, |
555 | char const *text, int id); |
fe8abbf4 |
556 | int dlg_listbox_getid(union control *ctrl, void *dlg, int index); |
557 | /* dlg_listbox_index returns <0 if no single element is selected. */ |
558 | int dlg_listbox_index(union control *ctrl, void *dlg); |
559 | int dlg_listbox_issel(union control *ctrl, void *dlg, int index); |
560 | void dlg_listbox_select(union control *ctrl, void *dlg, int index); |
561 | void dlg_text_set(union control *ctrl, void *dlg, char const *text); |
962468d4 |
562 | void dlg_filesel_set(union control *ctrl, void *dlg, Filename *fn); |
563 | Filename *dlg_filesel_get(union control *ctrl, void *dlg); |
ae62eaeb |
564 | void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec *fn); |
565 | FontSpec *dlg_fontsel_get(union control *ctrl, void *dlg); |
fe8abbf4 |
566 | /* |
567 | * Bracketing a large set of updates in these two functions will |
568 | * cause the front end (if possible) to delay updating the screen |
569 | * until it's all complete, thus avoiding flicker. |
570 | */ |
571 | void dlg_update_start(union control *ctrl, void *dlg); |
572 | void dlg_update_done(union control *ctrl, void *dlg); |
573 | /* |
574 | * Set input focus into a particular control. |
575 | */ |
576 | void dlg_set_focus(union control *ctrl, void *dlg); |
577 | /* |
7374c779 |
578 | * Change the label text on a control. |
579 | */ |
580 | void dlg_label_change(union control *ctrl, void *dlg, char const *text); |
581 | /* |
0bd8d76d |
582 | * Return the `ctrl' structure for the most recent control that had |
583 | * the input focus apart from the one mentioned. This is NOT |
584 | * GUARANTEED to work on all platforms, so don't base any critical |
585 | * functionality on it! |
fe8abbf4 |
586 | */ |
0bd8d76d |
587 | union control *dlg_last_focused(union control *ctrl, void *dlg); |
fe8abbf4 |
588 | /* |
589 | * During event processing, you might well want to give an error |
590 | * indication to the user. dlg_beep() is a quick and easy generic |
591 | * error; dlg_error() puts up a message-box or equivalent. |
592 | */ |
593 | void dlg_beep(void *dlg); |
594 | void dlg_error_msg(void *dlg, char *msg); |
595 | /* |
596 | * This function signals to the front end that the dialog's |
597 | * processing is completed, and passes an integer value (typically |
598 | * a success status). |
599 | */ |
600 | void dlg_end(void *dlg, int value); |
601 | |
602 | /* |
603 | * Routines to manage a (per-platform) colour selector. |
604 | * dlg_coloursel_start() is called in an event handler, and |
605 | * schedules the running of a colour selector after the event |
606 | * handler returns. The colour selector will send EVENT_CALLBACK to |
607 | * the control that spawned it, when it's finished; |
608 | * dlg_coloursel_results() fetches the results, as integers from 0 |
609 | * to 255; it returns nonzero on success, or zero if the colour |
610 | * selector was dismissed by hitting Cancel or similar. |
611 | * |
612 | * dlg_coloursel_start() accepts an RGB triple which is used to |
613 | * initialise the colour selector to its starting value. |
614 | */ |
615 | void dlg_coloursel_start(union control *ctrl, void *dlg, |
616 | int r, int g, int b); |
617 | int dlg_coloursel_results(union control *ctrl, void *dlg, |
618 | int *r, int *g, int *b); |
619 | |
620 | /* |
621 | * This routine is used by the platform-independent code to |
622 | * indicate that the value of a particular control is likely to |
623 | * have changed. It triggers a call of the handler for that control |
624 | * with `event' set to EVENT_REFRESH. |
625 | * |
626 | * If `ctrl' is NULL, _all_ controls in the dialog get refreshed |
627 | * (for loading or saving entire sets of settings). |
628 | */ |
629 | void dlg_refresh(union control *ctrl, void *dlg); |
630 | |
631 | /* |
4e6d4091 |
632 | * It's perfectly possible that individual controls might need to |
633 | * allocate or store per-dialog-instance data, so here's a |
634 | * mechanism. |
635 | * |
636 | * `dlg_get_privdata' and `dlg_set_privdata' allow the user to get |
637 | * and set a void * pointer associated with the control in |
638 | * question. `dlg_alloc_privdata' will allocate memory, store a |
639 | * pointer to that memory in the private data field, and arrange |
640 | * for it to be automatically deallocated on dialog cleanup. |
641 | */ |
642 | void *dlg_get_privdata(union control *ctrl, void *dlg); |
643 | void dlg_set_privdata(union control *ctrl, void *dlg, void *ptr); |
644 | void *dlg_alloc_privdata(union control *ctrl, void *dlg, size_t size); |
645 | |
646 | /* |
fe8abbf4 |
647 | * Standard helper functions for reading a controlbox structure. |
648 | */ |
649 | |
650 | /* |
651 | * Find the index of next controlset in a controlbox for a given |
652 | * path, or -1 if no such controlset exists. If -1 is passed as |
653 | * input, finds the first. Intended usage is something like |
654 | * |
655 | * for (index=-1; (index=ctrl_find_path(ctrlbox, index, path)) >= 0 ;) { |
656 | * ... process this controlset ... |
657 | * } |
658 | */ |
659 | int ctrl_find_path(struct controlbox *b, char *path, int index); |
660 | int ctrl_path_elements(char *path); |
661 | /* Return the number of matching path elements at the starts of p1 and p2, |
662 | * or INT_MAX if the paths are identical. */ |
663 | int ctrl_path_compare(char *p1, char *p2); |