dialog.h 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. /*
  2. * Exports and types from dialog.c.
  3. */
  4. /*
  5. * This is the big union which defines a single control, of any
  6. * type.
  7. *
  8. * General principles:
  9. * - _All_ pointers in this structure are expected to point to
  10. * dynamically allocated things, unless otherwise indicated.
  11. * - `char' fields giving keyboard shortcuts are expected to be
  12. * NO_SHORTCUT if no shortcut is desired for a particular control.
  13. * - The `label' field can often be NULL, which will cause the
  14. * control to not have a label at all. This doesn't apply to
  15. * checkboxes and push buttons, in which the label is not
  16. * separate from the control.
  17. */
  18. #define NO_SHORTCUT '\0'
  19. enum {
  20. CTRL_TEXT, /* just a static line of text */
  21. CTRL_EDITBOX, /* label plus edit box */
  22. CTRL_RADIO, /* label plus radio buttons */
  23. CTRL_CHECKBOX, /* checkbox (contains own label) */
  24. CTRL_BUTTON, /* simple push button (no label) */
  25. CTRL_LISTBOX, /* label plus list box */
  26. CTRL_COLUMNS, /* divide window into columns */
  27. CTRL_FILESELECT, /* label plus filename selector */
  28. CTRL_FONTSELECT, /* label plus font selector */
  29. CTRL_TABDELAY /* see `tabdelay' below */
  30. };
  31. /*
  32. * Many controls have `intorptr' unions for storing user data,
  33. * since the user might reasonably want to store either an integer
  34. * or a void * pointer. Here I define a union, and two convenience
  35. * functions to create that union from actual integers or pointers.
  36. *
  37. * The convenience functions are declared as inline if possible.
  38. * Otherwise, they're declared here and defined when this header is
  39. * included with DEFINE_INTORPTR_FNS defined. This is a total pain,
  40. * but such is life.
  41. */
  42. typedef union { void *p; const void *cp; int i; } intorptr;
  43. #ifndef INLINE
  44. intorptr I(int i);
  45. intorptr P(void *p);
  46. intorptr CP(const void *p);
  47. #endif
  48. #if defined DEFINE_INTORPTR_FNS || defined INLINE
  49. #ifdef INLINE
  50. #define PREFIX INLINE
  51. #else
  52. #define PREFIX
  53. #endif
  54. PREFIX intorptr I(int i) { intorptr ret; ret.i = i; return ret; }
  55. PREFIX intorptr P(void *p) { intorptr ret; ret.p = p; return ret; }
  56. PREFIX intorptr CP(const void *p) { intorptr ret; ret.cp = p; return ret; }
  57. #undef PREFIX
  58. #endif
  59. /*
  60. * Each control has an `int' field specifying which columns it
  61. * occupies in a multi-column part of the dialog box. These macros
  62. * pack and unpack that field.
  63. *
  64. * If a control belongs in exactly one column, just specifying the
  65. * column number is perfectly adequate.
  66. */
  67. #define COLUMN_FIELD(start, span) ( (((span)-1) << 16) + (start) )
  68. #define COLUMN_START(field) ( (field) & 0xFFFF )
  69. #define COLUMN_SPAN(field) ( (((field) >> 16) & 0xFFFF) + 1 )
  70. /*
  71. * The number of event types is being deliberately kept small, on
  72. * the grounds that not all platforms might be able to report a
  73. * large number of subtle events. We have:
  74. * - the special REFRESH event, called when a control's value
  75. * needs setting
  76. * - the ACTION event, called when the user does something that
  77. * positively requests action (double-clicking a list box item,
  78. * or pushing a push-button)
  79. * - the VALCHANGE event, called when the user alters the setting
  80. * of the control in a way that is usually considered to alter
  81. * the underlying data (toggling a checkbox or radio button,
  82. * moving the items around in a drag-list, editing an edit
  83. * control)
  84. * - the SELCHANGE event, called when the user alters the setting
  85. * of the control in a more minor way (changing the selected
  86. * item in a list box).
  87. * - the CALLBACK event, which happens after the handler routine
  88. * has requested a subdialog (file selector, font selector,
  89. * colour selector) and it has come back with information.
  90. */
  91. enum {
  92. EVENT_REFRESH,
  93. EVENT_ACTION,
  94. EVENT_VALCHANGE,
  95. EVENT_SELCHANGE,
  96. EVENT_CALLBACK
  97. };
  98. typedef void (*handler_fn)(dlgcontrol *ctrl, dlgparam *dp,
  99. void *data, int event);
  100. struct dlgcontrol {
  101. /*
  102. * Generic fields shared by all the control types.
  103. */
  104. int type;
  105. /*
  106. * Every control except CTRL_COLUMNS has _some_ sort of label. By
  107. * putting it in the `generic' union as well as everywhere else,
  108. * we avoid having to have an irritating switch statement when we
  109. * go through and deallocate all the memory in a config-box
  110. * structure.
  111. *
  112. * Yes, this does mean that any non-NULL value in this field is
  113. * expected to be dynamically allocated and freeable.
  114. *
  115. * For CTRL_COLUMNS, this field MUST be NULL.
  116. */
  117. char *label;
  118. /*
  119. * If `delay_taborder' is true, it indicates that this particular
  120. * control should not yet appear in the tab order. A subsequent
  121. * CTRL_TABDELAY entry will place it.
  122. */
  123. bool delay_taborder;
  124. /*
  125. * Indicate which column(s) this control occupies. This can be
  126. * unpacked into starting column and column span by the COLUMN
  127. * macros above.
  128. */
  129. int column;
  130. /*
  131. * Most controls need to provide a function which gets called when
  132. * that control's setting is changed, or when the control's
  133. * setting needs initialising.
  134. *
  135. * The `data' parameter points to the writable data being modified
  136. * as a result of the configuration activity; for example, the
  137. * PuTTY `Conf' structure, although not necessarily.
  138. *
  139. * The `dlg' parameter is passed back to the platform- specific
  140. * routines to read and write the actual control state.
  141. */
  142. handler_fn handler;
  143. /*
  144. * Almost all of the above functions will find it useful to be
  145. * able to store one or two pieces of `void *' or `int' data.
  146. */
  147. intorptr context, context2;
  148. /*
  149. * For any control, we also allow the storage of a piece of data
  150. * for use by context-sensitive help. For example, on Windows you
  151. * can click the magic question mark and then click a control, and
  152. * help for that control should spring up. Hence, here is a slot
  153. * in which to store per-control data that a particular
  154. * platform-specific driver can use to ensure it brings up the
  155. * right piece of help text.
  156. */
  157. HelpCtx helpctx;
  158. /*
  159. * Setting this to non-NULL coerces two or more controls to have
  160. * their y-coordinates adjusted so that they can sit alongside
  161. * each other and look nicely aligned, even if they're different
  162. * heights.
  163. *
  164. * Set this field on later controls (in terms of order in the data
  165. * structure), pointing back to earlier ones, so that when each
  166. * control is instantiated, the referred-to one is already there
  167. * to be referred to.
  168. *
  169. * Don't expect this to change the position of the _first_
  170. * control. Currently, the layout is done one control at a time,
  171. * so that once the first control has been placed, the second one
  172. * can't cause the first one to be retrospectively moved.
  173. */
  174. dlgcontrol *align_next_to;
  175. /*
  176. * Union of further fields specific to each control type.
  177. */
  178. union {
  179. struct { /* for CTRL_TABDELAY */
  180. dlgcontrol *ctrl;
  181. } tabdelay;
  182. struct { /* for CTRL_EDITBOX */
  183. char shortcut; /* keyboard shortcut */
  184. /*
  185. * Percentage of the dialog-box width used by the edit
  186. * box. If this is set to 100, the label is on its own
  187. * line; otherwise the label is on the same line as the
  188. * box itself.
  189. */
  190. int percentwidth;
  191. bool password; /* details of input are hidden */
  192. /*
  193. * A special case of the edit box is the combo box, which
  194. * has a drop-down list built in. (Note that a _non_-
  195. * editable drop-down list is done as a special case of a
  196. * list box.)
  197. *
  198. * Don't try setting has_list and password on the same
  199. * control; front ends are not required to support that
  200. * combination.
  201. */
  202. bool has_list;
  203. } editbox;
  204. struct { /* for CTRL_RADIO */
  205. /*
  206. * `shortcut' here is a single keyboard shortcut which is
  207. * expected to select the whole group of radio buttons. It
  208. * can be NO_SHORTCUT if required, and there is also a way
  209. * to place individual shortcuts on each button; see
  210. * below.
  211. */
  212. char shortcut;
  213. /*
  214. * There are separate fields for `ncolumns' and `nbuttons'
  215. * for several reasons.
  216. *
  217. * Firstly, we sometimes want the last of a set of buttons
  218. * to have a longer label than the rest; we achieve this
  219. * by setting `ncolumns' higher than `nbuttons', and the
  220. * layout code is expected to understand that the final
  221. * button should be given all the remaining space on the
  222. * line. This sounds like a ludicrously specific special
  223. * case (if we're doing this sort of thing, why not have
  224. * the general ability to have a particular button span
  225. * more than one column whether it's the last one or not?)
  226. * but actually it's reasonably common for the sort of
  227. * three-way control you get a lot of in PuTTY: `yes'
  228. * versus `no' versus `some more complex way to decide'.
  229. *
  230. * Secondly, setting `nbuttons' higher than `ncolumns'
  231. * lets us have more than one line of radio buttons for a
  232. * single setting. A very important special case of this
  233. * is setting `ncolumns' to 1, so that each button is on
  234. * its own line.
  235. */
  236. int ncolumns;
  237. int nbuttons;
  238. /*
  239. * This points to a dynamically allocated array of `char *'
  240. * pointers, each of which points to a dynamically
  241. * allocated string.
  242. */
  243. char **buttons; /* `nbuttons' button labels */
  244. /*
  245. * This points to a dynamically allocated array of `char'
  246. * giving the individual keyboard shortcuts for each radio
  247. * button. The array may be NULL if none are required.
  248. */
  249. char *shortcuts; /* `nbuttons' shortcuts; may be NULL */
  250. /*
  251. * This points to a dynamically allocated array of
  252. * intorptr, giving helpful data for each button.
  253. */
  254. intorptr *buttondata; /* `nbuttons' entries; may be NULL */
  255. } radio;
  256. struct { /* for CTRL_CHECKBOX */
  257. char shortcut;
  258. } checkbox;
  259. struct { /* for CTRL_BUTTON */
  260. char shortcut;
  261. /*
  262. * At least Windows has the concept of a `default push
  263. * button', which gets implicitly pressed when you hit
  264. * Return even if it doesn't have the input focus.
  265. */
  266. bool isdefault;
  267. /*
  268. * Also, the reverse of this: a default cancel-type
  269. * button, which is implicitly pressed when you hit
  270. * Escape.
  271. */
  272. bool iscancel;
  273. } button;
  274. struct { /* for CTRL_LISTBOX */
  275. char shortcut; /* keyboard shortcut */
  276. /*
  277. * Height of the list box, in approximate number of lines.
  278. * If this is zero, the list is a drop-down list.
  279. */
  280. int height; /* height in lines */
  281. /*
  282. * If this is set, the list elements can be reordered by
  283. * the user (by drag-and-drop or by Up and Down buttons,
  284. * whatever the per-platform implementation feels
  285. * comfortable with). This is not guaranteed to work on a
  286. * drop-down list, so don't try it!
  287. */
  288. bool draglist;
  289. /*
  290. * If this is non-zero, the list can have more than one
  291. * element selected at a time. This is not guaranteed to
  292. * work on a drop-down list, so don't try it!
  293. *
  294. * Different non-zero values request slightly different
  295. * types of multi-selection (this may well be meaningful
  296. * only in GTK, so everyone else can ignore it if they
  297. * want). 1 means the list box expects to have individual
  298. * items selected, whereas 2 means it expects the user to
  299. * want to select a large contiguous range at a time.
  300. */
  301. int multisel;
  302. /*
  303. * Percentage of the dialog-box width used by the list
  304. * box. If this is set to 100, the label is on its own
  305. * line; otherwise the label is on the same line as the
  306. * box itself. Setting this to anything other than 100 is
  307. * not guaranteed to work on a _non_-drop-down list, so
  308. * don't try it!
  309. */
  310. int percentwidth;
  311. /*
  312. * Some list boxes contain strings that contain tab
  313. * characters. If `ncols' is greater than 0, then
  314. * `percentages' is expected to be non-zero and to contain
  315. * the respective widths of `ncols' columns, which
  316. * together will exactly fit the width of the list box.
  317. * Otherwise `percentages' must be NULL.
  318. *
  319. * There should never be more than one column in a
  320. * drop-down list (one with height==0), because front ends
  321. * may have to implement it as a special case of an
  322. * editable combo box.
  323. */
  324. int ncols; /* number of columns */
  325. int *percentages; /* % width of each column */
  326. /*
  327. * Flag which can be set to false to suppress the
  328. * horizontal scroll bar if a list box entry goes off the
  329. * right-hand side.
  330. */
  331. bool hscroll;
  332. } listbox;
  333. struct { /* for CTRL_FILESELECT */
  334. char shortcut;
  335. /*
  336. * `filter' dictates what type of files will be selected
  337. * by default; for example, when selecting private key
  338. * files the file selector would do well to only show .PPK
  339. * files (on those systems where this is the chosen
  340. * 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. FILESELECT_FILTER_TYPE 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. bool for_writing;
  362. /*
  363. * On at least some platforms, the file selector is a
  364. * separate dialog box, and contains a user-settable
  365. * title.
  366. *
  367. * This value _is_ expected to require freeing.
  368. */
  369. char *title;
  370. /*
  371. * Reduce the file selector to just a single browse
  372. * button.
  373. *
  374. * Normally, a file selector is used to set a config
  375. * option that consists of a file name, so that that file
  376. * will be read or written at run time. In that situation,
  377. * it makes sense to have an edit box showing the
  378. * currently selected file name, and a button to change it
  379. * interactively.
  380. *
  381. * But occasionally a file selector is used to load a file
  382. * _during_ configuration. For example, host CA public
  383. * keys are entered directly into the configuration as
  384. * strings, not stored by reference to a filename; but if
  385. * you have one in a file, you want to be able to load it
  386. * during the lifetime of the CA config box rather than
  387. * awkwardly copy-pasting it. So in that case you just
  388. * want a 'pop up a file chooser' button, and when that
  389. * delivers a file name, you'll deal with it there and
  390. * then and write some other thing (like the file's
  391. * contents) into a nearby edit box.
  392. *
  393. * If you set this flag, then you may not call
  394. * dlg_filesel_set on the file selector at all, because it
  395. * doesn't store a filename. And you can only call
  396. * dlg_filesel_get on it in the handler for EVENT_ACTION,
  397. * which is what will be sent to you when the user has
  398. * used it to choose a filename.
  399. */
  400. bool just_button;
  401. } fileselect;
  402. struct { /* for CTRL_COLUMNS */
  403. /* In this variant, `label' MUST be NULL. */
  404. int ncols; /* number of columns */
  405. int *percentages; /* % width of each column */
  406. /*
  407. * Every time this control type appears, exactly one of
  408. * `ncols' and the previous number of columns MUST be one.
  409. * Attempting to allow a seamless transition from a four-
  410. * to a five-column layout, for example, would be way more
  411. * trouble than it was worth. If you must lay things out
  412. * like that, define eight unevenly sized columns and use
  413. * column-spanning a lot. But better still, just don't.
  414. *
  415. * `percentages' may be NULL if ncols==1, to save space.
  416. */
  417. } columns;
  418. struct { /* for CTRL_FONTSELECT */
  419. char shortcut;
  420. } fontselect;
  421. struct { /* for CTRL_TEXT */
  422. /*
  423. * If this is true (the default), the text will wrap on to
  424. * multiple lines. If false, it will stay on the same
  425. * line, with a horizontal scrollbar if necessary.
  426. */
  427. bool wrap;
  428. } text;
  429. };
  430. };
  431. #undef STANDARD_PREFIX
  432. /*
  433. * `controlset' is a container holding an array of `dlgcontrol'
  434. * structures, together with a panel name and a title for the whole
  435. * set. In Windows and any similar-looking GUI, each `controlset'
  436. * in the config will be a container box within a panel.
  437. *
  438. * Special case: if `boxname' is NULL, the control set gives an
  439. * overall title for an entire panel of controls.
  440. */
  441. struct controlset {
  442. char *pathname; /* panel path, e.g. "SSH/Tunnels" */
  443. char *boxname; /* internal short name of controlset */
  444. char *boxtitle; /* title of container box */
  445. int ncolumns; /* current no. of columns at bottom */
  446. size_t ncontrols; /* number of `dlgcontrol' in array */
  447. size_t ctrlsize; /* allocated size of array */
  448. dlgcontrol **ctrls; /* actual array */
  449. };
  450. typedef void (*ctrl_freefn_t)(void *); /* used by ctrl_alloc_with_free */
  451. /*
  452. * This is the container structure which holds a complete set of
  453. * controls.
  454. */
  455. struct controlbox {
  456. size_t nctrlsets; /* number of ctrlsets */
  457. size_t ctrlsetsize; /* ctrlset size */
  458. struct controlset **ctrlsets; /* actual array of ctrlsets */
  459. size_t nfrees;
  460. size_t freesize;
  461. void **frees; /* array of aux data areas to free */
  462. ctrl_freefn_t *freefuncs; /* parallel array of free functions */
  463. };
  464. struct controlbox *ctrl_new_box(void);
  465. void ctrl_free_box(struct controlbox *);
  466. /*
  467. * Standard functions used for populating a controlbox structure.
  468. */
  469. /* Set up a panel title. */
  470. struct controlset *ctrl_settitle(struct controlbox *,
  471. const char *path, const char *title);
  472. /* Retrieve a pointer to a controlset, creating it if absent. */
  473. struct controlset *ctrl_getset(struct controlbox *, const char *path,
  474. const char *name, const char *boxtitle);
  475. void ctrl_free_set(struct controlset *);
  476. void ctrl_free(dlgcontrol *);
  477. /*
  478. * This function works like `malloc', but the memory it returns
  479. * will be automatically freed when the controlbox is freed. Note
  480. * that a controlbox is a dialog-box _template_, not an instance,
  481. * and so data allocated through this function is better not used
  482. * to hold modifiable per-instance things. It's mostly here for
  483. * allocating structures to be passed as control handler params.
  484. *
  485. * ctrl_alloc_with_free also allows you to provide a function to free
  486. * the structure, in case there are other dynamically allocated bits
  487. * and pieces dangling off it.
  488. */
  489. void *ctrl_alloc(struct controlbox *b, size_t size);
  490. void *ctrl_alloc_with_free(struct controlbox *b, size_t size,
  491. ctrl_freefn_t freefunc);
  492. /*
  493. * Individual routines to create `dlgcontrol' structures in a controlset.
  494. *
  495. * Most of these routines allow the most common fields to be set
  496. * directly, and put default values in the rest. Each one returns a
  497. * pointer to the `dlgcontrol' it created, so that final tweaks
  498. * can be made.
  499. */
  500. /* `ncolumns' is followed by that many percentages, as integers. */
  501. dlgcontrol *ctrl_columns(struct controlset *, int ncolumns, ...);
  502. dlgcontrol *ctrl_editbox(struct controlset *, const char *label,
  503. char shortcut, int percentage, HelpCtx helpctx,
  504. handler_fn handler,
  505. intorptr context, intorptr context2);
  506. dlgcontrol *ctrl_combobox(struct controlset *, const char *label,
  507. char shortcut, int percentage, HelpCtx helpctx,
  508. handler_fn handler,
  509. intorptr context, intorptr context2);
  510. /*
  511. * `ncolumns' is followed by (alternately) radio button titles and
  512. * intorptrs, until a NULL in place of a title string is seen. Each
  513. * title is expected to be followed by a shortcut _iff_ `shortcut'
  514. * is NO_SHORTCUT.
  515. */
  516. dlgcontrol *ctrl_radiobuttons_fn(struct controlset *, const char *label,
  517. char shortcut, int ncolumns, HelpCtx helpctx,
  518. handler_fn handler, intorptr context, ...);
  519. #define ctrl_radiobuttons(...) \
  520. ctrl_radiobuttons_fn(__VA_ARGS__, (const char *)NULL)
  521. dlgcontrol *ctrl_pushbutton(struct controlset *, const char *label,
  522. char shortcut, HelpCtx helpctx,
  523. handler_fn handler, intorptr context);
  524. dlgcontrol *ctrl_listbox(struct controlset *, const char *label,
  525. char shortcut, HelpCtx helpctx,
  526. handler_fn handler, intorptr context);
  527. dlgcontrol *ctrl_droplist(struct controlset *, const char *label,
  528. char shortcut, int percentage, HelpCtx helpctx,
  529. handler_fn handler, intorptr context);
  530. dlgcontrol *ctrl_draglist(struct controlset *, const char *label,
  531. char shortcut, HelpCtx helpctx,
  532. handler_fn handler, intorptr context);
  533. dlgcontrol *ctrl_filesel(struct controlset *, const char *label,
  534. char shortcut, FILESELECT_FILTER_TYPE filter,
  535. bool write, const char *title, HelpCtx helpctx,
  536. handler_fn handler, intorptr context);
  537. dlgcontrol *ctrl_fontsel(struct controlset *, const char *label,
  538. char shortcut, HelpCtx helpctx,
  539. handler_fn handler, intorptr context);
  540. dlgcontrol *ctrl_text(struct controlset *, const char *text,
  541. HelpCtx helpctx);
  542. dlgcontrol *ctrl_checkbox(struct controlset *, const char *label,
  543. char shortcut, HelpCtx helpctx,
  544. handler_fn handler, intorptr context);
  545. dlgcontrol *ctrl_tabdelay(struct controlset *, dlgcontrol *);
  546. /*
  547. * Routines the platform-independent dialog code can call to read
  548. * and write the values of controls.
  549. */
  550. void dlg_radiobutton_set(dlgcontrol *ctrl, dlgparam *dp, int whichbutton);
  551. int dlg_radiobutton_get(dlgcontrol *ctrl, dlgparam *dp);
  552. void dlg_checkbox_set(dlgcontrol *ctrl, dlgparam *dp, bool checked);
  553. bool dlg_checkbox_get(dlgcontrol *ctrl, dlgparam *dp);
  554. void dlg_editbox_set(dlgcontrol *ctrl, dlgparam *dp, char const *text);
  555. char *dlg_editbox_get(dlgcontrol *ctrl, dlgparam *dp); /* result must be freed by caller */
  556. void dlg_editbox_select_range(dlgcontrol *ctrl, dlgparam *dp,
  557. size_t start, size_t len);
  558. /* The `listbox' functions can also apply to combo boxes. */
  559. void dlg_listbox_clear(dlgcontrol *ctrl, dlgparam *dp);
  560. void dlg_listbox_del(dlgcontrol *ctrl, dlgparam *dp, int index);
  561. void dlg_listbox_add(dlgcontrol *ctrl, dlgparam *dp, char const *text);
  562. /*
  563. * Each listbox entry may have a numeric id associated with it.
  564. * Note that some front ends only permit a string to be stored at
  565. * each position, which means that _if_ you put two identical
  566. * strings in any listbox then you MUST not assign them different
  567. * IDs and expect to get meaningful results back.
  568. */
  569. void dlg_listbox_addwithid(dlgcontrol *ctrl, dlgparam *dp,
  570. char const *text, int id);
  571. int dlg_listbox_getid(dlgcontrol *ctrl, dlgparam *dp, int index);
  572. /* dlg_listbox_index returns <0 if no single element is selected. */
  573. int dlg_listbox_index(dlgcontrol *ctrl, dlgparam *dp);
  574. bool dlg_listbox_issel(dlgcontrol *ctrl, dlgparam *dp, int index);
  575. void dlg_listbox_select(dlgcontrol *ctrl, dlgparam *dp, int index);
  576. void dlg_text_set(dlgcontrol *ctrl, dlgparam *dp, char const *text);
  577. void dlg_filesel_set(dlgcontrol *ctrl, dlgparam *dp, Filename *fn);
  578. Filename *dlg_filesel_get(dlgcontrol *ctrl, dlgparam *dp);
  579. void dlg_fontsel_set(dlgcontrol *ctrl, dlgparam *dp, FontSpec *fn);
  580. FontSpec *dlg_fontsel_get(dlgcontrol *ctrl, dlgparam *dp);
  581. /*
  582. * Bracketing a large set of updates in these two functions will
  583. * cause the front end (if possible) to delay updating the screen
  584. * until it's all complete, thus avoiding flicker.
  585. */
  586. void dlg_update_start(dlgcontrol *ctrl, dlgparam *dp);
  587. void dlg_update_done(dlgcontrol *ctrl, dlgparam *dp);
  588. /*
  589. * Set input focus into a particular control.
  590. */
  591. void dlg_set_focus(dlgcontrol *ctrl, dlgparam *dp);
  592. /*
  593. * Change the label text on a control.
  594. */
  595. void dlg_label_change(dlgcontrol *ctrl, dlgparam *dp, char const *text);
  596. /*
  597. * Return the `ctrl' structure for the most recent control that had
  598. * the input focus apart from the one mentioned. This is NOT
  599. * GUARANTEED to work on all platforms, so don't base any critical
  600. * functionality on it!
  601. */
  602. dlgcontrol *dlg_last_focused(dlgcontrol *ctrl, dlgparam *dp);
  603. /*
  604. * Find out whether a particular control is currently visible.
  605. */
  606. bool dlg_is_visible(dlgcontrol *ctrl, dlgparam *dp);
  607. /*
  608. * During event processing, you might well want to give an error
  609. * indication to the user. dlg_beep() is a quick and easy generic
  610. * error; dlg_error() puts up a message-box or equivalent.
  611. */
  612. void dlg_beep(dlgparam *dp);
  613. void dlg_error_msg(dlgparam *dp, const char *msg);
  614. /*
  615. * This function signals to the front end that the dialog's
  616. * processing is completed, and passes an integer value (typically
  617. * a success status).
  618. */
  619. void dlg_end(dlgparam *dp, int value);
  620. /*
  621. * Routines to manage a (per-platform) colour selector.
  622. * dlg_coloursel_start() is called in an event handler, and
  623. * schedules the running of a colour selector after the event
  624. * handler returns. The colour selector will send EVENT_CALLBACK to
  625. * the control that spawned it, when it's finished;
  626. * dlg_coloursel_results() fetches the results, as integers from 0
  627. * to 255; it returns nonzero on success, or zero if the colour
  628. * selector was dismissed by hitting Cancel or similar.
  629. *
  630. * dlg_coloursel_start() accepts an RGB triple which is used to
  631. * initialise the colour selector to its starting value.
  632. */
  633. void dlg_coloursel_start(dlgcontrol *ctrl, dlgparam *dp,
  634. int r, int g, int b);
  635. bool dlg_coloursel_results(dlgcontrol *ctrl, dlgparam *dp,
  636. int *r, int *g, int *b);
  637. /*
  638. * This routine is used by the platform-independent code to
  639. * indicate that the value of a particular control is likely to
  640. * have changed. It triggers a call of the handler for that control
  641. * with `event' set to EVENT_REFRESH.
  642. *
  643. * If `ctrl' is NULL, _all_ controls in the dialog get refreshed
  644. * (for loading or saving entire sets of settings).
  645. */
  646. void dlg_refresh(dlgcontrol *ctrl, dlgparam *dp);
  647. /*
  648. * Standard helper functions for reading a controlbox structure.
  649. */
  650. /*
  651. * Find the index of next controlset in a controlbox for a given
  652. * path, or -1 if no such controlset exists. If -1 is passed as
  653. * input, finds the first. Intended usage is something like
  654. *
  655. * for (index=-1; (index=ctrl_find_path(ctrlbox, index, path)) >= 0 ;) {
  656. * ... process this controlset ...
  657. * }
  658. */
  659. int ctrl_find_path(struct controlbox *b, const char *path, int index);
  660. int ctrl_path_elements(const char *path);
  661. /* Return the number of matching path elements at the starts of p1 and p2,
  662. * or INT_MAX if the paths are identical. */
  663. int ctrl_path_compare(const char *p1, const char *p2);
  664. /*
  665. * Normalise the align_next_to fields in a controlset so that they
  666. * form a backwards linked list.
  667. */
  668. void ctrlset_normalise_aligns(struct controlset *s);