static void gtextfield_destroy(GGadget *g) {
    GTextField *gt = (GTextField *) g;

    if ( gt==NULL )
return;
    if ( gt->listfield ) {
	GListField *glf = (GListField *) g;
	if ( glf->popup ) {
	    /* Must cleanup the popup before we die */
	    /* We do this instead of GDrawDestroyWindow because this method is synchronous */
	    GEvent die;
	    die.type = et_close;
	    die.w = glf->popup;
	    GDrawPostEvent(&die);
	}
	GTextInfoArrayFree(glf->ti);
    }
    if ( gt->completionfield )
	GCompletionDestroy((GCompletionField *) g);

    if ( gt->vsb!=NULL )
	(gt->vsb->g.funcs->destroy)(&gt->vsb->g);
    if ( gt->hsb!=NULL )
	(gt->hsb->g.funcs->destroy)(&gt->hsb->g);
    GDrawCancelTimer(gt->numeric_scroll);
    GDrawCancelTimer(gt->pressed);
    GDrawCancelTimer(gt->cursor);
    free(gt->lines);
    free(gt->oldtext);
    free(gt->text);
    free(gt->utf8_text);
    free(gt->lines8);
    _ggadget_destroy(g);
}
static void gtextfield_destroy(GGadget *g) {
    GTextField *gt = (GTextField *) g;

    if ( gt==NULL )
return;
    if ( gt->listfield ) {
	GListField *glf = (GListField *) g;
	if ( glf->popup ) {
	     
	     
	    GEvent die;
	    die.type = et_close;
	    die.w = glf->popup;
	    GDrawPostEvent(&die);
	}
	GTextInfoArrayFree(glf->ti);
    }
    if ( gt->completionfield )
	GCompletionDestroy((GCompletionField *) g);

    if ( gt->vsb!=NULL )
	(gt->vsb->g.funcs->destroy)(&gt->vsb->g);
    if ( gt->hsb!=NULL )
	(gt->hsb->g.funcs->destroy)(&gt->hsb->g);
    GDrawCancelTimer(gt->numeric_scroll);
    GDrawCancelTimer(gt->pressed);
    GDrawCancelTimer(gt->cursor);
    free(gt->lines);
    free(gt->oldtext);
    free(gt->text);
    free(gt->utf8_text);
    free(gt->lines8);
    _ggadget_destroy(g);
}