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 |
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; |
0bd8d76d |
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; |
fe8abbf4 |
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 | /* |
8eed910d |
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. |
fe8abbf4 |
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 | */ |
4eaff8d4 |
590 | void dlg_listbox_addwithid(union control *ctrl, void *dlg, |
591 | char const *text, int id); |
fe8abbf4 |
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 | /* |
0bd8d76d |
614 | * Return the `ctrl' structure for the most recent control that had |
615 | * the input focus apart from the one mentioned. This is NOT |
616 | * GUARANTEED to work on all platforms, so don't base any critical |
617 | * functionality on it! |
fe8abbf4 |
618 | */ |
0bd8d76d |
619 | union control *dlg_last_focused(union control *ctrl, void *dlg); |
fe8abbf4 |
620 | /* |
621 | * During event processing, you might well want to give an error |
622 | * indication to the user. dlg_beep() is a quick and easy generic |
623 | * error; dlg_error() puts up a message-box or equivalent. |
624 | */ |
625 | void dlg_beep(void *dlg); |
626 | void dlg_error_msg(void *dlg, char *msg); |
627 | /* |
628 | * This function signals to the front end that the dialog's |
629 | * processing is completed, and passes an integer value (typically |
630 | * a success status). |
631 | */ |
632 | void dlg_end(void *dlg, int value); |
633 | |
634 | /* |
635 | * Routines to manage a (per-platform) colour selector. |
636 | * dlg_coloursel_start() is called in an event handler, and |
637 | * schedules the running of a colour selector after the event |
638 | * handler returns. The colour selector will send EVENT_CALLBACK to |
639 | * the control that spawned it, when it's finished; |
640 | * dlg_coloursel_results() fetches the results, as integers from 0 |
641 | * to 255; it returns nonzero on success, or zero if the colour |
642 | * selector was dismissed by hitting Cancel or similar. |
643 | * |
644 | * dlg_coloursel_start() accepts an RGB triple which is used to |
645 | * initialise the colour selector to its starting value. |
646 | */ |
647 | void dlg_coloursel_start(union control *ctrl, void *dlg, |
648 | int r, int g, int b); |
649 | int dlg_coloursel_results(union control *ctrl, void *dlg, |
650 | int *r, int *g, int *b); |
651 | |
652 | /* |
653 | * This routine is used by the platform-independent code to |
654 | * indicate that the value of a particular control is likely to |
655 | * have changed. It triggers a call of the handler for that control |
656 | * with `event' set to EVENT_REFRESH. |
657 | * |
658 | * If `ctrl' is NULL, _all_ controls in the dialog get refreshed |
659 | * (for loading or saving entire sets of settings). |
660 | */ |
661 | void dlg_refresh(union control *ctrl, void *dlg); |
662 | |
663 | /* |
4e6d4091 |
664 | * It's perfectly possible that individual controls might need to |
665 | * allocate or store per-dialog-instance data, so here's a |
666 | * mechanism. |
667 | * |
668 | * `dlg_get_privdata' and `dlg_set_privdata' allow the user to get |
669 | * and set a void * pointer associated with the control in |
670 | * question. `dlg_alloc_privdata' will allocate memory, store a |
671 | * pointer to that memory in the private data field, and arrange |
672 | * for it to be automatically deallocated on dialog cleanup. |
673 | */ |
674 | void *dlg_get_privdata(union control *ctrl, void *dlg); |
675 | void dlg_set_privdata(union control *ctrl, void *dlg, void *ptr); |
676 | void *dlg_alloc_privdata(union control *ctrl, void *dlg, size_t size); |
677 | |
678 | /* |
fe8abbf4 |
679 | * Standard helper functions for reading a controlbox structure. |
680 | */ |
681 | |
682 | /* |
683 | * Find the index of next controlset in a controlbox for a given |
684 | * path, or -1 if no such controlset exists. If -1 is passed as |
685 | * input, finds the first. Intended usage is something like |
686 | * |
687 | * for (index=-1; (index=ctrl_find_path(ctrlbox, index, path)) >= 0 ;) { |
688 | * ... process this controlset ... |
689 | * } |
690 | */ |
691 | int ctrl_find_path(struct controlbox *b, char *path, int index); |
692 | int ctrl_path_elements(char *path); |
693 | /* Return the number of matching path elements at the starts of p1 and p2, |
694 | * or INT_MAX if the paths are identical. */ |
695 | int ctrl_path_compare(char *p1, char *p2); |