Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mRemoteNG/PuTTYNG.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'dialog.h')
-rw-r--r--dialog.h792
1 files changed, 411 insertions, 381 deletions
diff --git a/dialog.h b/dialog.h
index 86ebfc20..ef9a9dfe 100644
--- a/dialog.h
+++ b/dialog.h
@@ -43,11 +43,12 @@ enum {
* included with DEFINE_INTORPTR_FNS defined. This is a total pain,
* but such is life.
*/
-typedef union { void *p; int i; } intorptr;
+typedef union { void *p; const void *cp; int i; } intorptr;
#ifndef INLINE
intorptr I(int i);
intorptr P(void *p);
+intorptr CP(const void *p);
#endif
#if defined DEFINE_INTORPTR_FNS || defined INLINE
@@ -58,6 +59,7 @@ intorptr P(void *p);
#endif
PREFIX intorptr I(int i) { intorptr ret; ret.i = i; return ret; }
PREFIX intorptr P(void *p) { intorptr ret; ret.p = p; return ret; }
+PREFIX intorptr CP(const void *p) { intorptr ret; ret.cp = p; return ret; }
#undef PREFIX
#endif
@@ -73,8 +75,6 @@ PREFIX intorptr P(void *p) { intorptr ret; ret.p = p; return ret; }
#define COLUMN_START(field) ( (field) & 0xFFFF )
#define COLUMN_SPAN(field) ( (((field) >> 16) & 0xFFFF) + 1 )
-union control;
-
/*
* The number of event types is being deliberately kept small, on
* the grounds that not all platforms might be able to report a
@@ -103,326 +103,346 @@ enum {
EVENT_SELCHANGE,
EVENT_CALLBACK
};
-typedef void (*handler_fn)(union control *ctrl, dlgparam *dp,
+typedef void (*handler_fn)(dlgcontrol *ctrl, dlgparam *dp,
void *data, int event);
-#define STANDARD_PREFIX \
- int type; \
- char *label; \
- bool tabdelay; \
- int column; \
- handler_fn handler; \
- intorptr context; \
- intorptr helpctx; \
- union control *align_next_to
+struct dlgcontrol {
+ /*
+ * Generic fields shared by all the control types.
+ */
+ int type;
+ /*
+ * Every control except CTRL_COLUMNS has _some_ sort of label. By
+ * putting it in the `generic' union as well as everywhere else,
+ * we avoid having to have an irritating switch statement when we
+ * go through and deallocate all the memory in a config-box
+ * structure.
+ *
+ * Yes, this does mean that any non-NULL value in this field is
+ * expected to be dynamically allocated and freeable.
+ *
+ * For CTRL_COLUMNS, this field MUST be NULL.
+ */
+ char *label;
+ /*
+ * If `delay_taborder' is true, it indicates that this particular
+ * control should not yet appear in the tab order. A subsequent
+ * CTRL_TABDELAY entry will place it.
+ */
+ bool delay_taborder;
+ /*
+ * Indicate which column(s) this control occupies. This can be
+ * unpacked into starting column and column span by the COLUMN
+ * macros above.
+ */
+ int column;
+ /*
+ * Most controls need to provide a function which gets called when
+ * that control's setting is changed, or when the control's
+ * setting needs initialising.
+ *
+ * The `data' parameter points to the writable data being modified
+ * as a result of the configuration activity; for example, the
+ * PuTTY `Conf' structure, although not necessarily.
+ *
+ * The `dlg' parameter is passed back to the platform- specific
+ * routines to read and write the actual control state.
+ */
+ handler_fn handler;
+ /*
+ * Almost all of the above functions will find it useful to be
+ * able to store one or two pieces of `void *' or `int' data.
+ */
+ intorptr context, context2;
+ /*
+ * For any control, we also allow the storage of a piece of data
+ * for use by context-sensitive help. For example, on Windows you
+ * can click the magic question mark and then click a control, and
+ * help for that control should spring up. Hence, here is a slot
+ * in which to store per-control data that a particular
+ * platform-specific driver can use to ensure it brings up the
+ * right piece of help text.
+ */
+ HelpCtx helpctx;
+ /*
+ * Setting this to non-NULL coerces two or more controls to have
+ * their y-coordinates adjusted so that they can sit alongside
+ * each other and look nicely aligned, even if they're different
+ * heights.
+ *
+ * Set this field on later controls (in terms of order in the data
+ * structure), pointing back to earlier ones, so that when each
+ * control is instantiated, the referred-to one is already there
+ * to be referred to.
+ *
+ * Don't expect this to change the position of the _first_
+ * control. Currently, the layout is done one control at a time,
+ * so that once the first control has been placed, the second one
+ * can't cause the first one to be retrospectively moved.
+ */
+ dlgcontrol *align_next_to;
-union control {
/*
- * The first possibility in this union is the generic header
- * shared by all the structures, which we are therefore allowed
- * to access through any one of them.
+ * Union of further fields specific to each control type.
*/
- struct {
- int type;
- /*
- * Every control except CTRL_COLUMNS has _some_ sort of
- * label. By putting it in the `generic' union as well as
- * everywhere else, we avoid having to have an irritating
- * switch statement when we go through and deallocate all
- * the memory in a config-box structure.
- *
- * Yes, this does mean that any non-NULL value in this
- * field is expected to be dynamically allocated and
- * freeable.
- *
- * For CTRL_COLUMNS, this field MUST be NULL.
- */
- char *label;
- /*
- * If `tabdelay' is non-zero, it indicates that this
- * particular control should not yet appear in the tab
- * order. A subsequent CTRL_TABDELAY entry will place it.
- */
- bool tabdelay;
- /*
- * Indicate which column(s) this control occupies. This can
- * be unpacked into starting column and column span by the
- * COLUMN macros above.
- */
- int column;
- /*
- * Most controls need to provide a function which gets
- * called when that control's setting is changed, or when
- * the control's setting needs initialising.
- *
- * The `data' parameter points to the writable data being
- * modified as a result of the configuration activity; for
- * example, the PuTTY `Conf' structure, although not
- * necessarily.
- *
- * The `dlg' parameter is passed back to the platform-
- * specific routines to read and write the actual control
- * state.
- */
- handler_fn handler;
- /*
- * Almost all of the above functions will find it useful to
- * be able to store a piece of `void *' or `int' data.
- */
- intorptr context;
- /*
- * For any control, we also allow the storage of a piece of
- * data for use by context-sensitive help. For example, on
- * Windows you can click the magic question mark and then
- * click a control, and help for that control should spring
- * up. Hence, here is a slot in which to store per-control
- * data that a particular platform-specific driver can use
- * to ensure it brings up the right piece of help text.
- */
- intorptr helpctx;
- /*
- * Setting this to non-NULL coerces two controls to have their
- * y-coordinates adjusted so that they can sit alongside each
- * other and look nicely aligned, even if they're different
- * heights.
- *
- * Set this field on the _second_ control of the pair (in
- * terms of order in the data structure), so that when it's
- * instantiated, the first one is already there to be referred
- * to.
- */
- union control *align_next_to;
- } generic;
- struct {
- STANDARD_PREFIX;
- union control *ctrl;
- } tabdelay;
- struct {
- STANDARD_PREFIX;
- } text;
- struct {
- STANDARD_PREFIX;
- char shortcut; /* keyboard shortcut */
- /*
- * Percentage of the dialog-box width used by the edit box.
- * If this is set to 100, the label is on its own line;
- * otherwise the label is on the same line as the box
- * itself.
- */
- int percentwidth;
- bool password; /* details of input are hidden */
- /*
- * A special case of the edit box is the combo box, which
- * has a drop-down list built in. (Note that a _non_-
- * editable drop-down list is done as a special case of a
- * list box.)
- *
- * Don't try setting has_list and password on the same
- * control; front ends are not required to support that
- * combination.
- */
- bool has_list;
- /*
- * Edit boxes tend to need two items of context, so here's
- * a spare.
- */
- intorptr context2;
- } editbox;
- struct {
- STANDARD_PREFIX;
- /*
- * `shortcut' here is a single keyboard shortcut which is
- * expected to select the whole group of radio buttons. It
- * can be NO_SHORTCUT if required, and there is also a way
- * to place individual shortcuts on each button; see below.
- */
- char shortcut;
- /*
- * There are separate fields for `ncolumns' and `nbuttons'
- * for several reasons.
- *
- * Firstly, we sometimes want the last of a set of buttons
- * to have a longer label than the rest; we achieve this by
- * setting `ncolumns' higher than `nbuttons', and the
- * layout code is expected to understand that the final
- * button should be given all the remaining space on the
- * line. This sounds like a ludicrously specific special
- * case (if we're doing this sort of thing, why not have
- * the general ability to have a particular button span
- * more than one column whether it's the last one or not?)
- * but actually it's reasonably common for the sort of
- * three-way control you get a lot of in PuTTY: `yes'
- * versus `no' versus `some more complex way to decide'.
- *
- * Secondly, setting `nbuttons' higher than `ncolumns' lets
- * us have more than one line of radio buttons for a single
- * setting. A very important special case of this is
- * setting `ncolumns' to 1, so that each button is on its
- * own line.
- */
- int ncolumns;
- int nbuttons;
- /*
- * This points to a dynamically allocated array of `char *'
- * pointers, each of which points to a dynamically
- * allocated string.
- */
- char **buttons; /* `nbuttons' button labels */
- /*
- * This points to a dynamically allocated array of `char'
- * giving the individual keyboard shortcuts for each radio
- * button. The array may be NULL if none are required.
- */
- char *shortcuts; /* `nbuttons' shortcuts; may be NULL */
- /*
- * This points to a dynamically allocated array of
- * intorptr, giving helpful data for each button.
- */
- intorptr *buttondata; /* `nbuttons' entries; may be NULL */
- } radio;
- struct {
- STANDARD_PREFIX;
- char shortcut;
- } checkbox;
- struct {
- STANDARD_PREFIX;
- char shortcut;
- /*
- * At least Windows has the concept of a `default push
- * button', which gets implicitly pressed when you hit
- * Return even if it doesn't have the input focus.
- */
- bool isdefault;
- /*
- * Also, the reverse of this: a default cancel-type button,
- * which is implicitly pressed when you hit Escape.
- */
- bool iscancel;
- } button;
- struct {
- STANDARD_PREFIX;
- char shortcut; /* keyboard shortcut */
- /*
- * Height of the list box, in approximate number of lines.
- * If this is zero, the list is a drop-down list.
- */
- int height; /* height in lines */
- /*
- * If this is set, the list elements can be reordered by
- * the user (by drag-and-drop or by Up and Down buttons,
- * whatever the per-platform implementation feels
- * comfortable with). This is not guaranteed to work on a
- * drop-down list, so don't try it!
- */
- bool draglist;
- /*
- * If this is non-zero, the list can have more than one
- * element selected at a time. This is not guaranteed to
- * work on a drop-down list, so don't try it!
- *
- * Different non-zero values request slightly different
- * types of multi-selection (this may well be meaningful
- * only in GTK, so everyone else can ignore it if they
- * want). 1 means the list box expects to have individual
- * items selected, whereas 2 means it expects the user to
- * want to select a large contiguous range at a time.
- */
- int multisel;
- /*
- * Percentage of the dialog-box width used by the list box.
- * If this is set to 100, the label is on its own line;
- * otherwise the label is on the same line as the box
- * itself. Setting this to anything other than 100 is not
- * guaranteed to work on a _non_-drop-down list, so don't
- * try it!
- */
- int percentwidth;
- /*
- * Some list boxes contain strings that contain tab
- * characters. If `ncols' is greater than 0, then
- * `percentages' is expected to be non-zero and to contain
- * the respective widths of `ncols' columns, which together
- * will exactly fit the width of the list box. Otherwise
- * `percentages' must be NULL.
- *
- * There should never be more than one column in a
- * drop-down list (one with height==0), because front ends
- * may have to implement it as a special case of an
- * editable combo box.
- */
- int ncols; /* number of columns */
- int *percentages; /* % width of each column */
- /*
- * Flag which can be set to false to suppress the horizontal
- * scroll bar if a list box entry goes off the right-hand
- * side.
- */
- bool hscroll;
- } listbox;
- struct {
- STANDARD_PREFIX;
- char shortcut;
- /*
- * `filter' dictates what type of files will be selected by
- * default; for example, when selecting private key files
- * the file selector would do well to only show .PPK files
- * (on those systems where this is the chosen extension).
- *
- * The precise contents of `filter' are platform-defined,
- * unfortunately. The special value NULL means `all files'
- * and is always a valid fallback.
- *
- * Unlike almost all strings in this structure, this value
- * is NOT expected to require freeing (although of course
- * you can always use ctrl_alloc if you do need to create
- * one on the fly). This is because the likely mode of use
- * is to define string constants in a platform-specific
- * header file, and directly reference those. Or worse, a
- * particular platform might choose to cast integers into
- * this pointer type...
- */
- char const *filter;
- /*
- * Some systems like to know whether a file selector is
- * choosing a file to read or one to write (and possibly
- * create).
- */
- bool for_writing;
- /*
- * On at least some platforms, the file selector is a
- * separate dialog box, and contains a user-settable title.
- *
- * This value _is_ expected to require freeing.
- */
- char *title;
- } fileselect;
- struct {
- /* In this variant, `label' MUST be NULL. */
- STANDARD_PREFIX;
- int ncols; /* number of columns */
- int *percentages; /* % width of each column */
- /*
- * Every time this control type appears, exactly one of
- * `ncols' and the previous number of columns MUST be one.
- * Attempting to allow a seamless transition from a four-
- * to a five-column layout, for example, would be way more
- * trouble than it was worth. If you must lay things out
- * like that, define eight unevenly sized columns and use
- * column-spanning a lot. But better still, just don't.
- *
- * `percentages' may be NULL if ncols==1, to save space.
- */
- } columns;
- struct {
- STANDARD_PREFIX;
- char shortcut;
- } fontselect;
+ union {
+ struct { /* for CTRL_TABDELAY */
+ dlgcontrol *ctrl;
+ } tabdelay;
+ struct { /* for CTRL_EDITBOX */
+ char shortcut; /* keyboard shortcut */
+ /*
+ * Percentage of the dialog-box width used by the edit
+ * box. If this is set to 100, the label is on its own
+ * line; otherwise the label is on the same line as the
+ * box itself.
+ */
+ int percentwidth;
+ bool password; /* details of input are hidden */
+ /*
+ * A special case of the edit box is the combo box, which
+ * has a drop-down list built in. (Note that a _non_-
+ * editable drop-down list is done as a special case of a
+ * list box.)
+ *
+ * Don't try setting has_list and password on the same
+ * control; front ends are not required to support that
+ * combination.
+ */
+ bool has_list;
+ } editbox;
+ struct { /* for CTRL_RADIO */
+ /*
+ * `shortcut' here is a single keyboard shortcut which is
+ * expected to select the whole group of radio buttons. It
+ * can be NO_SHORTCUT if required, and there is also a way
+ * to place individual shortcuts on each button; see
+ * below.
+ */
+ char shortcut;
+ /*
+ * There are separate fields for `ncolumns' and `nbuttons'
+ * for several reasons.
+ *
+ * Firstly, we sometimes want the last of a set of buttons
+ * to have a longer label than the rest; we achieve this
+ * by setting `ncolumns' higher than `nbuttons', and the
+ * layout code is expected to understand that the final
+ * button should be given all the remaining space on the
+ * line. This sounds like a ludicrously specific special
+ * case (if we're doing this sort of thing, why not have
+ * the general ability to have a particular button span
+ * more than one column whether it's the last one or not?)
+ * but actually it's reasonably common for the sort of
+ * three-way control you get a lot of in PuTTY: `yes'
+ * versus `no' versus `some more complex way to decide'.
+ *
+ * Secondly, setting `nbuttons' higher than `ncolumns'
+ * lets us have more than one line of radio buttons for a
+ * single setting. A very important special case of this
+ * is setting `ncolumns' to 1, so that each button is on
+ * its own line.
+ */
+ int ncolumns;
+ int nbuttons;
+ /*
+ * This points to a dynamically allocated array of `char *'
+ * pointers, each of which points to a dynamically
+ * allocated string.
+ */
+ char **buttons; /* `nbuttons' button labels */
+ /*
+ * This points to a dynamically allocated array of `char'
+ * giving the individual keyboard shortcuts for each radio
+ * button. The array may be NULL if none are required.
+ */
+ char *shortcuts; /* `nbuttons' shortcuts; may be NULL */
+ /*
+ * This points to a dynamically allocated array of
+ * intorptr, giving helpful data for each button.
+ */
+ intorptr *buttondata; /* `nbuttons' entries; may be NULL */
+ } radio;
+ struct { /* for CTRL_CHECKBOX */
+ char shortcut;
+ } checkbox;
+ struct { /* for CTRL_BUTTON */
+ char shortcut;
+ /*
+ * At least Windows has the concept of a `default push
+ * button', which gets implicitly pressed when you hit
+ * Return even if it doesn't have the input focus.
+ */
+ bool isdefault;
+ /*
+ * Also, the reverse of this: a default cancel-type
+ * button, which is implicitly pressed when you hit
+ * Escape.
+ */
+ bool iscancel;
+ } button;
+ struct { /* for CTRL_LISTBOX */
+ char shortcut; /* keyboard shortcut */
+ /*
+ * Height of the list box, in approximate number of lines.
+ * If this is zero, the list is a drop-down list.
+ */
+ int height; /* height in lines */
+ /*
+ * If this is set, the list elements can be reordered by
+ * the user (by drag-and-drop or by Up and Down buttons,
+ * whatever the per-platform implementation feels
+ * comfortable with). This is not guaranteed to work on a
+ * drop-down list, so don't try it!
+ */
+ bool draglist;
+ /*
+ * If this is non-zero, the list can have more than one
+ * element selected at a time. This is not guaranteed to
+ * work on a drop-down list, so don't try it!
+ *
+ * Different non-zero values request slightly different
+ * types of multi-selection (this may well be meaningful
+ * only in GTK, so everyone else can ignore it if they
+ * want). 1 means the list box expects to have individual
+ * items selected, whereas 2 means it expects the user to
+ * want to select a large contiguous range at a time.
+ */
+ int multisel;
+ /*
+ * Percentage of the dialog-box width used by the list
+ * box. If this is set to 100, the label is on its own
+ * line; otherwise the label is on the same line as the
+ * box itself. Setting this to anything other than 100 is
+ * not guaranteed to work on a _non_-drop-down list, so
+ * don't try it!
+ */
+ int percentwidth;
+ /*
+ * Some list boxes contain strings that contain tab
+ * characters. If `ncols' is greater than 0, then
+ * `percentages' is expected to be non-zero and to contain
+ * the respective widths of `ncols' columns, which
+ * together will exactly fit the width of the list box.
+ * Otherwise `percentages' must be NULL.
+ *
+ * There should never be more than one column in a
+ * drop-down list (one with height==0), because front ends
+ * may have to implement it as a special case of an
+ * editable combo box.
+ */
+ int ncols; /* number of columns */
+ int *percentages; /* % width of each column */
+ /*
+ * Flag which can be set to false to suppress the
+ * horizontal scroll bar if a list box entry goes off the
+ * right-hand side.
+ */
+ bool hscroll;
+ } listbox;
+ struct { /* for CTRL_FILESELECT */
+ char shortcut;
+ /*
+ * `filter' dictates what type of files will be selected
+ * by default; for example, when selecting private key
+ * files the file selector would do well to only show .PPK
+ * files (on those systems where this is the chosen
+ * extension).
+ *
+ * The precise contents of `filter' are platform-defined,
+ * unfortunately. The special value NULL means `all files'
+ * and is always a valid fallback.
+ *
+ * Unlike almost all strings in this structure, this value
+ * is NOT expected to require freeing (although of course
+ * you can always use ctrl_alloc if you do need to create
+ * one on the fly). This is because the likely mode of use
+ * is to define string constants in a platform-specific
+ * header file, and directly reference those. Or worse, a
+ * particular platform might choose to cast integers into
+ * this pointer type...
+ */
+ char const *filter;
+ /*
+ * Some systems like to know whether a file selector is
+ * choosing a file to read or one to write (and possibly
+ * create).
+ */
+ bool for_writing;
+ /*
+ * On at least some platforms, the file selector is a
+ * separate dialog box, and contains a user-settable
+ * title.
+ *
+ * This value _is_ expected to require freeing.
+ */
+ char *title;
+ /*
+ * Reduce the file selector to just a single browse
+ * button.
+ *
+ * Normally, a file selector is used to set a config
+ * option that consists of a file name, so that that file
+ * will be read or written at run time. In that situation,
+ * it makes sense to have an edit box showing the
+ * currently selected file name, and a button to change it
+ * interactively.
+ *
+ * But occasionally a file selector is used to load a file
+ * _during_ configuration. For example, host CA public
+ * keys are entered directly into the configuration as
+ * strings, not stored by reference to a filename; but if
+ * you have one in a file, you want to be able to load it
+ * during the lifetime of the CA config box rather than
+ * awkwardly copy-pasting it. So in that case you just
+ * want a 'pop up a file chooser' button, and when that
+ * delivers a file name, you'll deal with it there and
+ * then and write some other thing (like the file's
+ * contents) into a nearby edit box.
+ *
+ * If you set this flag, then you may not call
+ * dlg_filesel_set on the file selector at all, because it
+ * doesn't store a filename. And you can only call
+ * dlg_filesel_get on it in the handler for EVENT_ACTION,
+ * which is what will be sent to you when the user has
+ * used it to choose a filename.
+ */
+ bool just_button;
+ } fileselect;
+ struct { /* for CTRL_COLUMNS */
+ /* In this variant, `label' MUST be NULL. */
+ int ncols; /* number of columns */
+ int *percentages; /* % width of each column */
+ /*
+ * Every time this control type appears, exactly one of
+ * `ncols' and the previous number of columns MUST be one.
+ * Attempting to allow a seamless transition from a four-
+ * to a five-column layout, for example, would be way more
+ * trouble than it was worth. If you must lay things out
+ * like that, define eight unevenly sized columns and use
+ * column-spanning a lot. But better still, just don't.
+ *
+ * `percentages' may be NULL if ncols==1, to save space.
+ */
+ } columns;
+ struct { /* for CTRL_FONTSELECT */
+ char shortcut;
+ } fontselect;
+ struct { /* for CTRL_TEXT */
+ /*
+ * If this is true (the default), the text will wrap on to
+ * multiple lines. If false, it will stay on the same
+ * line, with a horizontal scrollbar if necessary.
+ */
+ bool wrap;
+ } text;
+ };
};
#undef STANDARD_PREFIX
/*
- * `controlset' is a container holding an array of `union control'
+ * `controlset' is a container holding an array of `dlgcontrol'
* structures, together with a panel name and a title for the whole
* set. In Windows and any similar-looking GUI, each `controlset'
* in the config will be a container box within a panel.
@@ -435,9 +455,9 @@ struct controlset {
char *boxname; /* internal short name of controlset */
char *boxtitle; /* title of container box */
int ncolumns; /* current no. of columns at bottom */
- size_t ncontrols; /* number of `union control' in array */
+ size_t ncontrols; /* number of `dlgcontrol' in array */
size_t ctrlsize; /* allocated size of array */
- union control **ctrls; /* actual array */
+ dlgcontrol **ctrls; /* actual array */
};
typedef void (*ctrl_freefn_t)(void *); /* used by ctrl_alloc_with_free */
@@ -471,7 +491,7 @@ struct controlset *ctrl_getset(struct controlbox *, const char *path,
const char *name, const char *boxtitle);
void ctrl_free_set(struct controlset *);
-void ctrl_free(union control *);
+void ctrl_free(dlgcontrol *);
/*
* This function works like `malloc', but the memory it returns
@@ -490,73 +510,77 @@ void *ctrl_alloc_with_free(struct controlbox *b, size_t size,
ctrl_freefn_t freefunc);
/*
- * Individual routines to create `union control' structures in a controlset.
+ * Individual routines to create `dlgcontrol' structures in a controlset.
*
* Most of these routines allow the most common fields to be set
* directly, and put default values in the rest. Each one returns a
- * pointer to the `union control' it created, so that final tweaks
+ * pointer to the `dlgcontrol' it created, so that final tweaks
* can be made.
*/
/* `ncolumns' is followed by that many percentages, as integers. */
-union control *ctrl_columns(struct controlset *, int ncolumns, ...);
-union control *ctrl_editbox(struct controlset *, const char *label,
- char shortcut, int percentage, intorptr helpctx,
- handler_fn handler,
- intorptr context, intorptr context2);
-union control *ctrl_combobox(struct controlset *, const char *label,
- char shortcut, int percentage, intorptr helpctx,
- handler_fn handler,
- intorptr context, intorptr context2);
+dlgcontrol *ctrl_columns(struct controlset *, int ncolumns, ...);
+dlgcontrol *ctrl_editbox(struct controlset *, const char *label,
+ char shortcut, int percentage, HelpCtx helpctx,
+ handler_fn handler,
+ intorptr context, intorptr context2);
+dlgcontrol *ctrl_combobox(struct controlset *, const char *label,
+ char shortcut, int percentage, HelpCtx helpctx,
+ handler_fn handler,
+ intorptr context, intorptr context2);
/*
* `ncolumns' is followed by (alternately) radio button titles and
* intorptrs, until a NULL in place of a title string is seen. Each
* title is expected to be followed by a shortcut _iff_ `shortcut'
* is NO_SHORTCUT.
*/
-union control *ctrl_radiobuttons(struct controlset *, const char *label,
- char shortcut, int ncolumns, intorptr helpctx,
+dlgcontrol *ctrl_radiobuttons_fn(struct controlset *, const char *label,
+ char shortcut, int ncolumns, HelpCtx helpctx,
handler_fn handler, intorptr context, ...);
-union control *ctrl_pushbutton(struct controlset *, const char *label,
- char shortcut, intorptr helpctx,
- handler_fn handler, intorptr context);
-union control *ctrl_listbox(struct controlset *, const char *label,
- char shortcut, intorptr helpctx,
+#define ctrl_radiobuttons(...) \
+ ctrl_radiobuttons_fn(__VA_ARGS__, (const char *)NULL)
+dlgcontrol *ctrl_pushbutton(struct controlset *, const char *label,
+ char shortcut, HelpCtx helpctx,
handler_fn handler, intorptr context);
-union control *ctrl_droplist(struct controlset *, const char *label,
- char shortcut, int percentage, intorptr helpctx,
- handler_fn handler, intorptr context);
-union control *ctrl_draglist(struct controlset *, const char *label,
- char shortcut, intorptr helpctx,
- handler_fn handler, intorptr context);
-union control *ctrl_filesel(struct controlset *, const char *label,
- char shortcut, const char *filter, bool write,
- const char *title, intorptr helpctx,
- handler_fn handler, intorptr context);
-union control *ctrl_fontsel(struct controlset *, const char *label,
- char shortcut, intorptr helpctx,
- handler_fn handler, intorptr context);
-union control *ctrl_text(struct controlset *, const char *text,
- intorptr helpctx);
-union control *ctrl_checkbox(struct controlset *, const char *label,
- char shortcut, intorptr helpctx,
- handler_fn handler, intorptr context);
-union control *ctrl_tabdelay(struct controlset *, union control *);
+dlgcontrol *ctrl_listbox(struct controlset *, const char *label,
+ char shortcut, HelpCtx helpctx,
+ handler_fn handler, intorptr context);
+dlgcontrol *ctrl_droplist(struct controlset *, const char *label,
+ char shortcut, int percentage, HelpCtx helpctx,
+ handler_fn handler, intorptr context);
+dlgcontrol *ctrl_draglist(struct controlset *, const char *label,
+ char shortcut, HelpCtx helpctx,
+ handler_fn handler, intorptr context);
+dlgcontrol *ctrl_filesel(struct controlset *, const char *label,
+ char shortcut, const char *filter, bool write,
+ const char *title, HelpCtx helpctx,
+ handler_fn handler, intorptr context);
+dlgcontrol *ctrl_fontsel(struct controlset *, const char *label,
+ char shortcut, HelpCtx helpctx,
+ handler_fn handler, intorptr context);
+dlgcontrol *ctrl_text(struct controlset *, const char *text,
+ HelpCtx helpctx);
+dlgcontrol *ctrl_checkbox(struct controlset *, const char *label,
+ char shortcut, HelpCtx helpctx,
+ handler_fn handler, intorptr context);
+dlgcontrol *ctrl_tabdelay(struct controlset *, dlgcontrol *);
/*
* Routines the platform-independent dialog code can call to read
* and write the values of controls.
*/
-void dlg_radiobutton_set(union control *ctrl, dlgparam *dp, int whichbutton);
-int dlg_radiobutton_get(union control *ctrl, dlgparam *dp);
-void dlg_checkbox_set(union control *ctrl, dlgparam *dp, bool checked);
-bool dlg_checkbox_get(union control *ctrl, dlgparam *dp);
-void dlg_editbox_set(union control *ctrl, dlgparam *dp, char const *text);
-char *dlg_editbox_get(union control *ctrl, dlgparam *dp); /* result must be freed by caller */
+void dlg_radiobutton_set(dlgcontrol *ctrl, dlgparam *dp, int whichbutton);
+int dlg_radiobutton_get(dlgcontrol *ctrl, dlgparam *dp);
+void dlg_checkbox_set(dlgcontrol *ctrl, dlgparam *dp, bool checked);
+bool dlg_checkbox_get(dlgcontrol *ctrl, dlgparam *dp);
+void dlg_editbox_set(dlgcontrol *ctrl, dlgparam *dp, char const *text);
+char *dlg_editbox_get(dlgcontrol *ctrl, dlgparam *dp); /* result must be freed by caller */
+void dlg_editbox_select_range(dlgcontrol *ctrl, dlgparam *dp,
+ size_t start, size_t len);
/* The `listbox' functions can also apply to combo boxes. */
-void dlg_listbox_clear(union control *ctrl, dlgparam *dp);
-void dlg_listbox_del(union control *ctrl, dlgparam *dp, int index);
-void dlg_listbox_add(union control *ctrl, dlgparam *dp, char const *text);
+void dlg_listbox_clear(dlgcontrol *ctrl, dlgparam *dp);
+void dlg_listbox_del(dlgcontrol *ctrl, dlgparam *dp, int index);
+void dlg_listbox_add(dlgcontrol *ctrl, dlgparam *dp, char const *text);
/*
* Each listbox entry may have a numeric id associated with it.
* Note that some front ends only permit a string to be stored at
@@ -564,44 +588,44 @@ void dlg_listbox_add(union control *ctrl, dlgparam *dp, char const *text);
* strings in any listbox then you MUST not assign them different
* IDs and expect to get meaningful results back.
*/
-void dlg_listbox_addwithid(union control *ctrl, dlgparam *dp,
+void dlg_listbox_addwithid(dlgcontrol *ctrl, dlgparam *dp,
char const *text, int id);
-int dlg_listbox_getid(union control *ctrl, dlgparam *dp, int index);
+int dlg_listbox_getid(dlgcontrol *ctrl, dlgparam *dp, int index);
/* dlg_listbox_index returns <0 if no single element is selected. */
-int dlg_listbox_index(union control *ctrl, dlgparam *dp);
-bool dlg_listbox_issel(union control *ctrl, dlgparam *dp, int index);
-void dlg_listbox_select(union control *ctrl, dlgparam *dp, int index);
-void dlg_text_set(union control *ctrl, dlgparam *dp, char const *text);
-void dlg_filesel_set(union control *ctrl, dlgparam *dp, Filename *fn);
-Filename *dlg_filesel_get(union control *ctrl, dlgparam *dp);
-void dlg_fontsel_set(union control *ctrl, dlgparam *dp, FontSpec *fn);
-FontSpec *dlg_fontsel_get(union control *ctrl, dlgparam *dp);
+int dlg_listbox_index(dlgcontrol *ctrl, dlgparam *dp);
+bool dlg_listbox_issel(dlgcontrol *ctrl, dlgparam *dp, int index);
+void dlg_listbox_select(dlgcontrol *ctrl, dlgparam *dp, int index);
+void dlg_text_set(dlgcontrol *ctrl, dlgparam *dp, char const *text);
+void dlg_filesel_set(dlgcontrol *ctrl, dlgparam *dp, Filename *fn);
+Filename *dlg_filesel_get(dlgcontrol *ctrl, dlgparam *dp);
+void dlg_fontsel_set(dlgcontrol *ctrl, dlgparam *dp, FontSpec *fn);
+FontSpec *dlg_fontsel_get(dlgcontrol *ctrl, dlgparam *dp);
/*
* Bracketing a large set of updates in these two functions will
* cause the front end (if possible) to delay updating the screen
* until it's all complete, thus avoiding flicker.
*/
-void dlg_update_start(union control *ctrl, dlgparam *dp);
-void dlg_update_done(union control *ctrl, dlgparam *dp);
+void dlg_update_start(dlgcontrol *ctrl, dlgparam *dp);
+void dlg_update_done(dlgcontrol *ctrl, dlgparam *dp);
/*
* Set input focus into a particular control.
*/
-void dlg_set_focus(union control *ctrl, dlgparam *dp);
+void dlg_set_focus(dlgcontrol *ctrl, dlgparam *dp);
/*
* Change the label text on a control.
*/
-void dlg_label_change(union control *ctrl, dlgparam *dp, char const *text);
+void dlg_label_change(dlgcontrol *ctrl, dlgparam *dp, char const *text);
/*
* Return the `ctrl' structure for the most recent control that had
* the input focus apart from the one mentioned. This is NOT
* GUARANTEED to work on all platforms, so don't base any critical
* functionality on it!
*/
-union control *dlg_last_focused(union control *ctrl, dlgparam *dp);
+dlgcontrol *dlg_last_focused(dlgcontrol *ctrl, dlgparam *dp);
/*
* Find out whether a particular control is currently visible.
*/
-bool dlg_is_visible(union control *ctrl, dlgparam *dp);
+bool dlg_is_visible(dlgcontrol *ctrl, dlgparam *dp);
/*
* During event processing, you might well want to give an error
* indication to the user. dlg_beep() is a quick and easy generic
@@ -629,9 +653,9 @@ void dlg_end(dlgparam *dp, int value);
* dlg_coloursel_start() accepts an RGB triple which is used to
* initialise the colour selector to its starting value.
*/
-void dlg_coloursel_start(union control *ctrl, dlgparam *dp,
+void dlg_coloursel_start(dlgcontrol *ctrl, dlgparam *dp,
int r, int g, int b);
-bool dlg_coloursel_results(union control *ctrl, dlgparam *dp,
+bool dlg_coloursel_results(dlgcontrol *ctrl, dlgparam *dp,
int *r, int *g, int *b);
/*
@@ -643,7 +667,7 @@ bool dlg_coloursel_results(union control *ctrl, dlgparam *dp,
* If `ctrl' is NULL, _all_ controls in the dialog get refreshed
* (for loading or saving entire sets of settings).
*/
-void dlg_refresh(union control *ctrl, dlgparam *dp);
+void dlg_refresh(dlgcontrol *ctrl, dlgparam *dp);
/*
* Standard helper functions for reading a controlbox structure.
@@ -663,3 +687,9 @@ int ctrl_path_elements(const char *path);
/* Return the number of matching path elements at the starts of p1 and p2,
* or INT_MAX if the paths are identical. */
int ctrl_path_compare(const char *p1, const char *p2);
+
+/*
+ * Normalise the align_next_to fields in a controlset so that they
+ * form a backwards linked list.
+ */
+void ctrlset_normalise_aligns(struct controlset *s);