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
]);
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
< 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
]);
549 stoggle_callback(Widget w
,
550 SharedFontSelData
*data
,
551 XmToggleButtonCallbackStruct
*call_data
)
554 char newSize
[TEMP_BUF_SIZE
];
557 if (call_data
->reason
!= (int)XmCR_VALUE_CHANGED
)
560 do_sel
= (data
->sel
[SIZE
] != NULL
) && strcmp(data
->sel
[SIZE
], wild
);
562 for (i
= 0; do_sel
&& (i
< data
->num
); i
++)
563 if (match(data
, ENCODING
, i
)
564 && match(data
, NAME
, i
)
565 && match(data
, STYLE
, i
)
566 && match(data
, SIZE
, i
))
568 size_part(fn(data
, i
), newSize
, !data
->in_pixels
);
572 data
->in_pixels
= !data
->in_pixels
;
575 XtFree(data
->sel
[SIZE
]);
576 data
->sel
[SIZE
] = NULL
;
577 fill_lists(NONE
, data
);
581 str
= XmStringCreateLocalized(newSize
);
582 XmListSelectItem(data
->list
[SIZE
], str
, True
);
583 XmListSetBottomItem(data
->list
[SIZE
], str
);
589 * Show the currently selected font in the sample text label.
592 display_sample(SharedFontSelData
*data
)
597 XmFontList font_list
;
601 display
= XtDisplay(data
->dialog
);
602 font
= XLoadQueryFont(display
, data
->font_name
);
603 font_list
= gui_motif_create_fontlist(font
);
606 str
= XmStringCreateLocalized("AaBbZzYy 0123456789");
607 XtSetArg(args
[n
], XmNlabelString
, str
); n
++;
608 XtSetArg(args
[n
], XmNfontList
, font_list
); n
++;
610 XtSetValues(data
->sample
, args
, n
);
615 XFreeFont(display
, data
->old
);
616 XmFontListFree(data
->old_list
);
619 data
->old_list
= font_list
;
625 SharedFontSelData
*data
,
626 XmListCallbackStruct
*call_data
,
627 enum ListSpecifier which
)
631 XmStringGetLtoR(call_data
->item
, XmSTRING_DEFAULT_CHARSET
, &sel
);
633 if (!data
->sel
[which
])
634 data
->sel
[which
] = XtNewString(sel
);
637 XtFree(data
->sel
[which
]);
638 if (!strcmp(data
->sel
[which
], sel
))
640 /* unselecting current selection */
641 data
->sel
[which
] = NULL
;
643 XmListDeselectItem(w
, call_data
->item
);
646 data
->sel
[which
] = XtNewString(sel
);
650 fill_lists(which
, data
);
652 /* If there is a font selection, we display it. */
653 if (data
->sel
[ENCODING
]
657 && strcmp(data
->sel
[ENCODING
], wild
)
658 && strcmp(data
->sel
[NAME
], wild
)
659 && strcmp(data
->sel
[STYLE
], wild
)
660 && strcmp(data
->sel
[SIZE
], wild
))
665 XtFree(data
->font_name
);
666 data
->font_name
= NULL
;
668 for (i
= 0; i
< data
->num
; i
++)
670 if (match(data
, ENCODING
, i
)
671 && match(data
, NAME
, i
)
672 && match(data
, STYLE
, i
)
673 && match(data
, SIZE
, i
))
675 data
->font_name
= XtNewString(fn(data
, i
));
682 XmTextSetString(data
->name
, data
->font_name
);
683 display_sample(data
);
687 (char_u
*)_("Error"),
688 (char_u
*)_("Invalid font specification"),
689 (char_u
*)_("&Dismiss"), 1, NULL
);
698 char *nomatch_msg
= _("no specific match");
701 str
= XmStringCreateLocalized(nomatch_msg
);
702 XtSetArg(args
[n
], XmNlabelString
, str
); ++n
;
703 XtSetValues(data
->sample
, args
, n
);
704 apply_fontlist(data
->sample
);
705 XmTextSetString(data
->name
, nomatch_msg
);
714 encoding_callback(Widget w
,
715 SharedFontSelData
*data
,
719 XmListCallbackStruct fake_data
;
721 XtVaGetValues(w
, XmNlabelString
, &str
, NULL
);
726 fake_data
.item
= str
;
728 do_choice(0, data
, &fake_data
, ENCODING
);
732 name_callback(Widget w
,
733 SharedFontSelData
*data
,
734 XmListCallbackStruct
*call_data
)
736 do_choice(w
, data
, call_data
, NAME
);
740 style_callback(Widget w
,
741 SharedFontSelData
*data
,
742 XmListCallbackStruct
*call_data
)
744 do_choice(w
, data
, call_data
, STYLE
);
748 size_callback(Widget w
,
749 SharedFontSelData
*data
,
750 XmListCallbackStruct
*call_data
)
752 do_choice(w
, data
, call_data
, SIZE
);
757 cancel_callback(Widget w
,
758 SharedFontSelData
*data
,
759 XmListCallbackStruct
*call_data
)
761 if (data
->sel
[ENCODING
])
763 XtFree(data
->sel
[ENCODING
]);
764 data
->sel
[ENCODING
] = NULL
;
768 XtFree(data
->sel
[NAME
]);
769 data
->sel
[NAME
] = NULL
;
771 if (data
->sel
[STYLE
])
773 XtFree(data
->sel
[STYLE
]);
774 data
->sel
[STYLE
] = NULL
;
778 XtFree(data
->sel
[SIZE
]);
779 data
->sel
[SIZE
] = NULL
;
783 XtFree(data
->font_name
);
784 data
->font_name
= NULL
;
787 XFreeFontNames(data
->names
);
794 ok_callback(Widget w
,
795 SharedFontSelData
*data
,
796 XmPushButtonCallbackStruct
*call_data
)
802 pattern
= XmTextGetString(data
->name
);
803 name
= XListFonts(XtDisplay(data
->dialog
), pattern
, 1, &i
);
809 (char_u
*)_("Error"),
810 (char_u
*)_("Invalid font specification"),
811 (char_u
*)_("&Dismiss"), 1, NULL
);
812 XFreeFontNames(name
);
817 XtFree(data
->font_name
);
818 data
->font_name
= XtNewString(name
[0]);
820 if (data
->sel
[ENCODING
])
822 XtFree(data
->sel
[ENCODING
]);
823 data
->sel
[ENCODING
] = NULL
;
827 XtFree(data
->sel
[NAME
]);
828 data
->sel
[NAME
] = NULL
;
830 if (data
->sel
[STYLE
])
832 XtFree(data
->sel
[STYLE
]);
833 data
->sel
[STYLE
] = NULL
;
837 XtFree(data
->sel
[SIZE
]);
838 data
->sel
[SIZE
] = NULL
;
841 XFreeFontNames(name
);
844 XFreeFontNames(data
->names
);
851 * Returns pointer to an ASCII character string that contains the name of the
852 * selected font (in X format for naming fonts); it is the users responsibility
853 * to free the space allocated to this string.
856 gui_xm_select_font(char_u
*current
)
858 static SharedFontSelData _data
;
871 char big_font
[MAX_FONT_NAME_LEN
];
872 SharedFontSelData
*data
;
877 data
->names
= XListFonts(XtDisplay(parent
), "-*-*-*-*-*-*-*-*-*-*-*-*-*-*",
878 MAX_FONTS
, &data
->num
);
881 * Find the name of the biggest font less than the given limit
882 * MAX_DISPLAY_SIZE used to set up the initial height of the display
893 for (i
= 0, max
= 0; i
< data
->num
; i
++)
895 get_part(fn(data
, i
), 7, buf
);
897 if ((size
> max
) && (size
< MAX_DISPLAY_SIZE
))
903 strcpy(big_font
, fn(data
, idx
));
905 data
->old
= XLoadQueryFont(XtDisplay(parent
), big_font
);
906 data
->old_list
= gui_motif_create_fontlist(data
->old
);
908 /* Set the title of the Dialog window. */
909 data
->dialog
= XmCreateDialogShell(parent
, "fontSelector", NULL
, 0);
910 str
= XmStringCreateLocalized(_("Vim - Font Selector"));
912 /* Create form popup dialog widget. */
913 form
= XtVaCreateWidget("form",
914 xmFormWidgetClass
, data
->dialog
,
916 XmNautoUnmanage
, False
,
917 XmNdialogStyle
, XmDIALOG_FULL_APPLICATION_MODAL
,
921 sub_form
= XtVaCreateManagedWidget("subForm",
922 xmFormWidgetClass
, form
,
923 XmNbottomAttachment
, XmATTACH_FORM
,
925 XmNrightAttachment
, XmATTACH_FORM
,
927 XmNtopAttachment
, XmATTACH_FORM
,
929 XmNorientation
, XmVERTICAL
,
932 data
->ok
= XtVaCreateManagedWidget(_("OK"),
933 xmPushButtonGadgetClass
, sub_form
,
934 XmNleftAttachment
, XmATTACH_FORM
,
935 XmNrightAttachment
, XmATTACH_FORM
,
936 XmNtopAttachment
, XmATTACH_FORM
,
939 apply_fontlist(data
->ok
);
941 data
->cancel
= XtVaCreateManagedWidget(_("Cancel"),
942 xmPushButtonGadgetClass
, sub_form
,
943 XmNrightAttachment
, XmATTACH_FORM
,
944 XmNleftAttachment
, XmATTACH_FORM
,
945 XmNtopAttachment
, XmATTACH_WIDGET
,
946 XmNtopWidget
, data
->ok
,
948 XmNshowAsDefault
, True
,
950 apply_fontlist(data
->cancel
);
952 /* Create the separator for beauty. */
954 XtSetArg(args
[n
], XmNorientation
, XmVERTICAL
); n
++;
955 XtSetArg(args
[n
], XmNbottomAttachment
, XmATTACH_FORM
); n
++;
956 XtSetArg(args
[n
], XmNtopAttachment
, XmATTACH_FORM
); n
++;
957 XtSetArg(args
[n
], XmNrightAttachment
, XmATTACH_WIDGET
); n
++;
958 XtSetArg(args
[n
], XmNrightWidget
, sub_form
); n
++;
959 XtSetArg(args
[n
], XmNrightOffset
, 4); n
++;
960 separator
= XmCreateSeparatorGadget(form
, "separator", args
, n
);
961 XtManageChild(separator
);
963 /* Create font name text widget and the corresponding label. */
964 data
->name
= XtVaCreateManagedWidget("fontName",
965 xmTextWidgetClass
, form
,
966 XmNbottomAttachment
, XmATTACH_FORM
,
968 XmNleftAttachment
, XmATTACH_FORM
,
970 XmNrightAttachment
, XmATTACH_WIDGET
,
971 XmNrightWidget
, separator
,
974 XmNeditMode
, XmSINGLE_LINE_EDIT
,
975 XmNmaxLength
, MAX_FONT_NAME_LEN
,
979 str
= XmStringCreateLocalized(_("Name:"));
980 name
= XtVaCreateManagedWidget("fontNameLabel",
981 xmLabelGadgetClass
, form
,
983 XmNuserData
, data
->name
,
984 XmNleftAttachment
, XmATTACH_OPPOSITE_WIDGET
,
985 XmNleftWidget
, data
->name
,
986 XmNbottomAttachment
, XmATTACH_WIDGET
,
987 XmNbottomWidget
, data
->name
,
991 apply_fontlist(name
);
993 /* create sample display label widget */
994 disp_frame
= XtVaCreateManagedWidget("sampleFrame",
995 xmFrameWidgetClass
, form
,
996 XmNshadowType
, XmSHADOW_ETCHED_IN
,
997 XmNleftAttachment
, XmATTACH_FORM
,
999 XmNbottomAttachment
, XmATTACH_WIDGET
,
1000 XmNbottomWidget
, name
,
1001 XmNrightAttachment
, XmATTACH_WIDGET
,
1002 XmNrightWidget
, separator
,
1004 XmNalignment
, XmALIGNMENT_BEGINNING
,
1007 data
->sample
= XtVaCreateManagedWidget("sampleLabel",
1008 xmLabelWidgetClass
, disp_frame
,
1009 XmNleftAttachment
, XmATTACH_FORM
,
1010 XmNtopAttachment
, XmATTACH_FORM
,
1011 XmNbottomAttachment
, XmATTACH_FORM
,
1012 XmNrightAttachment
, XmATTACH_FORM
,
1013 XmNalignment
, XmALIGNMENT_BEGINNING
,
1014 XmNrecomputeSize
, False
,
1015 XmNfontList
, data
->old_list
,
1018 /* create toggle button */
1019 str
= XmStringCreateLocalized(_("Show size in Points"));
1020 size_toggle
= XtVaCreateManagedWidget("sizeToggle",
1021 xmToggleButtonGadgetClass
, form
,
1022 XmNlabelString
, str
,
1023 XmNleftAttachment
, XmATTACH_FORM
,
1025 XmNbottomAttachment
, XmATTACH_WIDGET
,
1026 XmNbottomWidget
, disp_frame
,
1030 apply_fontlist(size_toggle
);
1031 XtManageChild(size_toggle
);
1033 /* Encoding pulldown menu.
1036 data
->encoding_pulldown
= XmCreatePulldownMenu(form
,
1037 "encodingPulldown", NULL
, 0);
1038 str
= XmStringCreateLocalized(_("Encoding:"));
1040 XtSetArg(args
[n
], XmNsubMenuId
, data
->encoding_pulldown
); ++n
;
1041 XtSetArg(args
[n
], XmNlabelString
, str
); ++n
;
1042 XtSetArg(args
[n
], XmNleftAttachment
, XmATTACH_FORM
); ++n
;
1043 XtSetArg(args
[n
], XmNleftOffset
, 4); ++n
;
1044 XtSetArg(args
[n
], XmNbottomAttachment
, XmATTACH_WIDGET
); ++n
;
1045 XtSetArg(args
[n
], XmNbottomWidget
, size_toggle
); ++n
;
1046 XtSetArg(args
[n
], XmNbottomOffset
, 4); ++n
;
1047 XtSetArg(args
[n
], XmNrightAttachment
, XmATTACH_WIDGET
); ++n
;
1048 XtSetArg(args
[n
], XmNrightWidget
, separator
); ++n
;
1049 XtSetArg(args
[n
], XmNrightOffset
, 4); ++n
;
1050 data
->encoding_menu
= XmCreateOptionMenu(form
, "encodingMenu", args
, n
);
1052 XmAddTabGroup(data
->encoding_menu
);
1055 * Create scroll list widgets in a separate subform used to manage the
1056 * different sizes of the lists.
1059 sub_form
= XtVaCreateManagedWidget("subForm",
1060 xmFormWidgetClass
, form
,
1061 XmNbottomAttachment
, XmATTACH_WIDGET
,
1062 XmNbottomWidget
, data
->encoding_menu
,
1064 XmNleftAttachment
, XmATTACH_FORM
,
1066 XmNrightAttachment
, XmATTACH_WIDGET
,
1067 XmNrightWidget
, separator
,
1069 XmNtopAttachment
, XmATTACH_FORM
,
1071 XmNorientation
, XmVERTICAL
,
1075 frame
= XtVaCreateManagedWidget("frame", xmFrameWidgetClass
, sub_form
,
1076 XmNshadowThickness
, 0,
1077 XmNtopAttachment
, XmATTACH_FORM
,
1078 XmNbottomAttachment
, XmATTACH_FORM
,
1079 XmNleftAttachment
, XmATTACH_FORM
,
1080 XmNrightAttachment
, XmATTACH_POSITION
,
1081 XmNrightPosition
, 50,
1084 str
= XmStringCreateLocalized(_("Font:"));
1085 name
= XtVaCreateManagedWidget("nameListLabel", xmLabelGadgetClass
, frame
,
1086 XmNchildType
, XmFRAME_TITLE_CHILD
,
1087 XmNchildVerticalAlignment
, XmALIGNMENT_CENTER
,
1088 XmNchildHorizontalAlignment
, XmALIGNMENT_BEGINNING
,
1089 XmNlabelString
, str
,
1092 apply_fontlist(name
);
1095 XtSetArg(args
[n
], XmNvisibleItemCount
, 8); ++n
;
1096 XtSetArg(args
[n
], XmNresizable
, True
); ++n
;
1097 XtSetArg(args
[n
], XmNlistSizePolicy
, XmCONSTANT
); ++n
;
1098 XtSetArg(args
[n
], XmNvisualPolicy
, XmVARIABLE
); ++n
;
1099 #ifdef LESSTIF_VERSION
1100 XtSetArg(args
[n
], XmNscrollBarDisplayPolicy
, XmSTATIC
); ++n
;
1102 data
->list
[NAME
] = XmCreateScrolledList(frame
, "fontList", args
, n
);
1103 XtVaSetValues(name
, XmNuserData
, data
->list
[NAME
], NULL
);
1106 frame
= XtVaCreateManagedWidget("frame", xmFrameWidgetClass
, sub_form
,
1107 XmNshadowThickness
, 0,
1108 XmNtopAttachment
, XmATTACH_FORM
,
1109 XmNbottomAttachment
, XmATTACH_FORM
,
1110 XmNleftAttachment
, XmATTACH_POSITION
,
1111 XmNleftPosition
, 50,
1113 XmNrightAttachment
, XmATTACH_POSITION
,
1114 XmNrightPosition
, 80,
1117 str
= XmStringCreateLocalized(_("Style:"));
1118 name
= XtVaCreateManagedWidget("styleListLabel", xmLabelWidgetClass
, frame
,
1119 XmNchildType
, XmFRAME_TITLE_CHILD
,
1120 XmNchildVerticalAlignment
, XmALIGNMENT_CENTER
,
1121 XmNchildHorizontalAlignment
, XmALIGNMENT_BEGINNING
,
1122 XmNlabelString
, str
,
1125 apply_fontlist(name
);
1128 XtSetArg(args
[n
], XmNvisibleItemCount
, 8); ++n
;
1129 XtSetArg(args
[n
], XmNresizable
, True
); ++n
;
1130 XtSetArg(args
[n
], XmNlistSizePolicy
, XmCONSTANT
); ++n
;
1131 XtSetArg(args
[n
], XmNvisualPolicy
, XmVARIABLE
); ++n
;
1132 #ifdef LESSTIF_VERSION
1133 XtSetArg(args
[n
], XmNscrollBarDisplayPolicy
, XmSTATIC
); ++n
;
1135 data
->list
[STYLE
] = XmCreateScrolledList(frame
, "styleList", args
, n
);
1136 XtVaSetValues(name
, XmNuserData
, data
->list
[STYLE
], NULL
);
1139 frame
= XtVaCreateManagedWidget("frame", xmFrameWidgetClass
, sub_form
,
1140 XmNshadowThickness
, 0,
1141 XmNtopAttachment
, XmATTACH_FORM
,
1142 XmNbottomAttachment
, XmATTACH_FORM
,
1143 XmNleftAttachment
, XmATTACH_POSITION
,
1144 XmNleftPosition
, 80,
1146 XmNrightAttachment
, XmATTACH_FORM
,
1149 str
= XmStringCreateLocalized(_("Size:"));
1150 name
= XtVaCreateManagedWidget("sizeListLabel", xmLabelGadgetClass
, frame
,
1151 XmNchildType
, XmFRAME_TITLE_CHILD
,
1152 XmNchildVerticalAlignment
, XmALIGNMENT_CENTER
,
1153 XmNchildHorizontalAlignment
, XmALIGNMENT_BEGINNING
,
1154 XmNlabelString
, str
,
1157 apply_fontlist(name
);
1160 XtSetArg(args
[n
], XmNvisibleItemCount
, 8); ++n
;
1161 XtSetArg(args
[n
], XmNresizable
, True
); ++n
;
1162 XtSetArg(args
[n
], XmNlistSizePolicy
, XmCONSTANT
); ++n
;
1163 XtSetArg(args
[n
], XmNvisualPolicy
, XmVARIABLE
); ++n
;
1164 #ifdef LESSTIF_VERSION
1165 XtSetArg(args
[n
], XmNscrollBarDisplayPolicy
, XmSTATIC
); ++n
;
1167 data
->list
[SIZE
] = XmCreateScrolledList(frame
, "sizeList", args
, n
);
1168 XtVaSetValues(name
, XmNuserData
, data
->list
[SIZE
], NULL
);
1170 /* update form widgets cancel button */
1171 XtVaSetValues(form
, XmNcancelButton
, data
->cancel
, NULL
);
1173 XtAddCallback(size_toggle
, XmNvalueChangedCallback
,
1174 (XtCallbackProc
)stoggle_callback
, (XtPointer
)data
);
1175 XtAddCallback(data
->list
[NAME
], XmNbrowseSelectionCallback
,
1176 (XtCallbackProc
)name_callback
, (XtPointer
)data
);
1177 XtAddCallback(data
->list
[STYLE
], XmNbrowseSelectionCallback
,
1178 (XtCallbackProc
)style_callback
, (XtPointer
)data
);
1179 XtAddCallback(data
->list
[SIZE
], XmNbrowseSelectionCallback
,
1180 (XtCallbackProc
)size_callback
, (XtPointer
)data
);
1181 XtAddCallback(data
->ok
, XmNactivateCallback
,
1182 (XtCallbackProc
)ok_callback
, (XtPointer
)data
);
1183 XtAddCallback(data
->cancel
, XmNactivateCallback
,
1184 (XtCallbackProc
)cancel_callback
, (XtPointer
)data
);
1186 XmProcessTraversal(data
->list
[NAME
], XmTRAVERSE_CURRENT
);
1188 /* setup tabgroups */
1190 XmAddTabGroup(data
->list
[NAME
]);
1191 XmAddTabGroup(data
->list
[STYLE
]);
1192 XmAddTabGroup(data
->list
[SIZE
]);
1193 XmAddTabGroup(size_toggle
);
1194 XmAddTabGroup(data
->name
);
1195 XmAddTabGroup(data
->ok
);
1196 XmAddTabGroup(data
->cancel
);
1198 add_cancel_action(data
->dialog
, (XtCallbackProc
)cancel_callback
, data
);
1200 /* Preset selection data. */
1203 data
->in_pixels
= True
;
1204 data
->sel
[ENCODING
] = NULL
;
1205 data
->sel
[NAME
] = NULL
;
1206 data
->sel
[STYLE
] = NULL
;
1207 data
->sel
[SIZE
] = NULL
;
1208 data
->font_name
= NULL
;
1210 /* set up current font parameters */
1211 if (current
&& current
[0] != '\0')
1216 names
= XListFonts(XtDisplay(form
), (char *) current
, 1, &i
);
1220 char namebuf
[TEMP_BUF_SIZE
];
1221 char stylebuf
[TEMP_BUF_SIZE
];
1222 char sizebuf
[TEMP_BUF_SIZE
];
1223 char encodingbuf
[TEMP_BUF_SIZE
];
1228 name_part(found
, namebuf
);
1229 style_part(found
, stylebuf
);
1230 size_part(found
, sizebuf
, data
->in_pixels
);
1231 encoding_part(found
, encodingbuf
);
1233 if (strlen(namebuf
) > 0
1234 && strlen(stylebuf
) > 0
1235 && strlen(sizebuf
) > 0
1236 && strlen(encodingbuf
) > 0)
1238 data
->sel
[NAME
] = XtNewString(namebuf
);
1239 data
->sel
[STYLE
] = XtNewString(stylebuf
);
1240 data
->sel
[SIZE
] = XtNewString(sizebuf
);
1241 data
->sel
[ENCODING
] = XtNewString(encodingbuf
);
1242 data
->font_name
= XtNewString(names
[0]);
1243 display_sample(data
);
1244 XmTextSetString(data
->name
, data
->font_name
);
1248 /* We can't preset a symbolic name, which isn't a full font
1249 * description. Therefore we just behave the same way as if the
1250 * user didn't have selected anything thus far.
1252 * Unfortunately there is no known way to expand an abbreviated
1256 data
->font_name
= NULL
;
1259 XFreeFontNames(names
);
1262 fill_lists(NONE
, data
);
1264 /* Unfortunately LessTif doesn't align the list widget's properly. I don't
1265 * have currently any idea how to fix this problem.
1267 XtManageChild(data
->list
[NAME
]);
1268 XtManageChild(data
->list
[STYLE
]);
1269 XtManageChild(data
->list
[SIZE
]);
1270 XtManageChild(data
->encoding_menu
);
1271 manage_centered(form
);
1273 /* modal event loop */
1275 XtAppProcessEvent(XtWidgetToApplicationContext(data
->dialog
),
1276 (XtInputMask
)XtIMAll
);
1278 XtDestroyWidget(data
->dialog
);
1282 XFreeFont(XtDisplay(data
->dialog
), data
->old
);
1283 XmFontListFree(data
->old_list
);
1286 gui_motif_synch_fonts();
1288 return (char_u
*) data
->font_name
;