Sebastian Kuschel reports that pfd_closing can be called for a socket
[u/mdw/putty] / dialog.c
index ff221c0..8486919 100644 (file)
--- a/dialog.c
+++ b/dialog.c
@@ -41,12 +41,13 @@ int ctrl_path_compare(char *p1, char *p2)
 
 struct controlbox *ctrl_new_box(void)
 {
-    struct controlbox *ret = smalloc(sizeof(struct controlbox));
+    struct controlbox *ret = snew(struct controlbox);
 
     ret->nctrlsets = ret->ctrlsetsize = 0;
     ret->ctrlsets = NULL;
     ret->nfrees = ret->freesize = 0;
     ret->frees = NULL;
+    ret->freefuncs = NULL;
 
     return ret;
 }
@@ -59,9 +60,10 @@ void ctrl_free_box(struct controlbox *b)
        ctrl_free_set(b->ctrlsets[i]);
     }
     for (i = 0; i < b->nfrees; i++)
-       sfree(b->frees[i]);
+       b->freefuncs[i](b->frees[i]);
     sfree(b->ctrlsets);
     sfree(b->frees);
+    sfree(b->freefuncs);
     sfree(b);
 }
 
@@ -128,7 +130,7 @@ struct controlset *ctrl_settitle(struct controlbox *b,
                                 char *path, char *title)
 {
     
-    struct controlset *s = smalloc(sizeof(struct controlset));
+    struct controlset *s = snew(struct controlset);
     int index = ctrl_find_set(b, path, 1);
     s->pathname = dupstr(path);
     s->boxname = NULL;
@@ -138,8 +140,7 @@ struct controlset *ctrl_settitle(struct controlbox *b,
     s->ctrls = NULL;
     if (b->nctrlsets >= b->ctrlsetsize) {
        b->ctrlsetsize = b->nctrlsets + 32;
-       b->ctrlsets = srealloc(b->ctrlsets,
-                              b->ctrlsetsize*sizeof(*b->ctrlsets));
+       b->ctrlsets = sresize(b->ctrlsets, b->ctrlsetsize,struct controlset *);
     }
     if (index < b->nctrlsets)
        memmove(&b->ctrlsets[index+1], &b->ctrlsets[index],
@@ -162,7 +163,7 @@ struct controlset *ctrl_getset(struct controlbox *b,
            return b->ctrlsets[index];
        index++;
     }
-    s = smalloc(sizeof(struct controlset));
+    s = snew(struct controlset);
     s->pathname = dupstr(path);
     s->boxname = dupstr(name);
     s->boxtitle = boxtitle ? dupstr(boxtitle) : NULL;
@@ -171,8 +172,7 @@ struct controlset *ctrl_getset(struct controlbox *b,
     s->ctrls = NULL;
     if (b->nctrlsets >= b->ctrlsetsize) {
        b->ctrlsetsize = b->nctrlsets + 32;
-       b->ctrlsets = srealloc(b->ctrlsets,
-                              b->ctrlsetsize*sizeof(*b->ctrlsets));
+       b->ctrlsets = sresize(b->ctrlsets, b->ctrlsetsize,struct controlset *);
     }
     if (index < b->nctrlsets)
        memmove(&b->ctrlsets[index+1], &b->ctrlsets[index],
@@ -183,26 +183,44 @@ struct controlset *ctrl_getset(struct controlbox *b,
 }
 
 /* Allocate some private data in a controlbox. */
-void *ctrl_alloc(struct controlbox *b, size_t size)
+void *ctrl_alloc_with_free(struct controlbox *b, size_t size,
+                           ctrl_freefn_t freefunc)
 {
     void *p;
+    /*
+     * This is an internal allocation routine, so it's allowed to
+     * use smalloc directly.
+     */
     p = smalloc(size);
     if (b->nfrees >= b->freesize) {
        b->freesize = b->nfrees + 32;
-       b->frees = srealloc(b->frees, b->freesize*sizeof(*b->frees));
+       b->frees = sresize(b->frees, b->freesize, void *);
+       b->freefuncs = sresize(b->freefuncs, b->freesize, ctrl_freefn_t);
     }
-    b->frees[b->nfrees++] = p;
+    b->frees[b->nfrees] = p;
+    b->freefuncs[b->nfrees] = freefunc;
+    b->nfrees++;
     return p;
 }
 
+static void ctrl_default_free(void *p)
+{
+    sfree(p);
+}
+
+void *ctrl_alloc(struct controlbox *b, size_t size)
+{
+    return ctrl_alloc_with_free(b, size, ctrl_default_free);
+}
+
 static union control *ctrl_new(struct controlset *s, int type,
                               intorptr helpctx, handler_fn handler,
                               intorptr context)
 {
-    union control *c = smalloc(sizeof(union control));
+    union control *c = snew(union control);
     if (s->ncontrols >= s->ctrlsize) {
        s->ctrlsize = s->ncontrols + 32;
-       s->ctrls = srealloc(s->ctrls, s->ctrlsize * sizeof(*s->ctrls));
+       s->ctrls = sresize(s->ctrls, s->ctrlsize, union control *);
     }
     s->ctrls[s->ncontrols++] = c;
     /*
@@ -230,7 +248,7 @@ union control *ctrl_columns(struct controlset *s, int ncolumns, ...)
     } else {
        va_list ap;
        int i;
-       c->columns.percentages = smalloc(ncolumns * sizeof(int));
+       c->columns.percentages = snewn(ncolumns, int);
        va_start(ap, ncolumns);
        for (i = 0; i < ncolumns; i++)
            c->columns.percentages[i] = va_arg(ap, int);
@@ -300,11 +318,11 @@ union control *ctrl_radiobuttons(struct controlset *s, char *label,
     va_end(ap);
     c->radio.nbuttons = i;
     if (c->radio.shortcut == NO_SHORTCUT)
-       c->radio.shortcuts = smalloc(c->radio.nbuttons * sizeof(char));
+       c->radio.shortcuts = snewn(c->radio.nbuttons, char);
     else
        c->radio.shortcuts = NULL;
-    c->radio.buttons = smalloc(c->radio.nbuttons * sizeof(char *));
-    c->radio.buttondata = smalloc(c->radio.nbuttons * sizeof(intorptr));
+    c->radio.buttons = snewn(c->radio.nbuttons, char *);
+    c->radio.buttondata = snewn(c->radio.nbuttons, intorptr);
     /*
      * Second pass along variable argument list to actually fill in
      * the structure.
@@ -329,6 +347,7 @@ union control *ctrl_pushbutton(struct controlset *s,char *label,char shortcut,
     c->button.label = label ? dupstr(label) : NULL;
     c->button.shortcut = shortcut;
     c->button.isdefault = 0;
+    c->button.iscancel = 0;
     return c;
 }
 
@@ -359,6 +378,8 @@ union control *ctrl_droplist(struct controlset *s, char *label, char shortcut,
     c->listbox.draglist = 0;
     c->listbox.multisel = 0;
     c->listbox.percentwidth = percentage;
+    c->listbox.ncols = 0;
+    c->listbox.percentages = NULL;
     return c;
 }
 
@@ -373,6 +394,8 @@ union control *ctrl_draglist(struct controlset *s,char *label,char shortcut,
     c->listbox.draglist = 1;
     c->listbox.multisel = 0;
     c->listbox.percentwidth = 100;
+    c->listbox.ncols = 0;
+    c->listbox.percentages = NULL;
     return c;
 }
 
@@ -449,140 +472,3 @@ void ctrl_free(union control *ctrl)
     }
     sfree(ctrl);
 }
-
-void dlg_stdradiobutton_handler(union control *ctrl, void *dlg,
-                               void *data, int event)
-{
-    int button;
-    /*
-     * For a standard radio button set, the context parameter gives
-     * offsetof(targetfield, Config), and the extra data per button
-     * gives the value the target field should take if that button
-     * is the one selected.
-     */
-    if (event == EVENT_REFRESH) {
-       for (button = 0; button < ctrl->radio.nbuttons; button++)
-           if (*(int *)ATOFFSET(data, ctrl->radio.context.i) ==
-               ctrl->radio.buttondata[button].i)
-               break;
-       /* We expected that `break' to happen, in all circumstances. */
-       assert(button < ctrl->radio.nbuttons);
-       dlg_radiobutton_set(ctrl, dlg, button);
-    } else if (event == EVENT_VALCHANGE) {
-       button = dlg_radiobutton_get(ctrl, dlg);
-       assert(button >= 0 && button < ctrl->radio.nbuttons);
-       *(int *)ATOFFSET(data, ctrl->radio.context.i) =
-           ctrl->radio.buttondata[button].i;
-    }
-}
-
-void dlg_stdcheckbox_handler(union control *ctrl, void *dlg,
-                               void *data, int event)
-{
-    int offset, invert;
-
-    /*
-     * For a standard checkbox, the context parameter gives
-     * offsetof(targetfield, Config), optionally ORed with
-     * CHECKBOX_INVERT.
-     */
-    offset = ctrl->checkbox.context.i;
-    if (offset & CHECKBOX_INVERT) {
-       offset &= ~CHECKBOX_INVERT;
-       invert = 1;
-    } else
-       invert = 0;
-
-    /*
-     * C lacks a logical XOR, so the following code uses the idiom
-     * (!a ^ !b) to obtain the logical XOR of a and b. (That is, 1
-     * iff exactly one of a and b is nonzero, otherwise 0.)
-     */
-
-    if (event == EVENT_REFRESH) {
-       dlg_checkbox_set(ctrl,dlg, (!*(int *)ATOFFSET(data,offset) ^ !invert));
-    } else if (event == EVENT_VALCHANGE) {
-       *(int *)ATOFFSET(data, offset) = !dlg_checkbox_get(ctrl,dlg) ^ !invert;
-    }
-}
-
-void dlg_stdeditbox_handler(union control *ctrl, void *dlg,
-                           void *data, int event)
-{
-    /*
-     * The standard edit-box handler expects the main `context'
-     * field to contain the `offsetof' a field in the structure
-     * pointed to by `data'. The secondary `context2' field
-     * indicates the type of this field:
-     *
-     *  - if context2 > 0, the field is a char array and context2
-     *    gives its size.
-     *  - if context2 == -1, the field is an int and the edit box
-     *    is numeric.
-     *  - if context2 < -1, the field is an int and the edit box is
-     *    _floating_, and (-context2) gives the scale. (E.g. if
-     *    context2 == -1000, then typing 1.2 into the box will set
-     *    the field to 1200.)
-     */
-    int offset = ctrl->editbox.context.i;
-    int length = ctrl->editbox.context2.i;
-
-    if (length > 0) {
-       char *field = (char *)ATOFFSET(data, offset);
-       if (event == EVENT_REFRESH) {
-           dlg_editbox_set(ctrl, dlg, field);
-       } else if (event == EVENT_VALCHANGE) {
-           dlg_editbox_get(ctrl, dlg, field, length);
-       }
-    } else if (length < 0) {
-       int *field = (int *)ATOFFSET(data, offset);
-       char data[80];
-       if (event == EVENT_REFRESH) {
-           if (length == -1)
-               sprintf(data, "%d", *field);
-           else
-               sprintf(data, "%g", (double)*field / (double)(-length));
-           dlg_editbox_set(ctrl, dlg, data);
-       } else if (event == EVENT_VALCHANGE) {
-           dlg_editbox_get(ctrl, dlg, data, lenof(data));
-           if (length == -1)
-               *field = atoi(data);
-           else
-               *field = (int)((-length) * atof(data));
-       }
-    }
-}
-
-void dlg_stdfilesel_handler(union control *ctrl, void *dlg,
-                           void *data, int event)
-{
-    /*
-     * The standard file-selector handler expects the `context'
-     * field to contain the `offsetof' a Filename field in the
-     * structure pointed to by `data'.
-     */
-    int offset = ctrl->fileselect.context.i;
-
-    if (event == EVENT_REFRESH) {
-       dlg_filesel_set(ctrl, dlg, *(Filename *)ATOFFSET(data, offset));
-    } else if (event == EVENT_VALCHANGE) {
-       dlg_filesel_get(ctrl, dlg, (Filename *)ATOFFSET(data, offset));
-    }
-}
-
-void dlg_stdfontsel_handler(union control *ctrl, void *dlg,
-                           void *data, int event)
-{
-    /*
-     * The standard file-selector handler expects the `context'
-     * field to contain the `offsetof' a FontSpec field in the
-     * structure pointed to by `data'.
-     */
-    int offset = ctrl->fontselect.context.i;
-
-    if (event == EVENT_REFRESH) {
-       dlg_fontsel_set(ctrl, dlg, *(FontSpec *)ATOFFSET(data, offset));
-    } else if (event == EVENT_VALCHANGE) {
-       dlg_fontsel_get(ctrl, dlg, (FontSpec *)ATOFFSET(data, offset));
-    }
-}