]> git.ipfire.org Git - thirdparty/newt.git/commitdiff
handle component destruction
authorRichard W.M. Jones <rjones@redhat.com>
Wed, 19 Mar 2008 13:50:36 +0000 (14:50 +0100)
committerMiroslav Lichvar <mlichvar@redhat.com>
Fri, 21 Mar 2008 11:58:40 +0000 (12:58 +0100)
Handle component destruction in a way which is more friendly to garbage
collection.

13 files changed:
button.c
checkbox.c
checkboxtree.c
entry.c
form.c
label.c
listbox.c
newt.0.52.ver
newt.h
newt_pr.h
scale.c
scrollbar.c
textbox.c

index fa819ebfdfd9a1ced4064d35ca7e5d095dd735db..8eb5e5a9021f86046671c258cec48804df92eb56 100644 (file)
--- a/button.c
+++ b/button.c
@@ -45,6 +45,7 @@ static newtComponent createButton(int left, int row, const char * text, int comp
        return NULL;
     }
     co->data = bu;
+    co->destroyCallback = NULL;
 
     bu->text = strdup(text);
     bu->compact = compact;
index 85cd49e6e402cff7814081fbbafb48fdb462b0f8..198d66227cc623fa947460e46c373a3ac01192f1 100644 (file)
@@ -126,6 +126,7 @@ newtComponent newtCheckbox(int left, int top, const char * text, char defValue,
     co->ops = &cbOps;
 
     co->callback = NULL;
+    co->destroyCallback = NULL;
     co->height = 1;
     co->width = wstrlen(text, -1) + 4;
     co->top = top;
index e574d55e4679d50c23a65d5cf97d6c50c0763ab8..9c3775685c4eba8b163bb30cf0b04f15664c343a 100644 (file)
@@ -333,6 +333,7 @@ newtComponent newtCheckboxTreeMulti(int left, int top, int height, char *seq, in
     co = malloc(sizeof(*co));
     ct = malloc(sizeof(struct CheckboxTree));
     co->callback = NULL;
+    co->destroyCallback = NULL;
     co->data = ct;
     co->left = left;
     co->top = top;
diff --git a/entry.c b/entry.c
index 5693c3ec1d59ed7750b82d1006c067bec06b1aaf..fc2382f96ab271ce887af9430b3a0165569ffc1d 100644 (file)
--- a/entry.c
+++ b/entry.c
@@ -78,6 +78,7 @@ newtComponent newtEntry(int left, int top, const char * initialValue, int width,
     co->width = width;
     co->isMapped = 0;
     co->callback = NULL;
+    co->destroyCallback = NULL;
 
     co->ops = &entryOps;
 
diff --git a/form.c b/form.c
index 075c13dfd97c393e6b82818de95cb1920b527410..ae1c6a06aee2a585887a7627bbf3b71264df021a 100644 (file)
--- a/form.c
+++ b/form.c
@@ -448,6 +448,7 @@ newtComponent newtForm(newtComponent vertBar, void * help, int flags) {
 
     co->takesFocus = 0;                        /* we may have 0 components */
     co->ops = &formOps;
+    co->destroyCallback = NULL;
 
     form->help = help;
     form->flags = flags;
@@ -785,6 +786,26 @@ static struct eventResult formEvent(newtComponent co, struct event ev) {
     return er;
 }
 
+/* Destroy a component.  Components which have been added to a form
+ * are destroyed when the form is destroyed; this is just for the
+ * (rare) case of components which for whatever reason weren't added
+ * to a form.
+ */
+void newtComponentDestroy(newtComponent co) {
+    /* If the user registered a destroy callback for this component,
+     * now is a good time to call it.
+     */
+    if (co->destroyCallback)
+        co->destroyCallback(co, co->destroyCallbackData);
+
+    if (co->ops->destroy) {
+        co->ops->destroy(co);
+    } else {
+        if (co->data) free(co->data);
+       free(co);
+    }
+}
+
 /* this also destroys all of the components on the form */
 void newtFormDestroy(newtComponent co) {
     newtComponent subco;
@@ -794,12 +815,7 @@ void newtFormDestroy(newtComponent co) {
     /* first, destroy all of the components */
     for (i = 0; i < form->numComps; i++) {
        subco = form->elements[i].co;
-       if (subco->ops->destroy) {
-           subco->ops->destroy(subco);
-       } else {
-           if (subco->data) free(subco->data);
-           free(subco);
-       }
+       newtComponentDestroy(subco);
     }
 
     if (form->hotKeys) free(form->hotKeys);
@@ -1119,6 +1135,13 @@ void newtComponentAddCallback(newtComponent co, newtCallback f, void * data) {
     co->callbackData = data;
 }
 
+/* Add a callback which is called when the component is destroyed. */
+void newtComponentAddDestroyCallback(newtComponent co,
+                               newtCallback f, void * data) {
+    co->destroyCallback = f;
+    co->destroyCallbackData = data;
+}
+
 void newtComponentTakesFocus(newtComponent co, int val) {
     co->takesFocus = val;
 }
diff --git a/label.c b/label.c
index ad8665b82068cea9a6b3f76478f3ae6de31b0c7e..a0c17a4a391fb1e623327e12b7f4e40816bb9e8a 100644 (file)
--- a/label.c
+++ b/label.c
@@ -28,6 +28,7 @@ newtComponent newtLabel(int left, int top, const char * text) {
     co = malloc(sizeof(*co));
     la = malloc(sizeof(struct label));
     co->data = la;
+    co->destroyCallback = NULL;
 
     co->ops = &labelOps;
 
index c802e7ce0f9616af8aa516033c16495b1208fdee..1a77e0e64726d5fb9fc96986c5b88144787c6d34 100644 (file)
--- a/listbox.c
+++ b/listbox.c
@@ -133,6 +133,7 @@ newtComponent newtListbox(int left, int top, int height, int flags) {
     co->ops = &listboxOps;
     co->takesFocus = 1;
     co->callback = NULL;
+    co->destroyCallback = NULL;
 
     updateWidth(co, li, 5);
 
index fe9bdd388b59f2d0fc085e1a052a682bc1791d2b..df7c4d7a6d2dd9fcb47a35eb7dca57cda9f09a05 100644 (file)
@@ -141,3 +141,9 @@ NEWT_0.52.6 {
                newtSetColor;
                newtPopWindowNoRefresh;
 } NEWT_0.52;
+
+NEWT_0.52.9 {
+       global:
+               newtComponentAddDestroyCallback;
+               newtComponentDestroy;
+} NEWT_0.52.6;
diff --git a/newt.h b/newt.h
index daa55138db12c0da418e52fee5c3914ce79d88e9..88f2dd8d29880aa213f714c47a051388d94c5646 100644 (file)
--- a/newt.h
+++ b/newt.h
@@ -255,10 +255,20 @@ void newtScaleSet(newtComponent co, unsigned long long amount);
 void newtComponentAddCallback(newtComponent co, newtCallback f, void * data);
 void newtComponentTakesFocus(newtComponent co, int val);
 
+/* This callback is called when a component is destroyed. */
+void newtComponentAddDestroyCallback(newtComponent co,
+                                     newtCallback f, void * data);
+
 /* this also destroys all of the components (including other forms) on the 
    form */
 void newtFormDestroy(newtComponent form);      
 
+/* NB: You SHOULD NOT call this for components which have been added
+ * to a form (ie. almost all components).  They are destroyed along
+ * with the form when you call newtFormDestroy.
+ */
+void newtComponentDestroy(newtComponent co);
+
 /* Key codes */
 
 #define NEWT_KEY_TAB                   '\t'
index cc839ad22e358dce6db420add2f404710955a702..5d60ebebe2fa1cc7e502e1e040abfd6c3a1682dd 100644 (file)
--- a/newt_pr.h
+++ b/newt_pr.h
@@ -40,6 +40,9 @@ struct newtComponent_struct {
     newtCallback callback;
     void * callbackData;
 
+    newtCallback destroyCallback;
+    void * destroyCallbackData;
+
     void * data;
 } ;
 
diff --git a/scale.c b/scale.c
index 07cebd5a558aca1f9cbda1a74cf37c7c21e7d12b..f9a1f40cd9771c87d137d6f1a4502525536f7615 100644 (file)
--- a/scale.c
+++ b/scale.c
@@ -28,6 +28,7 @@ newtComponent newtScale(int left, int top, int width, long long fullValue) {
     co = malloc(sizeof(*co));
     sc = malloc(sizeof(struct scale));
     co->data = sc;
+    co->destroyCallback = NULL;
 
     co->ops = &scaleOps;
 
index 96ed513f7d7ca954f3b1c504e88930d80bfae736..b89ede2beb32dac93e57b1dc4a37e647f6194848 100644 (file)
@@ -46,6 +46,7 @@ newtComponent newtVerticalScrollbar(int left, int top, int height,
     co = malloc(sizeof(*co));
     sb = malloc(sizeof(*sb));
     co->data = sb;
+    co->destroyCallback = NULL;
 
     if (height >= 2) {
        sb->arrows = 1;
index fcfb41f227498e30f6817c71c0f0a37226824224..873a23c948c13cc8c947215e7874e68ac0e611e2 100644 (file)
--- a/textbox.c
+++ b/textbox.c
@@ -105,6 +105,7 @@ newtComponent newtTextbox(int left, int top, int width, int height, int flags) {
     co->left = left;
     co->takesFocus = 0;
     co->width = width;
+    co->destroyCallback = NULL;
 
     tb->doWrap = flags & NEWT_FLAG_WRAP;
     tb->numLines = 0;