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 | /* |
308 | * If this is set, the list can have more than one element |
309 | * selected at a time. This is not guaranteed to work on a |
310 | * drop-down list, so don't try it! |
311 | */ |
312 | int multisel; |
313 | /* |
314 | * Percentage of the dialog-box width used by the list box. |
315 | * If this is set to 100, the label is on its own line; |
316 | * otherwise the label is on the same line as the box |
317 | * itself. Setting this to anything other than 100 is not |
318 | * guaranteed to work on a _non_-drop-down list, so don't |
319 | * try it! |
320 | */ |
321 | int percentwidth; |
322 | /* |
323 | * Some list boxes contain strings that contain tab |
324 | * characters. If `ncols' is greater than 0, then |
325 | * `percentages' is expected to be non-zero and to contain |
326 | * the respective widths of `ncols' columns, which together |
327 | * will exactly fit the width of the list box. Otherwise |
328 | * `percentages' must be NULL. |
329 | */ |
330 | int ncols; /* number of columns */ |
331 | int *percentages; /* % width of each column */ |
332 | } listbox; |
333 | struct { |
334 | STANDARD_PREFIX; |
335 | char shortcut; |
336 | /* |
337 | * `filter' dictates what type of files will be selected by |
338 | * default; for example, when selecting private key files |
339 | * the file selector would do well to only show .PPK files |
340 | * (on those systems where this is the chosen extension). |
341 | * |
342 | * The precise contents of `filter' are platform-defined, |
343 | * unfortunately. The special value NULL means `all files' |
344 | * and is always a valid fallback. |
345 | * |
346 | * Unlike almost all strings in this structure, this value |
347 | * is NOT expected to require freeing (although of course |
348 | * you can always use ctrl_alloc if you do need to create |
349 | * one on the fly). This is because the likely mode of use |
350 | * is to define string constants in a platform-specific |
351 | * header file, and directly reference those. Or worse, a |
352 | * particular platform might choose to cast integers into |
353 | * this pointer type... |
354 | */ |
355 | char const *filter; |
356 | /* |
357 | * Some systems like to know whether a file selector is |
358 | * choosing a file to read or one to write (and possibly |
359 | * create). |
360 | */ |
361 | int for_writing; |
362 | /* |
363 | * On at least some platforms, the file selector is a |
364 | * separate dialog box, and contains a user-settable title. |
365 | * |
366 | * This value _is_ expected to require freeing. |
367 | */ |
368 | char *title; |
369 | } fileselect; |
370 | struct { |
371 | /* In this variant, `label' MUST be NULL. */ |
372 | STANDARD_PREFIX; |
373 | int ncols; /* number of columns */ |
374 | int *percentages; /* % width of each column */ |
375 | /* |
376 | * Every time this control type appears, exactly one of |
377 | * `ncols' and the previous number of columns MUST be one. |
378 | * Attempting to allow a seamless transition from a four- |
379 | * to a five-column layout, for example, would be way more |
380 | * trouble than it was worth. If you must lay things out |
381 | * like that, define eight unevenly sized columns and use |
382 | * column-spanning a lot. But better still, just don't. |
383 | * |
384 | * `percentages' may be NULL if ncols==1, to save space. |
385 | */ |
386 | } columns; |
387 | struct { |
388 | STANDARD_PREFIX; |
389 | char shortcut; |
390 | } fontselect; |
391 | }; |
392 | |
393 | #undef STANDARD_PREFIX |
394 | |
395 | /* |
396 | * `controlset' is a container holding an array of `union control' |
397 | * structures, together with a panel name and a title for the whole |
398 | * set. In Windows and any similar-looking GUI, each `controlset' |
399 | * in the config will be a container box within a panel. |
400 | * |
401 | * Special case: if `boxname' is NULL, the control set gives an |
402 | * overall title for an entire panel of controls. |
403 | */ |
404 | struct controlset { |
405 | char *pathname; /* panel path, e.g. "SSH/Tunnels" */ |
406 | char *boxname; /* internal short name of controlset */ |
407 | char *boxtitle; /* title of container box */ |
408 | int ncolumns; /* current no. of columns at bottom */ |
409 | int ncontrols; /* number of `union control' in array */ |
410 | int ctrlsize; /* allocated size of array */ |
411 | union control **ctrls; /* actual array */ |
412 | }; |
413 | |
414 | /* |
415 | * This is the container structure which holds a complete set of |
416 | * controls. |
417 | */ |
418 | struct controlbox { |
419 | int nctrlsets; /* number of ctrlsets */ |
420 | int ctrlsetsize; /* ctrlset size */ |
421 | struct controlset **ctrlsets; /* actual array of ctrlsets */ |
422 | int nfrees; |
423 | int freesize; |
424 | void **frees; /* array of aux data areas to free */ |
425 | }; |
426 | |
427 | struct controlbox *ctrl_new_box(void); |
428 | void ctrl_free_box(struct controlbox *); |
429 | |
430 | /* |
431 | * Standard functions used for populating a controlbox structure. |
432 | */ |
433 | |
434 | /* Set up a panel title. */ |
435 | struct controlset *ctrl_settitle(struct controlbox *, |
436 | char *path, char *title); |
437 | /* Retrieve a pointer to a controlset, creating it if absent. */ |
438 | struct controlset *ctrl_getset(struct controlbox *, |
439 | char *path, char *name, char *boxtitle); |
440 | void ctrl_free_set(struct controlset *); |
441 | |
442 | void ctrl_free(union control *); |
443 | |
444 | /* |
445 | * This function works like `malloc', but the memory it returns |
446 | * will be automatically freed when the controlbox is freed. Note |
447 | * that a controlbox is a dialog-box _template_, not an instance, |
448 | * and so data allocated through this function is better not used |
449 | * to hold modifiable per-instance things. It's mostly here for |
450 | * allocating structures to be passed as control handler params. |
451 | */ |
452 | void *ctrl_alloc(struct controlbox *b, size_t size); |
453 | |
454 | /* |
455 | * Individual routines to create `union control' structures in a controlset. |
456 | * |
457 | * Most of these routines allow the most common fields to be set |
458 | * directly, and put default values in the rest. Each one returns a |
459 | * pointer to the `union control' it created, so that final tweaks |
460 | * can be made. |
461 | */ |
462 | |
463 | /* `ncolumns' is followed by that many percentages, as integers. */ |
464 | union control *ctrl_columns(struct controlset *, int ncolumns, ...); |
465 | union control *ctrl_editbox(struct controlset *, char *label, char shortcut, |
466 | int percentage, intorptr helpctx, |
467 | handler_fn handler, |
468 | intorptr context, intorptr context2); |
469 | union control *ctrl_combobox(struct controlset *, char *label, char shortcut, |
470 | int percentage, intorptr helpctx, |
471 | handler_fn handler, |
472 | intorptr context, intorptr context2); |
473 | /* |
474 | * `ncolumns' is followed by (alternately) radio button titles and |
475 | * intorptrs, until a NULL in place of a title string is seen. Each |
476 | * title is expected to be followed by a shortcut _iff_ `shortcut' |
477 | * is NO_SHORTCUT. |
478 | */ |
479 | union control *ctrl_radiobuttons(struct controlset *, char *label, |
480 | char shortcut, int ncolumns, |
481 | intorptr helpctx, |
482 | handler_fn handler, intorptr context, ...); |
483 | union control *ctrl_pushbutton(struct controlset *,char *label,char shortcut, |
484 | intorptr helpctx, |
485 | handler_fn handler, intorptr context); |
486 | union control *ctrl_listbox(struct controlset *,char *label,char shortcut, |
487 | intorptr helpctx, |
488 | handler_fn handler, intorptr context); |
489 | union control *ctrl_droplist(struct controlset *, char *label, char shortcut, |
490 | int percentage, intorptr helpctx, |
491 | handler_fn handler, intorptr context); |
492 | union control *ctrl_draglist(struct controlset *,char *label,char shortcut, |
493 | intorptr helpctx, |
494 | handler_fn handler, intorptr context); |
495 | union control *ctrl_filesel(struct controlset *,char *label,char shortcut, |
496 | char const *filter, int write, char *title, |
497 | intorptr helpctx, |
498 | handler_fn handler, intorptr context); |
499 | union control *ctrl_fontsel(struct controlset *,char *label,char shortcut, |
500 | intorptr helpctx, |
501 | handler_fn handler, intorptr context); |
502 | union control *ctrl_text(struct controlset *, char *text, intorptr helpctx); |
503 | union control *ctrl_checkbox(struct controlset *, char *label, char shortcut, |
504 | intorptr helpctx, |
505 | handler_fn handler, intorptr context); |
506 | union control *ctrl_tabdelay(struct controlset *, union control *); |
507 | |
508 | /* |
509 | * Standard handler routines to cover most of the common cases in |
510 | * the config box. |
511 | */ |
512 | /* |
513 | * The standard radio-button handler expects the main `context' |
514 | * field to contain the `offsetof' of an int field in the structure |
515 | * pointed to by `data', and expects each of the individual button |
516 | * data to give a value for that int field. |
517 | */ |
518 | void dlg_stdradiobutton_handler(union control *ctrl, void *dlg, |
519 | void *data, int event); |
520 | /* |
521 | * The standard checkbox handler expects the main `context' field |
522 | * to contain the `offsetof' an int field in the structure pointed |
523 | * to by `data', optionally ORed with CHECKBOX_INVERT to indicate |
524 | * that the sense of the datum is opposite to the sense of the |
525 | * checkbox. |
526 | */ |
527 | #define CHECKBOX_INVERT (1<<30) |
528 | void dlg_stdcheckbox_handler(union control *ctrl, void *dlg, |
529 | void *data, int event); |
530 | /* |
531 | * The standard edit-box handler expects the main `context' field |
532 | * to contain the `offsetof' a field in the structure pointed to by |
533 | * `data'. The secondary `context2' field indicates the type of |
534 | * this field: |
535 | * |
536 | * - if context2 > 0, the field is a char array and context2 gives |
537 | * its size. |
538 | * - if context2 == -1, the field is an int and the edit box is |
539 | * numeric. |
540 | * - if context2 < -1, the field is an int and the edit box is |
541 | * _floating_, and (-context2) gives the scale. (E.g. if |
542 | * context2 == -1000, then typing 1.2 into the box will set the |
543 | * field to 1200.) |
544 | */ |
545 | void dlg_stdeditbox_handler(union control *ctrl, void *dlg, |
546 | void *data, int event); |
547 | /* |
548 | * The standard file-selector handler expects the main `context' |
549 | * field to contain the `offsetof' a Filename field in the |
550 | * structure pointed to by `data'. |
551 | */ |
552 | void dlg_stdfilesel_handler(union control *ctrl, void *dlg, |
553 | void *data, int event); |
554 | /* |
555 | * The standard font-selector handler expects the main `context' |
556 | * field to contain the `offsetof' a Font field in the structure |
557 | * pointed to by `data'. |
558 | */ |
559 | void dlg_stdfontsel_handler(union control *ctrl, void *dlg, |
560 | void *data, int event); |
561 | |
562 | /* |
563 | * Routines the platform-independent dialog code can call to read |
564 | * and write the values of controls. |
565 | */ |
566 | void dlg_radiobutton_set(union control *ctrl, void *dlg, int whichbutton); |
567 | int dlg_radiobutton_get(union control *ctrl, void *dlg); |
568 | void dlg_checkbox_set(union control *ctrl, void *dlg, int checked); |
569 | int dlg_checkbox_get(union control *ctrl, void *dlg); |
570 | void dlg_editbox_set(union control *ctrl, void *dlg, char const *text); |
571 | void dlg_editbox_get(union control *ctrl, void *dlg, char *buffer, int length); |
572 | /* The `listbox' functions can also apply to combo boxes. */ |
573 | void dlg_listbox_clear(union control *ctrl, void *dlg); |
574 | void dlg_listbox_del(union control *ctrl, void *dlg, int index); |
575 | void dlg_listbox_add(union control *ctrl, void *dlg, char const *text); |
576 | /* |
577 | * Each listbox entry may have a numeric id associated with it. |
578 | * Note that some front ends only permit a string to be stored at |
579 | * each position, which means that _if_ you put two identical |
580 | * strings in any listbox then you MUST not assign them different |
581 | * IDs and expect to get meaningful results back. |
582 | */ |
583 | void dlg_listbox_addwithindex(union control *ctrl, void *dlg, |
584 | char const *text, int id); |
585 | int dlg_listbox_getid(union control *ctrl, void *dlg, int index); |
586 | /* dlg_listbox_index returns <0 if no single element is selected. */ |
587 | int dlg_listbox_index(union control *ctrl, void *dlg); |
588 | int dlg_listbox_issel(union control *ctrl, void *dlg, int index); |
589 | void dlg_listbox_select(union control *ctrl, void *dlg, int index); |
590 | void dlg_text_set(union control *ctrl, void *dlg, char const *text); |
591 | void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn); |
592 | void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn); |
593 | void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec fn); |
594 | void dlg_fontsel_get(union control *ctrl, void *dlg, FontSpec *fn); |
595 | /* |
596 | * Bracketing a large set of updates in these two functions will |
597 | * cause the front end (if possible) to delay updating the screen |
598 | * until it's all complete, thus avoiding flicker. |
599 | */ |
600 | void dlg_update_start(union control *ctrl, void *dlg); |
601 | void dlg_update_done(union control *ctrl, void *dlg); |
602 | /* |
603 | * Set input focus into a particular control. |
604 | */ |
605 | void dlg_set_focus(union control *ctrl, void *dlg); |
606 | /* |
0bd8d76d |
607 | * Return the `ctrl' structure for the most recent control that had |
608 | * the input focus apart from the one mentioned. This is NOT |
609 | * GUARANTEED to work on all platforms, so don't base any critical |
610 | * functionality on it! |
fe8abbf4 |
611 | */ |
0bd8d76d |
612 | union control *dlg_last_focused(union control *ctrl, void *dlg); |
fe8abbf4 |
613 | /* |
614 | * During event processing, you might well want to give an error |
615 | * indication to the user. dlg_beep() is a quick and easy generic |
616 | * error; dlg_error() puts up a message-box or equivalent. |
617 | */ |
618 | void dlg_beep(void *dlg); |
619 | void dlg_error_msg(void *dlg, char *msg); |
620 | /* |
621 | * This function signals to the front end that the dialog's |
622 | * processing is completed, and passes an integer value (typically |
623 | * a success status). |
624 | */ |
625 | void dlg_end(void *dlg, int value); |
626 | |
627 | /* |
628 | * Routines to manage a (per-platform) colour selector. |
629 | * dlg_coloursel_start() is called in an event handler, and |
630 | * schedules the running of a colour selector after the event |
631 | * handler returns. The colour selector will send EVENT_CALLBACK to |
632 | * the control that spawned it, when it's finished; |
633 | * dlg_coloursel_results() fetches the results, as integers from 0 |
634 | * to 255; it returns nonzero on success, or zero if the colour |
635 | * selector was dismissed by hitting Cancel or similar. |
636 | * |
637 | * dlg_coloursel_start() accepts an RGB triple which is used to |
638 | * initialise the colour selector to its starting value. |
639 | */ |
640 | void dlg_coloursel_start(union control *ctrl, void *dlg, |
641 | int r, int g, int b); |
642 | int dlg_coloursel_results(union control *ctrl, void *dlg, |
643 | int *r, int *g, int *b); |
644 | |
645 | /* |
646 | * This routine is used by the platform-independent code to |
647 | * indicate that the value of a particular control is likely to |
648 | * have changed. It triggers a call of the handler for that control |
649 | * with `event' set to EVENT_REFRESH. |
650 | * |
651 | * If `ctrl' is NULL, _all_ controls in the dialog get refreshed |
652 | * (for loading or saving entire sets of settings). |
653 | */ |
654 | void dlg_refresh(union control *ctrl, void *dlg); |
655 | |
656 | /* |
4e6d4091 |
657 | * It's perfectly possible that individual controls might need to |
658 | * allocate or store per-dialog-instance data, so here's a |
659 | * mechanism. |
660 | * |
661 | * `dlg_get_privdata' and `dlg_set_privdata' allow the user to get |
662 | * and set a void * pointer associated with the control in |
663 | * question. `dlg_alloc_privdata' will allocate memory, store a |
664 | * pointer to that memory in the private data field, and arrange |
665 | * for it to be automatically deallocated on dialog cleanup. |
666 | */ |
667 | void *dlg_get_privdata(union control *ctrl, void *dlg); |
668 | void dlg_set_privdata(union control *ctrl, void *dlg, void *ptr); |
669 | void *dlg_alloc_privdata(union control *ctrl, void *dlg, size_t size); |
670 | |
671 | /* |
fe8abbf4 |
672 | * Standard helper functions for reading a controlbox structure. |
673 | */ |
674 | |
675 | /* |
676 | * Find the index of next controlset in a controlbox for a given |
677 | * path, or -1 if no such controlset exists. If -1 is passed as |
678 | * input, finds the first. Intended usage is something like |
679 | * |
680 | * for (index=-1; (index=ctrl_find_path(ctrlbox, index, path)) >= 0 ;) { |
681 | * ... process this controlset ... |
682 | * } |
683 | */ |
684 | int ctrl_find_path(struct controlbox *b, char *path, int index); |
685 | int ctrl_path_elements(char *path); |
686 | /* Return the number of matching path elements at the starts of p1 and p2, |
687 | * or INT_MAX if the paths are identical. */ |
688 | int ctrl_path_compare(char *p1, char *p2); |