📄 dialog.h
字号:
/* * Exports and types from dialog.c. *//* * This will come in handy for generic control handlers. Anyone * knows how to make this more portable, let me know :-) */#define ATOFFSET(data, offset) ( (void *) ( (char *)(data) + (offset) ) )/* * This is the big union which defines a single control, of any * type. * * General principles: * - _All_ pointers in this structure are expected to point to * dynamically allocated things, unless otherwise indicated. * - `char' fields giving keyboard shortcuts are expected to be * NO_SHORTCUT if no shortcut is desired for a particular control. * - The `label' field can often be NULL, which will cause the * control to not have a label at all. This doesn't apply to * checkboxes and push buttons, in which the label is not * separate from the control. */#define NO_SHORTCUT '\0'enum { CTRL_TEXT, /* just a static line of text */ CTRL_EDITBOX, /* label plus edit box */ CTRL_RADIO, /* label plus radio buttons */ CTRL_CHECKBOX, /* checkbox (contains own label) */ CTRL_BUTTON, /* simple push button (no label) */ CTRL_LISTBOX, /* label plus list box */ CTRL_COLUMNS, /* divide window into columns */ CTRL_FILESELECT, /* label plus filename selector */ CTRL_FONTSELECT, /* label plus font selector */ CTRL_TABDELAY /* see `tabdelay' below */};/* * Many controls have `intorptr' unions for storing user data, * since the user might reasonably want to store either an integer * or a void * pointer. Here I define a union, and two convenience * functions to create that union from actual integers or pointers. * * The convenience functions are declared as inline if possible. * Otherwise, they're declared here and defined when this header is * included with DEFINE_INTORPTR_FNS defined. This is a total pain, * but such is life. */typedef union { void *p; int i; } intorptr;#ifndef INLINEintorptr I(int i);intorptr P(void *p);#endif#if defined DEFINE_INTORPTR_FNS || defined INLINE#ifdef INLINE#define PREFIX INLINE#else#define PREFIX#endifPREFIX intorptr I(int i) { intorptr ret; ret.i = i; return ret; }PREFIX intorptr P(void *p) { intorptr ret; ret.p = p; return ret; }#undef PREFIX#endif/* * Each control has an `int' field specifying which columns it * occupies in a multi-column part of the dialog box. These macros * pack and unpack that field. * * If a control belongs in exactly one column, just specifying the * column number is perfectly adequate. */#define COLUMN_FIELD(start, span) ( (((span)-1) << 16) + (start) )#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 * large number of subtle events. We have: * - the special REFRESH event, called when a control's value * needs setting * - the ACTION event, called when the user does something that * positively requests action (double-clicking a list box item, * or pushing a push-button) * - the VALCHANGE event, called when the user alters the setting * of the control in a way that is usually considered to alter * the underlying data (toggling a checkbox or radio button, * moving the items around in a drag-list, editing an edit * control) * - the SELCHANGE event, called when the user alters the setting * of the control in a more minor way (changing the selected * item in a list box). * - the CALLBACK event, which happens after the handler routine * has requested a subdialog (file selector, font selector, * colour selector) and it has come back with information. */enum { EVENT_REFRESH, EVENT_ACTION, EVENT_VALCHANGE, EVENT_SELCHANGE, EVENT_CALLBACK};typedef void (*handler_fn)(union control *ctrl, void *dlg, void *data, int event);#define STANDARD_PREFIX \ int type; \ char *label; \ int tabdelay; \ int column; \ handler_fn handler; \ intorptr context; \ intorptr helpctxunion 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. */ 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. */ int 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 `Config' 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; } 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; int 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.) */ int 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. */ int isdefault; /* * Also, the reverse of this: a default cancel-type button, * which is implicitly pressed when you hit Escape. */ int 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! */ int 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. */ int ncols; /* number of columns */ int *percentages; /* % width of each column */ } 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). *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -