+struct ttymodes_data {
+ union control *modelist, *valradio, *valbox;
+ union control *addbutton, *rembutton, *listbox;
+};
+
+static void ttymodes_handler(union control *ctrl, void *dlg,
+ void *data, int event)
+{
+ Config *cfg = (Config *)data;
+ struct ttymodes_data *td =
+ (struct ttymodes_data *)ctrl->generic.context.p;
+
+ if (event == EVENT_REFRESH) {
+ if (ctrl == td->listbox) {
+ char *p = cfg->ttymodes;
+ dlg_update_start(ctrl, dlg);
+ dlg_listbox_clear(ctrl, dlg);
+ while (*p) {
+ int tabpos = strchr(p, '\t') - p;
+ char *disp = dupprintf("%.*s\t%s", tabpos, p,
+ (p[tabpos+1] == 'A') ? "(auto)" :
+ p+tabpos+2);
+ dlg_listbox_add(ctrl, dlg, disp);
+ p += strlen(p) + 1;
+ sfree(disp);
+ }
+ dlg_update_done(ctrl, dlg);
+ } else if (ctrl == td->modelist) {
+ int i;
+ dlg_update_start(ctrl, dlg);
+ dlg_listbox_clear(ctrl, dlg);
+ for (i = 0; ttymodes[i]; i++)
+ dlg_listbox_add(ctrl, dlg, ttymodes[i]);
+ dlg_listbox_select(ctrl, dlg, 0); /* *shrug* */
+ dlg_update_done(ctrl, dlg);
+ } else if (ctrl == td->valradio) {
+ dlg_radiobutton_set(ctrl, dlg, 0);
+ }
+ } else if (event == EVENT_ACTION) {
+ if (ctrl == td->addbutton) {
+ int ind = dlg_listbox_index(td->modelist, dlg);
+ if (ind >= 0) {
+ char type = dlg_radiobutton_get(td->valradio, dlg) ? 'V' : 'A';
+ int slen, left;
+ char *p, str[lenof(cfg->ttymodes)];
+ /* Construct new entry */
+ memset(str, 0, lenof(str));
+ strncpy(str, ttymodes[ind], lenof(str)-3);
+ slen = strlen(str);
+ str[slen] = '\t';
+ str[slen+1] = type;
+ slen += 2;
+ if (type == 'V') {
+ dlg_editbox_get(td->valbox, dlg, str+slen, lenof(str)-slen);
+ }
+ /* Find end of list, deleting any existing instance */
+ p = cfg->ttymodes;
+ left = lenof(cfg->ttymodes);
+ while (*p) {
+ int t = strchr(p, '\t') - p;
+ if (t == strlen(ttymodes[ind]) &&
+ strncmp(p, ttymodes[ind], t) == 0) {
+ memmove(p, p+strlen(p)+1, left - (strlen(p)+1));
+ continue;
+ }
+ left -= strlen(p) + 1;
+ p += strlen(p) + 1;
+ }
+ /* Append new entry */
+ memset(p, 0, left);
+ strncpy(p, str, left - 2);
+ dlg_refresh(td->listbox, dlg);
+ } else
+ dlg_beep(dlg);
+ } else if (ctrl == td->rembutton) {
+ char *p = cfg->ttymodes;
+ int i = 0, len = lenof(cfg->ttymodes);
+ while (*p) {
+ int multisel = dlg_listbox_index(td->listbox, dlg) < 0;
+ if (dlg_listbox_issel(td->listbox, dlg, i)) {
+ if (!multisel) {
+ /* Populate controls with entry we're about to
+ * delete, for ease of editing.
+ * (If multiple entries were selected, don't
+ * touch the controls.) */
+ char *val = strchr(p, '\t');
+ if (val) {
+ int ind = 0;
+ val++;
+ while (ttymodes[ind]) {
+ if (strlen(ttymodes[ind]) == val-p-1 &&
+ !strncmp(ttymodes[ind], p, val-p-1))
+ break;
+ ind++;
+ }
+ dlg_listbox_select(td->modelist, dlg, ind);
+ dlg_radiobutton_set(td->valradio, dlg,
+ (*val == 'V'));
+ dlg_editbox_set(td->valbox, dlg, val+1);
+ }
+ }
+ memmove(p, p+strlen(p)+1, len - (strlen(p)+1));
+ i++;
+ continue;
+ }
+ len -= strlen(p) + 1;
+ p += strlen(p) + 1;
+ i++;
+ }
+ memset(p, 0, lenof(cfg->ttymodes) - len);
+ dlg_refresh(td->listbox, dlg);
+ }
+ }
+}
+