1 /* vi:set ts=8 sts=4 sw=4:
3 * VIM - Vi IMproved by Bram Moolenaar
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
11 * (C) 2001,2005 by Marcin Dalecki <martin@dalecki.de>
13 * Implementation of dialogue functions for the Motif GUI variant.
15 * Note about Lesstif: Apparently lesstif doesn't get the widget layout right,
16 * when using a dynamic scrollbar policy.
20 #include <Xm/PushBG.h>
25 #include <Xm/LabelG.h>
26 #include <Xm/ToggleBG.h>
27 #include <Xm/SeparatoG.h>
28 #include <Xm/DialogS.h>
30 #include <Xm/RowColumn.h>
31 #include <Xm/AtomMgr.h>
32 #include <Xm/Protocols.h>
34 #include <X11/keysym.h>
35 #include <X11/Xatom.h>
36 #include <X11/StringDefs.h>
37 #include <X11/Intrinsic.h>
41 extern Widget vimShell
;
44 # define apply_fontlist(w) gui_motif_menu_fontlist(w)
46 # define apply_fontlist(w)
49 /****************************************************************************
50 * Font selection dialogue implementation.
53 static char wild
[3] = "*";
56 * FIXME: This is a generic function, which should be used throughout the whole
59 * Add close_callback, which will be called when the user selects close from
60 * the window menu. The close menu item usually activates f.kill which sends a
61 * WM_DELETE_WINDOW protocol request for the window.
65 add_cancel_action(Widget shell
, XtCallbackProc close_callback
, void *arg
)
67 static Atom wmp_atom
= 0;
68 static Atom dw_atom
= 0;
69 Display
*display
= XtDisplay(shell
);
71 /* deactivate the built-in delete response of killing the application */
72 XtVaSetValues(shell
, XmNdeleteResponse
, XmDO_NOTHING
, NULL
);
74 /* add a delete window protocol callback instead */
77 wmp_atom
= XmInternAtom(display
, "WM_PROTOCOLS", True
);
78 dw_atom
= XmInternAtom(display
, "WM_DELETE_WINDOW", True
);
80 XmAddProtocolCallback(shell
, wmp_atom
, dw_atom
, close_callback
, arg
);
83 #define MAX_FONTS 65535
84 #define MAX_FONT_NAME_LEN 256
85 #define MAX_ENTRIES_IN_LIST 5000
86 #define MAX_DISPLAY_SIZE 150
87 #define TEMP_BUF_SIZE 256
98 typedef struct _SharedFontSelData
103 Widget encoding_pulldown
;
104 Widget encoding_menu
;
108 char **names
; /* font name array of arrays */
109 int num
; /* number of font names */
110 String sel
[NONE
]; /* selection category */
111 Boolean in_pixels
; /* toggle state - size in pixels */
112 char *font_name
; /* current font name */
113 XFontStruct
*old
; /* font data structure for sample display */
114 XmFontList old_list
; /* font data structure for sample display */
115 Boolean exit
; /* used for program exit control */
119 * Checking access to the font name array for validity.
122 fn(SharedFontSelData
*data
, int i
)
124 /* Assertion checks: */
132 return data
->names
[i
];
136 * Get a specific substring from a font name.
139 get_part(char *in
, int pos
, char *out
)
146 for (i
= 0; (pos
> 0) && (in
[i
] != '\0'); ++i
)
153 for (j
= 0; (in
[i
] != '-') && (in
[i
] != '\0'); ++i
, ++j
)
159 * Given a font name this function returns the part used in the first
163 name_part(char *font
, char *buf
)
165 char buf2
[TEMP_BUF_SIZE
];
166 char buf3
[TEMP_BUF_SIZE
];
168 get_part(font
, 2, buf2
);
169 get_part(font
, 1, buf3
);
172 vim_snprintf(buf
, TEMP_BUF_SIZE
, "%s (%s)", buf2
, buf3
);
174 vim_snprintf(buf
, TEMP_BUF_SIZE
, "%s", buf2
);
178 * Given a font name this function returns the part used in the second scroll list.
181 style_part(char *font
, char *buf
)
183 char buf2
[TEMP_BUF_SIZE
];
184 char buf3
[TEMP_BUF_SIZE
];
186 get_part(font
, 3, buf3
);
187 get_part(font
, 5, buf2
);
189 if (!strcmp(buf2
, "normal") && !strcmp(buf2
, "Normal")
190 && !strcmp(buf2
, "NORMAL"))
191 vim_snprintf(buf
, TEMP_BUF_SIZE
, "%s %s", buf3
, buf2
);
195 get_part(font
, 6, buf2
);
198 vim_snprintf(buf3
, TEMP_BUF_SIZE
, "%s %s", buf
, buf2
);
202 get_part(font
, 4, buf2
);
204 if (!strcmp(buf2
, "o") || !strcmp(buf2
, "O"))
205 vim_snprintf(buf
, TEMP_BUF_SIZE
, "%s oblique", buf3
);
206 else if (!strcmp(buf2
, "i") || !strcmp(buf2
, "I"))
207 vim_snprintf(buf
, TEMP_BUF_SIZE
, "%s italic", buf3
);
209 if (!strcmp(buf
, " "))
214 * Given a font name this function returns the part used in the third
218 size_part(char *font
, char *buf
, int inPixels
)
227 get_part(font
, 7, buf
);
231 sprintf(buf
, "%3d", size
);
236 get_part(font
, 8, buf
);
240 temp
= (float)size
/ 10.0;
242 if (buf
[strlen(buf
) - 1] == '0')
243 sprintf(buf
, "%3d", size
);
245 sprintf(buf
, "%4.1f", temp
);
251 * Given a font name this function returns the part used in the choice menu.
254 encoding_part(char *font
, char *buf
)
256 char buf1
[TEMP_BUF_SIZE
];
257 char buf2
[TEMP_BUF_SIZE
];
261 get_part(font
, 13, buf1
);
262 get_part(font
, 14, buf2
);
264 if (strlen(buf1
) > 0 && strlen(buf2
))
265 vim_snprintf(buf
, TEMP_BUF_SIZE
, "%s-%s", buf1
, buf2
);
266 if (!strcmp(buf
, " "))
271 * Inserts a string into correct sorted position in a list.
274 add_to_list(char **buf
, char *item
, int *count
)
279 if (*count
== MAX_ENTRIES_IN_LIST
)
282 /* avoid duplication */
283 for (i
= 0; i
< *count
; ++i
)
285 if (!strcmp(buf
[i
], item
))
289 /* find order place, but make sure that wild card comes first */
290 if (!strcmp(item
, wild
))
293 for (i
= 0; i
< *count
; ++i
)
294 if (strcmp(buf
[i
], item
) > 0 && strcmp(buf
[i
], wild
))
297 /* now insert the item */
298 for (j
= *count
; j
> i
; --j
)
300 buf
[i
] = XtNewString(item
);
306 * True if the font matches some field.
309 match(SharedFontSelData
*data
, enum ListSpecifier l
, int i
)
311 char buf
[TEMP_BUF_SIZE
];
313 /* An empty selection or a wild card matches anything.
315 if (!data
->sel
[l
] || !strcmp(data
->sel
[l
], wild
))
318 /* chunk out the desired part... */
322 encoding_part(fn(data
, i
), buf
);
326 name_part(fn(data
, i
), buf
);
330 style_part(fn(data
, i
), buf
);
334 size_part(fn(data
, i
), buf
, data
->in_pixels
);
340 /* ...and chew it now */
342 return !strcmp(buf
, data
->sel
[l
]);
346 proportional(char *font
)
348 char buf
[TEMP_BUF_SIZE
];
350 get_part(font
, 11, buf
);
352 return !strcmp(buf
, "p") || !strcmp(buf
, "P");
356 static void encoding_callback(Widget w
, SharedFontSelData
*data
,
360 * Parse through the fontlist data and set up the three scroll lists. The fix
361 * parameter can be used to exclude a list from any changes. This is used for
362 * updates after selections caused by the users actions.
365 fill_lists(enum ListSpecifier fix
, SharedFontSelData
*data
)
367 char *list
[NONE
][MAX_ENTRIES_IN_LIST
];
369 char buf
[TEMP_BUF_SIZE
];
370 XmString items
[MAX_ENTRIES_IN_LIST
];
374 for (idx
= (int)ENCODING
; idx
< (int)NONE
; ++idx
)
377 /* First we insert the wild char into every single list. */
379 add_to_list(list
[ENCODING
], wild
, &count
[ENCODING
]);
381 add_to_list(list
[NAME
], wild
, &count
[NAME
]);
383 add_to_list(list
[STYLE
], wild
, &count
[STYLE
]);
385 add_to_list(list
[SIZE
], wild
, &count
[SIZE
]);
387 for (i
= 0; i
< data
->num
&& i
< MAX_ENTRIES_IN_LIST
; i
++)
389 if (proportional(fn(data
, i
)))
393 && match(data
, NAME
, i
)
394 && match(data
, STYLE
, i
)
395 && match(data
, SIZE
, i
))
397 encoding_part(fn(data
, i
), buf
);
398 add_to_list(list
[ENCODING
], buf
, &count
[ENCODING
]);
402 && match(data
, ENCODING
, i
)
403 && match(data
, STYLE
, i
)
404 && match(data
, SIZE
, i
))
406 name_part(fn(data
, i
), buf
);
407 add_to_list(list
[NAME
], buf
, &count
[NAME
]);
411 && match(data
, ENCODING
, i
)
412 && match(data
, NAME
, i
)
413 && match(data
, SIZE
, i
))
415 style_part(fn(data
, i
), buf
);
416 add_to_list(list
[STYLE
], buf
, &count
[STYLE
]);
420 && match(data
, ENCODING
, i
)
421 && match(data
, NAME
, i
)
422 && match(data
, STYLE
, i
))
424 size_part(fn(data
, i
), buf
, data
->in_pixels
);
425 add_to_list(list
[SIZE
], buf
, &count
[SIZE
]);
430 * And now do the preselection in all lists where there was one:
437 Widget selected_button
= 0;
439 /* Get and update the current button list. */
440 XtVaGetValues(data
->encoding_pulldown
,
441 XmNchildren
, &children
,
442 XmNnumChildren
, &n_items
,
445 for (i
= 0; i
< count
[ENCODING
]; ++i
)
449 items
[i
] = XmStringCreateLocalized(list
[ENCODING
][i
]);
451 if (i
< (int)n_items
)
453 /* recycle old button */
454 XtVaSetValues(children
[i
],
455 XmNlabelString
, items
[i
],
458 button
= children
[i
];
462 /* create a new button */
463 button
= XtVaCreateManagedWidget("button",
464 xmPushButtonGadgetClass
,
465 data
->encoding_pulldown
,
466 XmNlabelString
, items
[i
],
469 XtAddCallback(button
, XmNactivateCallback
,
470 (XtCallbackProc
) encoding_callback
, (XtPointer
) data
);
471 XtManageChild(button
);
474 if (data
->sel
[ENCODING
])
476 if (!strcmp(data
->sel
[ENCODING
], list
[ENCODING
][i
]))
477 selected_button
= button
;
479 XtFree(list
[ENCODING
][i
]);
482 /* Destroy all the outstanding menu items.
484 for (i
= count
[ENCODING
]; i
< (int)n_items
; ++i
)
486 XtUnmanageChild(children
[i
]);
487 XtDestroyWidget(children
[i
]);
490 /* Preserve the current selection visually.
494 XtVaSetValues(data
->encoding_menu
,
495 XmNmenuHistory
, selected_button
,
499 for (i
= 0; i
< count
[ENCODING
]; ++i
)
500 XmStringFree(items
[i
]);
504 * Now loop trough the remaining lists and set them up.
506 for (idx
= (int)NAME
; idx
< (int)NONE
; ++idx
)
510 if (fix
== (enum ListSpecifier
)idx
)
513 switch ((enum ListSpecifier
)idx
)
516 w
= data
->list
[NAME
];
519 w
= data
->list
[STYLE
];
522 w
= data
->list
[SIZE
];
525 w
= (Widget
)0; /* for lint */
528 for (i
= 0; i
< count
[idx
]; ++i
)
530 items
[i
] = XmStringCreateLocalized(list
[idx
][i
]);
531 XtFree(list
[idx
][i
]);
533 XmListDeleteAllItems(w
);
534 XmListAddItems(w
, items
, count
[idx
], 1);
537 XmStringFree(items
[0]);
538 items
[0] = XmStringCreateLocalized(data
->sel
[idx
]);
539 XmListSelectItem(w
, items
[0], False
);
540 XmListSetBottomItem(w
, items
[0]);
542 for (i
= 0; i
< count
[idx
]; ++i
)
543 XmStringFree(items
[i
]);
548 stoggle_callback(Widget w UNUSED
,
549 SharedFontSelData
*data
,
550 XmToggleButtonCallbackStruct
*call_data
)
553 char newSize
[TEMP_BUF_SIZE
];
556 if (call_data
->reason
!= (int)XmCR_VALUE_CHANGED
)
559 do_sel
= (data
->sel
[SIZE
] != NULL
) && strcmp(data
->sel
[SIZE
], wild
);
561 for (i
= 0; do_sel
&& (i
< data
->num
); i
++)
562 if (match(data
, ENCODING
, i
)
563 && match(data
, NAME
, i
)
564 && match(data
, STYLE
, i
)
565 && match(data
, SIZE
, i
))
567 size_part(fn(data
, i
), newSize
, !data
->in_pixels
);
571 data
->in_pixels
= !data
->in_pixels
;
574 XtFree(data
->sel
[SIZE
]);
575 data
->sel
[SIZE
] = NULL
;
576 fill_lists(NONE
, data
);
580 str
= XmStringCreateLocalized(newSize
);
581 XmListSelectItem(data
->list
[SIZE
], str
, True
);
582 XmListSetBottomItem(data
->list
[SIZE
], str
);
588 * Show the currently selected font in the sample text label.
591 display_sample(SharedFontSelData
*data
)
596 XmFontList font_list
;
600 display
= XtDisplay(data
->dialog
);
601 font
= XLoadQueryFont(display
, data
->font_name
);
602 font_list
= gui_motif_create_fontlist(font
);
605 str
= XmStringCreateLocalized("AaBbZzYy 0123456789");
606 XtSetArg(args
[n
], XmNlabelString
, str
); n
++;
607 XtSetArg(args
[n
], XmNfontList
, font_list
); n
++;
609 XtSetValues(data
->sample
, args
, n
);
614 XFreeFont(display
, data
->old
);
615 XmFontListFree(data
->old_list
);
618 data
->old_list
= font_list
;
624 SharedFontSelData
*data
,
625 XmListCallbackStruct
*call_data
,
626 enum ListSpecifier which
)
630 XmStringGetLtoR(call_data
->item
, XmSTRING_DEFAULT_CHARSET
, &sel
);
632 if (!data
->sel
[which
])
633 data
->sel
[which
] = XtNewString(sel
);
636 XtFree(data
->sel
[which
]);
637 if (!strcmp(data
->sel
[which
], sel
))
639 /* unselecting current selection */
640 data
->sel
[which
] = NULL
;
642 XmListDeselectItem(w
, call_data
->item
);
645 data
->sel
[which
] = XtNewString(sel
);
649 fill_lists(which
, data
);
651 /* If there is a font selection, we display it. */
652 if (data
->sel
[ENCODING
]
656 && strcmp(data
->sel
[ENCODING
], wild
)
657 && strcmp(data
->sel
[NAME
], wild
)
658 && strcmp(data
->sel
[STYLE
], wild
)
659 && strcmp(data
->sel
[SIZE
], wild
))
664 XtFree(data
->font_name
);
665 data
->font_name
= NULL
;
667 for (i
= 0; i
< data
->num
; i
++)
669 if (match(data
, ENCODING
, i
)
670 && match(data
, NAME
, i
)
671 && match(data
, STYLE
, i
)
672 && match(data
, SIZE
, i
))
674 data
->font_name
= XtNewString(fn(data
, i
));
681 XmTextSetString(data
->name
, data
->font_name
);
682 display_sample(data
);
686 (char_u
*)_("Error"),
687 (char_u
*)_("Invalid font specification"),
688 (char_u
*)_("&Dismiss"), 1, NULL
);
697 char *nomatch_msg
= _("no specific match");
700 str
= XmStringCreateLocalized(nomatch_msg
);
701 XtSetArg(args
[n
], XmNlabelString
, str
); ++n
;
702 XtSetValues(data
->sample
, args
, n
);
703 apply_fontlist(data
->sample
);
704 XmTextSetString(data
->name
, nomatch_msg
);
712 encoding_callback(Widget w
,
713 SharedFontSelData
*data
,
714 XtPointer dummy UNUSED
)
717 XmListCallbackStruct fake_data
;
719 XtVaGetValues(w
, XmNlabelString
, &str
, NULL
);
724 fake_data
.item
= str
;
726 do_choice(0, data
, &fake_data
, ENCODING
);
730 name_callback(Widget w
,
731 SharedFontSelData
*data
,
732 XmListCallbackStruct
*call_data
)
734 do_choice(w
, data
, call_data
, NAME
);
738 style_callback(Widget w
,
739 SharedFontSelData
*data
,
740 XmListCallbackStruct
*call_data
)
742 do_choice(w
, data
, call_data
, STYLE
);
746 size_callback(Widget w
,
747 SharedFontSelData
*data
,
748 XmListCallbackStruct
*call_data
)
750 do_choice(w
, data
, call_data
, SIZE
);
754 cancel_callback(Widget w UNUSED
,
755 SharedFontSelData
*data
,
756 XmListCallbackStruct
*call_data UNUSED
)
758 if (data
->sel
[ENCODING
])
760 XtFree(data
->sel
[ENCODING
]);
761 data
->sel
[ENCODING
] = NULL
;
765 XtFree(data
->sel
[NAME
]);
766 data
->sel
[NAME
] = NULL
;
768 if (data
->sel
[STYLE
])
770 XtFree(data
->sel
[STYLE
]);
771 data
->sel
[STYLE
] = NULL
;
775 XtFree(data
->sel
[SIZE
]);
776 data
->sel
[SIZE
] = NULL
;
780 XtFree(data
->font_name
);
781 data
->font_name
= NULL
;
784 XFreeFontNames(data
->names
);
790 ok_callback(Widget w UNUSED
,
791 SharedFontSelData
*data
,
792 XmPushButtonCallbackStruct
*call_data UNUSED
)
798 pattern
= XmTextGetString(data
->name
);
799 name
= XListFonts(XtDisplay(data
->dialog
), pattern
, 1, &i
);
805 (char_u
*)_("Error"),
806 (char_u
*)_("Invalid font specification"),
807 (char_u
*)_("&Dismiss"), 1, NULL
);
808 XFreeFontNames(name
);
813 XtFree(data
->font_name
);
814 data
->font_name
= XtNewString(name
[0]);
816 if (data
->sel
[ENCODING
])
818 XtFree(data
->sel
[ENCODING
]);
819 data
->sel
[ENCODING
] = NULL
;
823 XtFree(data
->sel
[NAME
]);
824 data
->sel
[NAME
] = NULL
;
826 if (data
->sel
[STYLE
])
828 XtFree(data
->sel
[STYLE
]);
829 data
->sel
[STYLE
] = NULL
;
833 XtFree(data
->sel
[SIZE
]);
834 data
->sel
[SIZE
] = NULL
;
837 XFreeFontNames(name
);
840 XFreeFontNames(data
->names
);
847 * Returns pointer to an ASCII character string that contains the name of the
848 * selected font (in X format for naming fonts); it is the users responsibility
849 * to free the space allocated to this string.
852 gui_xm_select_font(char_u
*current
)
854 static SharedFontSelData _data
;
867 char big_font
[MAX_FONT_NAME_LEN
];
868 SharedFontSelData
*data
;
873 data
->names
= XListFonts(XtDisplay(parent
), "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
874 MAX_FONTS
, &data
->num
);
877 * Find the name of the biggest font less than the given limit
878 * MAX_DISPLAY_SIZE used to set up the initial height of the display
889 for (i
= 0, max
= 0; i
< data
->num
; i
++)
891 get_part(fn(data
, i
), 7, buf
);
893 if ((size
> max
) && (size
< MAX_DISPLAY_SIZE
))
899 strcpy(big_font
, fn(data
, idx
));
901 data
->old
= XLoadQueryFont(XtDisplay(parent
), big_font
);
902 data
->old_list
= gui_motif_create_fontlist(data
->old
);
904 /* Set the title of the Dialog window. */
905 data
->dialog
= XmCreateDialogShell(parent
, "fontSelector", NULL
, 0);
906 str
= XmStringCreateLocalized(_("Vim - Font Selector"));
908 /* Create form popup dialog widget. */
909 form
= XtVaCreateWidget("form",
910 xmFormWidgetClass
, data
->dialog
,
912 XmNautoUnmanage
, False
,
913 XmNdialogStyle
, XmDIALOG_FULL_APPLICATION_MODAL
,
917 sub_form
= XtVaCreateManagedWidget("subForm",
918 xmFormWidgetClass
, form
,
919 XmNbottomAttachment
, XmATTACH_FORM
,
921 XmNrightAttachment
, XmATTACH_FORM
,
923 XmNtopAttachment
, XmATTACH_FORM
,
925 XmNorientation
, XmVERTICAL
,
928 data
->ok
= XtVaCreateManagedWidget(_("OK"),
929 xmPushButtonGadgetClass
, sub_form
,
930 XmNleftAttachment
, XmATTACH_FORM
,
931 XmNrightAttachment
, XmATTACH_FORM
,
932 XmNtopAttachment
, XmATTACH_FORM
,
935 apply_fontlist(data
->ok
);
937 data
->cancel
= XtVaCreateManagedWidget(_("Cancel"),
938 xmPushButtonGadgetClass
, sub_form
,
939 XmNrightAttachment
, XmATTACH_FORM
,
940 XmNleftAttachment
, XmATTACH_FORM
,
941 XmNtopAttachment
, XmATTACH_WIDGET
,
942 XmNtopWidget
, data
->ok
,
944 XmNshowAsDefault
, True
,
946 apply_fontlist(data
->cancel
);
948 /* Create the separator for beauty. */
950 XtSetArg(args
[n
], XmNorientation
, XmVERTICAL
); n
++;
951 XtSetArg(args
[n
], XmNbottomAttachment
, XmATTACH_FORM
); n
++;
952 XtSetArg(args
[n
], XmNtopAttachment
, XmATTACH_FORM
); n
++;
953 XtSetArg(args
[n
], XmNrightAttachment
, XmATTACH_WIDGET
); n
++;
954 XtSetArg(args
[n
], XmNrightWidget
, sub_form
); n
++;
955 XtSetArg(args
[n
], XmNrightOffset
, 4); n
++;
956 separator
= XmCreateSeparatorGadget(form
, "separator", args
, n
);
957 XtManageChild(separator
);
959 /* Create font name text widget and the corresponding label. */
960 data
->name
= XtVaCreateManagedWidget("fontName",
961 xmTextWidgetClass
, form
,
962 XmNbottomAttachment
, XmATTACH_FORM
,
964 XmNleftAttachment
, XmATTACH_FORM
,
966 XmNrightAttachment
, XmATTACH_WIDGET
,
967 XmNrightWidget
, separator
,
970 XmNeditMode
, XmSINGLE_LINE_EDIT
,
971 XmNmaxLength
, MAX_FONT_NAME_LEN
,
975 str
= XmStringCreateLocalized(_("Name:"));
976 name
= XtVaCreateManagedWidget("fontNameLabel",
977 xmLabelGadgetClass
, form
,
979 XmNuserData
, data
->name
,
980 XmNleftAttachment
, XmATTACH_OPPOSITE_WIDGET
,
981 XmNleftWidget
, data
->name
,
982 XmNbottomAttachment
, XmATTACH_WIDGET
,
983 XmNbottomWidget
, data
->name
,
987 apply_fontlist(name
);
989 /* create sample display label widget */
990 disp_frame
= XtVaCreateManagedWidget("sampleFrame",
991 xmFrameWidgetClass
, form
,
992 XmNshadowType
, XmSHADOW_ETCHED_IN
,
993 XmNleftAttachment
, XmATTACH_FORM
,
995 XmNbottomAttachment
, XmATTACH_WIDGET
,
996 XmNbottomWidget
, name
,
997 XmNrightAttachment
, XmATTACH_WIDGET
,
998 XmNrightWidget
, separator
,
1000 XmNalignment
, XmALIGNMENT_BEGINNING
,
1003 data
->sample
= XtVaCreateManagedWidget("sampleLabel",
1004 xmLabelWidgetClass
, disp_frame
,
1005 XmNleftAttachment
, XmATTACH_FORM
,
1006 XmNtopAttachment
, XmATTACH_FORM
,
1007 XmNbottomAttachment
, XmATTACH_FORM
,
1008 XmNrightAttachment
, XmATTACH_FORM
,
1009 XmNalignment
, XmALIGNMENT_BEGINNING
,
1010 XmNrecomputeSize
, False
,
1011 XmNfontList
, data
->old_list
,
1014 /* create toggle button */
1015 str
= XmStringCreateLocalized(_("Show size in Points"));
1016 size_toggle
= XtVaCreateManagedWidget("sizeToggle",
1017 xmToggleButtonGadgetClass
, form
,
1018 XmNlabelString
, str
,
1019 XmNleftAttachment
, XmATTACH_FORM
,
1021 XmNbottomAttachment
, XmATTACH_WIDGET
,
1022 XmNbottomWidget
, disp_frame
,
1026 apply_fontlist(size_toggle
);
1027 XtManageChild(size_toggle
);
1029 /* Encoding pulldown menu.
1032 data
->encoding_pulldown
= XmCreatePulldownMenu(form
,
1033 "encodingPulldown", NULL
, 0);
1034 str
= XmStringCreateLocalized(_("Encoding:"));
1036 XtSetArg(args
[n
], XmNsubMenuId
, data
->encoding_pulldown
); ++n
;
1037 XtSetArg(args
[n
], XmNlabelString
, str
); ++n
;
1038 XtSetArg(args
[n
], XmNleftAttachment
, XmATTACH_FORM
); ++n
;
1039 XtSetArg(args
[n
], XmNleftOffset
, 4); ++n
;
1040 XtSetArg(args
[n
], XmNbottomAttachment
, XmATTACH_WIDGET
); ++n
;
1041 XtSetArg(args
[n
], XmNbottomWidget
, size_toggle
); ++n
;
1042 XtSetArg(args
[n
], XmNbottomOffset
, 4); ++n
;
1043 XtSetArg(args
[n
], XmNrightAttachment
, XmATTACH_WIDGET
); ++n
;
1044 XtSetArg(args
[n
], XmNrightWidget
, separator
); ++n
;
1045 XtSetArg(args
[n
], XmNrightOffset
, 4); ++n
;
1046 data
->encoding_menu
= XmCreateOptionMenu(form
, "encodingMenu", args
, n
);
1048 XmAddTabGroup(data
->encoding_menu
);
1051 * Create scroll list widgets in a separate subform used to manage the
1052 * different sizes of the lists.
1055 sub_form
= XtVaCreateManagedWidget("subForm",
1056 xmFormWidgetClass
, form
,
1057 XmNbottomAttachment
, XmATTACH_WIDGET
,
1058 XmNbottomWidget
, data
->encoding_menu
,
1060 XmNleftAttachment
, XmATTACH_FORM
,
1062 XmNrightAttachment
, XmATTACH_WIDGET
,
1063 XmNrightWidget
, separator
,
1065 XmNtopAttachment
, XmATTACH_FORM
,
1067 XmNorientation
, XmVERTICAL
,
1071 frame
= XtVaCreateManagedWidget("frame", xmFrameWidgetClass
, sub_form
,
1072 XmNshadowThickness
, 0,
1073 XmNtopAttachment
, XmATTACH_FORM
,
1074 XmNbottomAttachment
, XmATTACH_FORM
,
1075 XmNleftAttachment
, XmATTACH_FORM
,
1076 XmNrightAttachment
, XmATTACH_POSITION
,
1077 XmNrightPosition
, 50,
1080 str
= XmStringCreateLocalized(_("Font:"));
1081 name
= XtVaCreateManagedWidget("nameListLabel", xmLabelGadgetClass
, frame
,
1082 XmNchildType
, XmFRAME_TITLE_CHILD
,
1083 XmNchildVerticalAlignment
, XmALIGNMENT_CENTER
,
1084 XmNchildHorizontalAlignment
, XmALIGNMENT_BEGINNING
,
1085 XmNlabelString
, str
,
1088 apply_fontlist(name
);
1091 XtSetArg(args
[n
], XmNvisibleItemCount
, 8); ++n
;
1092 XtSetArg(args
[n
], XmNresizable
, True
); ++n
;
1093 XtSetArg(args
[n
], XmNlistSizePolicy
, XmCONSTANT
); ++n
;
1094 XtSetArg(args
[n
], XmNvisualPolicy
, XmVARIABLE
); ++n
;
1095 #ifdef LESSTIF_VERSION
1096 XtSetArg(args
[n
], XmNscrollBarDisplayPolicy
, XmSTATIC
); ++n
;
1098 data
->list
[NAME
] = XmCreateScrolledList(frame
, "fontList", args
, n
);
1099 XtVaSetValues(name
, XmNuserData
, data
->list
[NAME
], NULL
);
1102 frame
= XtVaCreateManagedWidget("frame", xmFrameWidgetClass
, sub_form
,
1103 XmNshadowThickness
, 0,
1104 XmNtopAttachment
, XmATTACH_FORM
,
1105 XmNbottomAttachment
, XmATTACH_FORM
,
1106 XmNleftAttachment
, XmATTACH_POSITION
,
1107 XmNleftPosition
, 50,
1109 XmNrightAttachment
, XmATTACH_POSITION
,
1110 XmNrightPosition
, 80,
1113 str
= XmStringCreateLocalized(_("Style:"));
1114 name
= XtVaCreateManagedWidget("styleListLabel", xmLabelWidgetClass
, frame
,
1115 XmNchildType
, XmFRAME_TITLE_CHILD
,
1116 XmNchildVerticalAlignment
, XmALIGNMENT_CENTER
,
1117 XmNchildHorizontalAlignment
, XmALIGNMENT_BEGINNING
,
1118 XmNlabelString
, str
,
1121 apply_fontlist(name
);
1124 XtSetArg(args
[n
], XmNvisibleItemCount
, 8); ++n
;
1125 XtSetArg(args
[n
], XmNresizable
, True
); ++n
;
1126 XtSetArg(args
[n
], XmNlistSizePolicy
, XmCONSTANT
); ++n
;
1127 XtSetArg(args
[n
], XmNvisualPolicy
, XmVARIABLE
); ++n
;
1128 #ifdef LESSTIF_VERSION
1129 XtSetArg(args
[n
], XmNscrollBarDisplayPolicy
, XmSTATIC
); ++n
;
1131 data
->list
[STYLE
] = XmCreateScrolledList(frame
, "styleList", args
, n
);
1132 XtVaSetValues(name
, XmNuserData
, data
->list
[STYLE
], NULL
);
1135 frame
= XtVaCreateManagedWidget("frame", xmFrameWidgetClass
, sub_form
,
1136 XmNshadowThickness
, 0,
1137 XmNtopAttachment
, XmATTACH_FORM
,
1138 XmNbottomAttachment
, XmATTACH_FORM
,
1139 XmNleftAttachment
, XmATTACH_POSITION
,
1140 XmNleftPosition
, 80,
1142 XmNrightAttachment
, XmATTACH_FORM
,
1145 str
= XmStringCreateLocalized(_("Size:"));
1146 name
= XtVaCreateManagedWidget("sizeListLabel", xmLabelGadgetClass
, frame
,
1147 XmNchildType
, XmFRAME_TITLE_CHILD
,
1148 XmNchildVerticalAlignment
, XmALIGNMENT_CENTER
,
1149 XmNchildHorizontalAlignment
, XmALIGNMENT_BEGINNING
,
1150 XmNlabelString
, str
,
1153 apply_fontlist(name
);
1156 XtSetArg(args
[n
], XmNvisibleItemCount
, 8); ++n
;
1157 XtSetArg(args
[n
], XmNresizable
, True
); ++n
;
1158 XtSetArg(args
[n
], XmNlistSizePolicy
, XmCONSTANT
); ++n
;
1159 XtSetArg(args
[n
], XmNvisualPolicy
, XmVARIABLE
); ++n
;
1160 #ifdef LESSTIF_VERSION
1161 XtSetArg(args
[n
], XmNscrollBarDisplayPolicy
, XmSTATIC
); ++n
;
1163 data
->list
[SIZE
] = XmCreateScrolledList(frame
, "sizeList", args
, n
);
1164 XtVaSetValues(name
, XmNuserData
, data
->list
[SIZE
], NULL
);
1166 /* update form widgets cancel button */
1167 XtVaSetValues(form
, XmNcancelButton
, data
->cancel
, NULL
);
1169 XtAddCallback(size_toggle
, XmNvalueChangedCallback
,
1170 (XtCallbackProc
)stoggle_callback
, (XtPointer
)data
);
1171 XtAddCallback(data
->list
[NAME
], XmNbrowseSelectionCallback
,
1172 (XtCallbackProc
)name_callback
, (XtPointer
)data
);
1173 XtAddCallback(data
->list
[STYLE
], XmNbrowseSelectionCallback
,
1174 (XtCallbackProc
)style_callback
, (XtPointer
)data
);
1175 XtAddCallback(data
->list
[SIZE
], XmNbrowseSelectionCallback
,
1176 (XtCallbackProc
)size_callback
, (XtPointer
)data
);
1177 XtAddCallback(data
->ok
, XmNactivateCallback
,
1178 (XtCallbackProc
)ok_callback
, (XtPointer
)data
);
1179 XtAddCallback(data
->cancel
, XmNactivateCallback
,
1180 (XtCallbackProc
)cancel_callback
, (XtPointer
)data
);
1182 XmProcessTraversal(data
->list
[NAME
], XmTRAVERSE_CURRENT
);
1184 /* setup tabgroups */
1186 XmAddTabGroup(data
->list
[NAME
]);
1187 XmAddTabGroup(data
->list
[STYLE
]);
1188 XmAddTabGroup(data
->list
[SIZE
]);
1189 XmAddTabGroup(size_toggle
);
1190 XmAddTabGroup(data
->name
);
1191 XmAddTabGroup(data
->ok
);
1192 XmAddTabGroup(data
->cancel
);
1194 add_cancel_action(data
->dialog
, (XtCallbackProc
)cancel_callback
, data
);
1196 /* Preset selection data. */
1199 data
->in_pixels
= True
;
1200 data
->sel
[ENCODING
] = NULL
;
1201 data
->sel
[NAME
] = NULL
;
1202 data
->sel
[STYLE
] = NULL
;
1203 data
->sel
[SIZE
] = NULL
;
1204 data
->font_name
= NULL
;
1206 /* set up current font parameters */
1207 if (current
&& current
[0] != '\0')
1212 names
= XListFonts(XtDisplay(form
), (char *) current
, 1, &i
);
1216 char namebuf
[TEMP_BUF_SIZE
];
1217 char stylebuf
[TEMP_BUF_SIZE
];
1218 char sizebuf
[TEMP_BUF_SIZE
];
1219 char encodingbuf
[TEMP_BUF_SIZE
];
1224 name_part(found
, namebuf
);
1225 style_part(found
, stylebuf
);
1226 size_part(found
, sizebuf
, data
->in_pixels
);
1227 encoding_part(found
, encodingbuf
);
1229 if (strlen(namebuf
) > 0
1230 && strlen(stylebuf
) > 0
1231 && strlen(sizebuf
) > 0
1232 && strlen(encodingbuf
) > 0)
1234 data
->sel
[NAME
] = XtNewString(namebuf
);
1235 data
->sel
[STYLE
] = XtNewString(stylebuf
);
1236 data
->sel
[SIZE
] = XtNewString(sizebuf
);
1237 data
->sel
[ENCODING
] = XtNewString(encodingbuf
);
1238 data
->font_name
= XtNewString(names
[0]);
1239 display_sample(data
);
1240 XmTextSetString(data
->name
, data
->font_name
);
1244 /* We can't preset a symbolic name, which isn't a full font
1245 * description. Therefore we just behave the same way as if the
1246 * user didn't have selected anything thus far.
1248 * Unfortunately there is no known way to expand an abbreviated
1252 data
->font_name
= NULL
;
1255 XFreeFontNames(names
);
1258 fill_lists(NONE
, data
);
1260 /* Unfortunately LessTif doesn't align the list widget's properly. I don't
1261 * have currently any idea how to fix this problem.
1263 XtManageChild(data
->list
[NAME
]);
1264 XtManageChild(data
->list
[STYLE
]);
1265 XtManageChild(data
->list
[SIZE
]);
1266 XtManageChild(data
->encoding_menu
);
1267 manage_centered(form
);
1269 /* modal event loop */
1271 XtAppProcessEvent(XtWidgetToApplicationContext(data
->dialog
),
1272 (XtInputMask
)XtIMAll
);
1274 XtDestroyWidget(data
->dialog
);
1278 XFreeFont(XtDisplay(data
->dialog
), data
->old
);
1279 XmFontListFree(data
->old_list
);
1282 gui_motif_synch_fonts();
1284 return (char_u
*) data
->font_name
;