static void FVMenuSelectByName(GWindow _gw, struct gmenuitem *UNUSED(mi), GEvent *e) {
    FontView *fv = (FontView *) GDrawGetUserData(_gw);
    GRect pos;
    GWindow gw;
    GWindowAttrs wattrs;
    GGadgetCreateData gcd[8], *hvarray[12][2], *barray[8], boxes[3];
    GTextInfo label[8];
    int merge = SelMergeType(e);
    int done=0,k,i;

    memset(&wattrs,0,sizeof(wattrs));
    memset(&gcd,0,sizeof(gcd));
    memset(&label,0,sizeof(label));
    memset(&boxes,0,sizeof(boxes));

    wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
    wattrs.event_masks = ~(1<<et_charup);
    wattrs.restrict_input_to_me = false;
    wattrs.undercursor = 1;
    wattrs.cursor = ct_pointer;
    wattrs.utf8_window_title = _("Select by Name");
    wattrs.is_dlg = false;
    pos.x = pos.y = 0;
    pos.width = 100;
    pos.height = 100;
    gw = GDrawCreateTopWindow(NULL,&pos,ss_e_h,&done,&wattrs);

    k = i = 0;

    label[k].text = (unichar_t *) _("Enter either a wildcard pattern (to match glyph names)\n or a unicode encoding like \"U+0065\".");
    label[k].text_is_1byte = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    gcd[k].gd.popup_msg = (unichar_t *) _(
	"Unix style wildcarding is accepted:\n"
	"Most characters match themselves\n"
	"A \"?\" will match any single character\n"
	"A \"*\" will match an arbitrary number of characters (including none)\n"
	"An \"[abd]\" set of characters within square brackets will match any (single) character\n"
	"A \"{scmp,c2sc}\" set of strings within curly brackets will match any string\n"
	"So \"a.*\" would match \"a.\" or \"a.sc\" or \"a.swash\"\n"
	"While \"a.{scmp,c2sc}\" would match \"a.scmp\" or \"a.c2sc\"\n"
	"And \"a.[abd]\" would match \"a.a\" or \"a.b\" or \"a.d\"");
    gcd[k++].creator = GLabelCreate;
    hvarray[i][0] = &gcd[k-1]; hvarray[i++][1] = NULL;

    gcd[k].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    gcd[k].gd.popup_msg = gcd[k-1].gd.popup_msg;
    gcd[k++].creator = GTextFieldCreate;
    hvarray[i][0] = &gcd[k-1]; hvarray[i++][1] = NULL;

    label[k].text = (unichar_t *) _("Select Results");
    label[k].text_is_1byte = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    gcd[k].gd.popup_msg = (unichar_t *) _("Set the selection of the font view to the glyphs\nwhich match");
    gcd[k++].creator = GRadioCreate;
    hvarray[i][0] = &gcd[k-1]; hvarray[i++][1] = NULL;

    label[k].text = (unichar_t *) _("Merge Results");
    label[k].text_is_1byte = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    gcd[k].gd.popup_msg = (unichar_t *) _("Expand the selection of the font view to include\nall the glyphs which match");
    gcd[k++].creator = GRadioCreate;
    hvarray[i][0] = &gcd[k-1]; hvarray[i++][1] = NULL;

    label[k].text = (unichar_t *) _("Restrict Selection");
    label[k].text_is_1byte = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    gcd[k].gd.popup_msg = (unichar_t *) _("Remove matching glyphs from the selection." );
    gcd[k++].creator = GRadioCreate;
    hvarray[i][0] = &gcd[k-1]; hvarray[i++][1] = NULL;

    label[k].text = (unichar_t *) _("Logical And with Selection");
    label[k].text_is_1byte = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    gcd[k].gd.popup_msg = (unichar_t *) _("Remove glyphs which do not match from the selection." );
    gcd[k++].creator = GRadioCreate;
    hvarray[i][0] = &gcd[k-1]; hvarray[i++][1] = NULL;
    gcd[k-4 + merge/4].gd.flags |= gg_cb_on;

    hvarray[i][0] = GCD_Glue; hvarray[i++][1] = NULL;

    label[k].text = (unichar_t *) _("_OK");
    label[k].text_is_1byte = true;
    label[k].text_in_resource = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_visible|gg_enabled | gg_but_default;
    gcd[k].gd.handle_controlevent = SS_OK;
    gcd[k++].creator = GButtonCreate;

    label[k].text = (unichar_t *) _("_Cancel");
    label[k].text_is_1byte = true;
    label[k].text_in_resource = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_visible|gg_enabled | gg_but_cancel;
    gcd[k].gd.handle_controlevent = SS_Cancel;
    gcd[k++].creator = GButtonCreate;

    barray[0] = barray[2] = barray[3] = barray[4] = barray[6] = GCD_Glue; barray[7] = NULL;
    barray[1] = &gcd[k-2]; barray[5] = &gcd[k-1];
    hvarray[i][0] = &boxes[2]; hvarray[i++][1] = NULL;
    hvarray[i][0] = NULL;

    memset(boxes,0,sizeof(boxes));
    boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
    boxes[0].gd.flags = gg_enabled|gg_visible;
    boxes[0].gd.u.boxelements = hvarray[0];
    boxes[0].creator = GHVGroupCreate;

    boxes[2].gd.flags = gg_enabled|gg_visible;
    boxes[2].gd.u.boxelements = barray;
    boxes[2].creator = GHBoxCreate;

    GGadgetsCreate(gw,boxes);
    GHVBoxSetExpandableCol(boxes[2].ret,gb_expandgluesame);
    GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);


    GHVBoxFitWindow(boxes[0].ret);

    GDrawSetVisible(gw,true);
    while ( !done ) {
	GDrawProcessOneEvent(NULL);
	if ( done==2 ) {
	    char *str = GGadgetGetTitle8(gcd[1].ret);
	    int merge = GGadgetIsChecked(gcd[2].ret) ? mt_set :
			GGadgetIsChecked(gcd[3].ret) ? mt_merge :
			GGadgetIsChecked(gcd[4].ret) ? mt_restrict :
						       mt_and;
	    int ret = FVSelectByName(fv,str,merge);
	    free(str);
	    if ( !ret )
		done = 0;
	}
    }
    GDrawDestroyWindow(gw);
}
static void FVMenuSelectByName(GWindow _gw, struct gmenuitem *UNUSED(mi), GEvent *e) {
    FontView *fv = (FontView *) GDrawGetUserData(_gw);
    GRect pos;
    GWindow gw;
    GWindowAttrs wattrs;
    GGadgetCreateData gcd[8], *hvarray[12][2], *barray[8], boxes[3];
    GTextInfo label[8];
    int merge = SelMergeType(e);
    int done=0,k,i;

    memset(&wattrs,0,sizeof(wattrs));
    memset(&gcd,0,sizeof(gcd));
    memset(&label,0,sizeof(label));
    memset(&boxes,0,sizeof(boxes));

    wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
    wattrs.event_masks = ~(1<<et_charup);
    wattrs.restrict_input_to_me = false;
    wattrs.undercursor = 1;
    wattrs.cursor = ct_pointer;
    wattrs.utf8_window_title = _("Select by Name");
    wattrs.is_dlg = false;
    pos.x = pos.y = 0;
    pos.width = 100;
    pos.height = 100;
    gw = GDrawCreateTopWindow(NULL,&pos,ss_e_h,&done,&wattrs);

    k = i = 0;

    label[k].text = (unichar_t *) _("Enter either a wildcard pattern (to match glyph names)\n or a unicode encoding like \"U+0065\".");
    label[k].text_is_1byte = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    gcd[k].gd.popup_msg = (unichar_t *) _(
	"Unix style wildcarding is accepted:\n"
	"Most characters match themselves\n"
	"A \"?\" will match any single character\n"
	"A \"*\" will match an arbitrary number of characters (including none)\n"
	"An \"[abd]\" set of characters within square brackets will match any (single) character\n"
	"A \"{scmp,c2sc}\" set of strings within curly brackets will match any string\n"
	"So \"a.*\" would match \"a.\" or \"a.sc\" or \"a.swash\"\n"
	"While \"a.{scmp,c2sc}\" would match \"a.scmp\" or \"a.c2sc\"\n"
	"And \"a.[abd]\" would match \"a.a\" or \"a.b\" or \"a.d\"");
    gcd[k++].creator = GLabelCreate;
    hvarray[i][0] = &gcd[k-1]; hvarray[i++][1] = NULL;

    gcd[k].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    gcd[k].gd.popup_msg = gcd[k-1].gd.popup_msg;
    gcd[k++].creator = GTextFieldCreate;
    hvarray[i][0] = &gcd[k-1]; hvarray[i++][1] = NULL;

    label[k].text = (unichar_t *) _("Select Results");
    label[k].text_is_1byte = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    gcd[k].gd.popup_msg = (unichar_t *) _("Set the selection of the font view to the glyphs\nwhich match");
    gcd[k++].creator = GRadioCreate;
    hvarray[i][0] = &gcd[k-1]; hvarray[i++][1] = NULL;

    label[k].text = (unichar_t *) _("Merge Results");
    label[k].text_is_1byte = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    gcd[k].gd.popup_msg = (unichar_t *) _("Expand the selection of the font view to include\nall the glyphs which match");
    gcd[k++].creator = GRadioCreate;
    hvarray[i][0] = &gcd[k-1]; hvarray[i++][1] = NULL;

    label[k].text = (unichar_t *) _("Restrict Selection");
    label[k].text_is_1byte = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    gcd[k].gd.popup_msg = (unichar_t *) _("Remove matching glyphs from the selection." );
    gcd[k++].creator = GRadioCreate;
    hvarray[i][0] = &gcd[k-1]; hvarray[i++][1] = NULL;

    label[k].text = (unichar_t *) _("Logical And with Selection");
    label[k].text_is_1byte = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    gcd[k].gd.popup_msg = (unichar_t *) _("Remove glyphs which do not match from the selection." );
    gcd[k++].creator = GRadioCreate;
    hvarray[i][0] = &gcd[k-1]; hvarray[i++][1] = NULL;
    gcd[k-4 + merge/4].gd.flags |= gg_cb_on;

    hvarray[i][0] = GCD_Glue; hvarray[i++][1] = NULL;

    label[k].text = (unichar_t *) _("_OK");
    label[k].text_is_1byte = true;
    label[k].text_in_resource = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_visible|gg_enabled | gg_but_default;
    gcd[k].gd.handle_controlevent = SS_OK;
    gcd[k++].creator = GButtonCreate;

    label[k].text = (unichar_t *) _("_Cancel");
    label[k].text_is_1byte = true;
    label[k].text_in_resource = true;
    gcd[k].gd.label = &label[k];
    gcd[k].gd.flags = gg_visible|gg_enabled | gg_but_cancel;
    gcd[k].gd.handle_controlevent = SS_Cancel;
    gcd[k++].creator = GButtonCreate;

    barray[0] = barray[2] = barray[3] = barray[4] = barray[6] = GCD_Glue; barray[7] = NULL;
    barray[1] = &gcd[k-2]; barray[5] = &gcd[k-1];
    hvarray[i][0] = &boxes[2]; hvarray[i++][1] = NULL;
    hvarray[i][0] = NULL;

    memset(boxes,0,sizeof(boxes));
    boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
    boxes[0].gd.flags = gg_enabled|gg_visible;
    boxes[0].gd.u.boxelements = hvarray[0];
    boxes[0].creator = GHVGroupCreate;

    boxes[2].gd.flags = gg_enabled|gg_visible;
    boxes[2].gd.u.boxelements = barray;
    boxes[2].creator = GHBoxCreate;

    GGadgetsCreate(gw,boxes);
    GHVBoxSetExpandableCol(boxes[2].ret,gb_expandgluesame);
    GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);


    GHVBoxFitWindow(boxes[0].ret);

    GDrawSetVisible(gw,true);
    while ( !done ) {
	GDrawProcessOneEvent(NULL);
	if ( done==2 ) {
	    char *str = GGadgetGetTitle8(gcd[1].ret);
	    int merge = GGadgetIsChecked(gcd[2].ret) ? mt_set :
			GGadgetIsChecked(gcd[3].ret) ? mt_merge :
			GGadgetIsChecked(gcd[4].ret) ? mt_restrict :
						       mt_and;
	    int ret = FVSelectByName(fv,str,merge);
	    free(str);
	    if ( !ret )
		done = 0;
	}
    }
    GDrawDestroyWindow(gw);
}