static Boolean do_choice(Widget w, SharedFontSelData *data, XmListCallbackStruct *call_data, enum ListSpecifier which) { char *sel; XmStringGetLtoR(call_data->item, XmSTRING_DEFAULT_CHARSET, &sel); if (!data->sel[which]) data->sel[which] = XtNewString(sel); else { if (!strcmp(data->sel[which], sel)) { /* unselecting current selection */ XtFree(data->sel[which]); data->sel[which] = NULL; if (w) XmListDeselectItem(w, call_data->item); } else { XtFree(data->sel[which]); data->sel[which] = XtNewString(sel); } } XtFree(sel); fill_lists(which, data); /* If there is a font selection, we display it. */ if (data->sel[ENCODING] && data->sel[NAME] && data->sel[STYLE] && data->sel[SIZE] && strcmp(data->sel[ENCODING], wild) && strcmp(data->sel[NAME], wild) && strcmp(data->sel[STYLE], wild) && strcmp(data->sel[SIZE], wild)) { int i; if (data->font_name) XtFree(data->font_name); data->font_name = NULL; for (i = 0; i < data->num; i++) { if (match(data, ENCODING, i) && match(data, NAME, i) && match(data, STYLE, i) && match(data, SIZE, i)) { data->font_name = XtNewString(fn(data, i)); break; } } if (data->font_name) { XmTextSetString(data->name, data->font_name); display_sample(data); } else do_dialog(VIM_ERROR, (char_u *)_("Error"), (char_u *)_("Invalid font specification"), (char_u *)_("&Dismiss"), 1, NULL); return True; } else { int n; XmString str; Arg args[4]; char *nomatch_msg = _("no specific match"); n = 0; str = XmStringCreateLocalized(nomatch_msg); XtSetArg(args[n], XmNlabelString, str); ++n; XtSetValues(data->sample, args, n); apply_fontlist(data->sample); XmTextSetString(data->name, nomatch_msg); XmStringFree(str); return False; } }
/* * Returns pointer to an ASCII character string that contains the name of the * selected font (in X format for naming fonts); it is the users responsibility * to free the space allocated to this string. */ char_u * gui_xm_select_font(char_u *current) { static SharedFontSelData _data; Widget parent; Widget form; Widget separator; Widget sub_form; Widget size_toggle; Widget name; Widget disp_frame; Widget frame; Arg args[64]; int n; XmString str; char big_font[MAX_FONT_NAME_LEN]; SharedFontSelData *data; data = &_data; parent = vimShell; data->names = XListFonts(XtDisplay(parent), "-*-*-*-*-*-*-*-*-*-*-*-*-*-*", MAX_FONTS, &data->num); /* * Find the name of the biggest font less than the given limit * MAX_DISPLAY_SIZE used to set up the initial height of the display * widget. */ { int i; int max; int index = 0; int size; char str[128]; for (i = 0, max = 0; i < data->num; i++) { get_part(fn(data, i), 7, str); size = atoi(str); if ((size > max) && (size < MAX_DISPLAY_SIZE)) { index = i; max = size; } } strcpy(big_font, fn(data, index)); } data->old = XLoadQueryFont(XtDisplay(parent), big_font); data->old_list = gui_motif_create_fontlist(data->old); /* Set the title of the Dialog window. */ data->dialog = XmCreateDialogShell(parent, "fontSelector", NULL, 0); str = XmStringCreateLocalized(_("Vim - Font Selector")); /* Create form popup dialog widget. */ form = XtVaCreateWidget("form", xmFormWidgetClass, data->dialog, XmNdialogTitle, str, XmNautoUnmanage, False, XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL, NULL); XmStringFree(str); sub_form = XtVaCreateManagedWidget("subForm", xmFormWidgetClass, form, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 4, XmNrightAttachment, XmATTACH_FORM, XmNrightOffset, 4, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 4, XmNorientation, XmVERTICAL, NULL); data->ok = XtVaCreateManagedWidget(_("OK"), xmPushButtonGadgetClass, sub_form, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 4, NULL); apply_fontlist(data->ok); data->cancel = XtVaCreateManagedWidget(_("Cancel"), xmPushButtonGadgetClass, sub_form, XmNrightAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_WIDGET, XmNtopWidget, data->ok, XmNtopOffset, 4, XmNshowAsDefault, True, NULL); apply_fontlist(data->cancel); /* Create the separator for beauty. */ n = 0; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, sub_form); n++; XtSetArg(args[n], XmNrightOffset, 4); n++; separator = XmCreateSeparatorGadget(form, "separator", args, n); XtManageChild(separator); /* Create font name text widget and the corresponding label. */ data->name = XtVaCreateManagedWidget("fontName", xmTextWidgetClass, form, XmNbottomAttachment, XmATTACH_FORM, XmNbottomOffset, 4, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 4, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, separator, XmNrightOffset, 4, XmNeditable, False, XmNeditMode, XmSINGLE_LINE_EDIT, XmNmaxLength, MAX_FONT_NAME_LEN, XmNcolumns, 60, NULL); str = XmStringCreateLocalized(_("Name:")); name = XtVaCreateManagedWidget("fontNameLabel", xmLabelGadgetClass, form, XmNlabelString, str, XmNuserData, data->name, XmNleftAttachment, XmATTACH_OPPOSITE_WIDGET, XmNleftWidget, data->name, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, data->name, XmNtopOffset, 1, NULL); XmStringFree(str); apply_fontlist(name); /* create sample display label widget */ disp_frame = XtVaCreateManagedWidget("sampleFrame", xmFrameWidgetClass, form, XmNshadowType, XmSHADOW_ETCHED_IN, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 4, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, name, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, separator, XmNrightOffset, 4, XmNalignment, XmALIGNMENT_BEGINNING, NULL); data->sample = XtVaCreateManagedWidget("sampleLabel", xmLabelWidgetClass, disp_frame, XmNleftAttachment, XmATTACH_FORM, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, XmNalignment, XmALIGNMENT_BEGINNING, XmNrecomputeSize, False, XmNfontList, data->old_list, NULL); /* create toggle button */ str = XmStringCreateLocalized(_("Show size in Points")); size_toggle = XtVaCreateManagedWidget("sizeToggle", xmToggleButtonGadgetClass, form, XmNlabelString, str, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 4, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, disp_frame, XmNbottomOffset, 4, NULL); XmStringFree(str); apply_fontlist(size_toggle); XtManageChild(size_toggle); /* Encoding pulldown menu. */ data->encoding_pulldown = XmCreatePulldownMenu(form, "encodingPulldown", NULL, 0); str = XmStringCreateLocalized(_("Encoding:")); n = 0; XtSetArg(args[n], XmNsubMenuId, data->encoding_pulldown); ++n; XtSetArg(args[n], XmNlabelString, str); ++n; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); ++n; XtSetArg(args[n], XmNleftOffset, 4); ++n; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); ++n; XtSetArg(args[n], XmNbottomWidget, size_toggle); ++n; XtSetArg(args[n], XmNbottomOffset, 4); ++n; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); ++n; XtSetArg(args[n], XmNrightWidget, separator); ++n; XtSetArg(args[n], XmNrightOffset, 4); ++n; data->encoding_menu = XmCreateOptionMenu(form, "encodingMenu", args, n); XmStringFree(str); XmAddTabGroup(data->encoding_menu); /* * Create scroll list widgets in a separate subform used to manage the * different sizes of the lists. */ sub_form = XtVaCreateManagedWidget("subForm", xmFormWidgetClass, form, XmNbottomAttachment, XmATTACH_WIDGET, XmNbottomWidget, data->encoding_menu, XmNbottomOffset, 4, XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, 4, XmNrightAttachment, XmATTACH_WIDGET, XmNrightWidget, separator, XmNrightOffset, 4, XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, 2, XmNorientation, XmVERTICAL, NULL); /* font list */ frame = XtVaCreateManagedWidget("frame", xmFrameWidgetClass, sub_form, XmNshadowThickness, 0, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 50, NULL); str = XmStringCreateLocalized(_("Font:")); name = XtVaCreateManagedWidget("nameListLabel", xmLabelGadgetClass, frame, XmNchildType, XmFRAME_TITLE_CHILD, XmNchildVerticalAlignment, XmALIGNMENT_CENTER, XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING, XmNlabelString, str, NULL); XmStringFree(str); apply_fontlist(name); n = 0; XtSetArg(args[n], XmNvisibleItemCount, 8); ++n; XtSetArg(args[n], XmNresizable, True); ++n; XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); ++n; XtSetArg(args[n], XmNvisualPolicy, XmVARIABLE); ++n; #ifdef LESSTIF_VERSION XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); ++n; #endif data->list[NAME] = XmCreateScrolledList(frame, "fontList", args, n); XtVaSetValues(name, XmNuserData, data->list[NAME], NULL); /* style list */ frame = XtVaCreateManagedWidget("frame", xmFrameWidgetClass, sub_form, XmNshadowThickness, 0, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 50, XmNleftOffset, 4, XmNrightAttachment, XmATTACH_POSITION, XmNrightPosition, 80, NULL); str = XmStringCreateLocalized(_("Style:")); name = XtVaCreateManagedWidget("styleListLabel", xmLabelWidgetClass, frame, XmNchildType, XmFRAME_TITLE_CHILD, XmNchildVerticalAlignment, XmALIGNMENT_CENTER, XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING, XmNlabelString, str, NULL); XmStringFree(str); apply_fontlist(name); n = 0; XtSetArg(args[n], XmNvisibleItemCount, 8); ++n; XtSetArg(args[n], XmNresizable, True); ++n; XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); ++n; XtSetArg(args[n], XmNvisualPolicy, XmVARIABLE); ++n; #ifdef LESSTIF_VERSION XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); ++n; #endif data->list[STYLE] = XmCreateScrolledList(frame, "styleList", args, n); XtVaSetValues(name, XmNuserData, data->list[STYLE], NULL); /* size list */ frame = XtVaCreateManagedWidget("frame", xmFrameWidgetClass, sub_form, XmNshadowThickness, 0, XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, XmNleftAttachment, XmATTACH_POSITION, XmNleftPosition, 80, XmNleftOffset, 4, XmNrightAttachment, XmATTACH_FORM, NULL); str = XmStringCreateLocalized(_("Size:")); name = XtVaCreateManagedWidget("sizeListLabel", xmLabelGadgetClass, frame, XmNchildType, XmFRAME_TITLE_CHILD, XmNchildVerticalAlignment, XmALIGNMENT_CENTER, XmNchildHorizontalAlignment, XmALIGNMENT_BEGINNING, XmNlabelString, str, NULL); XmStringFree(str); apply_fontlist(name); n = 0; XtSetArg(args[n], XmNvisibleItemCount, 8); ++n; XtSetArg(args[n], XmNresizable, True); ++n; XtSetArg(args[n], XmNlistSizePolicy, XmCONSTANT); ++n; XtSetArg(args[n], XmNvisualPolicy, XmVARIABLE); ++n; #ifdef LESSTIF_VERSION XtSetArg(args[n], XmNscrollBarDisplayPolicy, XmSTATIC); ++n; #endif data->list[SIZE] = XmCreateScrolledList(frame, "sizeList", args, n); XtVaSetValues(name, XmNuserData, data->list[SIZE], NULL); /* update form widgets cancel button */ XtVaSetValues(form, XmNcancelButton, data->cancel, NULL); XtAddCallback(size_toggle, XmNvalueChangedCallback, (XtCallbackProc)stoggle_callback, (XtPointer)data); XtAddCallback(data->list[NAME], XmNbrowseSelectionCallback, (XtCallbackProc)name_callback, (XtPointer)data); XtAddCallback(data->list[STYLE], XmNbrowseSelectionCallback, (XtCallbackProc)style_callback, (XtPointer)data); XtAddCallback(data->list[SIZE], XmNbrowseSelectionCallback, (XtCallbackProc)size_callback, (XtPointer)data); XtAddCallback(data->ok, XmNactivateCallback, (XtCallbackProc)ok_callback, (XtPointer)data); XtAddCallback(data->cancel, XmNactivateCallback, (XtCallbackProc)cancel_callback, (XtPointer)data); XmProcessTraversal(data->list[NAME], XmTRAVERSE_CURRENT); /* setup tabgroups */ XmAddTabGroup(data->list[NAME]); XmAddTabGroup(data->list[STYLE]); XmAddTabGroup(data->list[SIZE]); XmAddTabGroup(size_toggle); XmAddTabGroup(data->name); XmAddTabGroup(data->ok); XmAddTabGroup(data->cancel); add_cancel_action(data->dialog, (XtCallbackProc)cancel_callback, data); /* Preset selection data. */ data->exit = False; data->in_pixels= True; data->sel[ENCODING] = NULL; data->sel[NAME] = NULL; data->sel[STYLE] = NULL; data->sel[SIZE] = NULL; data->font_name = NULL; /* set up current font parameters */ if (current && current[0] != '\0') { int i; char **names; names = XListFonts(XtDisplay(form), (char *) current, 1, &i); if (i != 0) { char name[TEMP_BUF_SIZE]; char style[TEMP_BUF_SIZE]; char size[TEMP_BUF_SIZE]; char encoding[TEMP_BUF_SIZE]; char *found; found = names[0]; name_part(found, name); style_part(found, style); size_part(found, size, data->in_pixels); encoding_part(found, encoding); if (strlen(name) > 0 && strlen(style) > 0 && strlen(size) > 0 && strlen(encoding) > 0) { data->sel[NAME] = XtNewString(name); data->sel[STYLE] = XtNewString(style); data->sel[SIZE] = XtNewString(size); data->sel[ENCODING] = XtNewString(encoding); data->font_name = XtNewString(names[0]); display_sample(data); XmTextSetString(data->name, data->font_name); } else { /* We can't preset a symbolic name, which isn't a full font * description. Therefore we just behave the same way as if the * user didn't have selected anything thus far. * * Unfortunately there is no known way to expand an abbreviated * font name. */ data->font_name = NULL; } } XFreeFontNames(names); } fill_lists(NONE, data); /* Unfortunately LessTif doesn't align the list widget's properly. I don't * have currently any idea how to fix this problem. */ XtManageChild(data->list[NAME]); XtManageChild(data->list[STYLE]); XtManageChild(data->list[SIZE]); XtManageChild(data->encoding_menu); manage_centered(form); /* modal event loop */ while (!data->exit) XtAppProcessEvent(XtWidgetToApplicationContext(data->dialog), (XtInputMask)XtIMAll); XtDestroyWidget(data->dialog); if (data->old) { XFreeFont(XtDisplay(data->dialog), data->old); XmFontListFree(data->old_list); } gui_motif_synch_fonts(); return (char_u *) data->font_name; }