2 * Copyright 2008 Department of Mathematical Sciences, New Mexico State University
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * DEPARTMENT OF MATHEMATICAL SCIENCES OR NEW MEXICO STATE UNIVERSITY BE
18 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
19 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 /**************************************************************************
28 * Application globals.
30 **************************************************************************/
32 gchar buffer1[BUFSIZ];
33 gchar buffer2[BUFSIZ];
34 gbdfed_options_t options;
37 * The list of editors that exist.
39 gbdfed_editor_t *editors;
42 /**************************************************************************
44 * Forward declarations and local variables.
46 **************************************************************************/
49 * These are formats that can appear in the editor for importing/loading and
52 #define XMBDFED_BDF_FORMAT 1
53 #define XMBDFED_CONSOLE_FORMAT 2
54 #define XMBDFED_PKGF_FORMAT 3
55 #define XMBDFED_FNT_FORMAT 4
56 #define XMBDFED_HBF_FORMAT 5
57 #define XMBDFED_TTF_FORMAT 6
58 #define XMBDFED_PSF_FORMAT 7
59 #define XMBDFED_HEX_FORMAT 8
60 #define XMBDFED_HEADER_FORMAT 9
62 /**************************************************************************
66 **************************************************************************/
68 static const gchar *gbdfed_16x16[] = {
69 /* width height num_colors chars_per_pixel */
96 static const gchar *gbdfed_32x32[] = {
97 /* width height num_colors chars_per_pixel */
105 ".##a##.##.##.##.##.##.##.##.##.#",
106 ".##a##.##.##.##.##.##.##.##.##.#",
107 "...a............................",
108 ".##a##.##.##.##.##.##.##.##.##.#",
109 ".##a##.##.##.##.##.##.##.##.##.#",
110 "...a............................",
111 ".##abb.bb.bb.##.##.##.##.##.bb.#",
112 ".##abb.bb.bb.##.##.##.##.##.bb.#",
113 "...a............................",
114 ".##a##.bb.bb.bb.##.##.##.bb.##.#",
115 ".##a##.bb.bb.bb.##.##.##.bb.##.#",
116 "...a............................",
117 ".##a##.##.bb.bb.bb.##.bb.##.##.#",
118 ".##a##.##.bb.bb.bb.##.bb.##.##.#",
119 "...a............................",
120 ".##a##.##.##.bb.##.bb.##.##.##.#",
121 ".##a##.##.##.bb.##.bb.##.##.##.#",
122 "...a............................",
123 ".##a##.##.bb.##.bb.bb.bb.##.##.#",
124 ".##a##.##.bb.##.bb.bb.bb.##.##.#",
125 "...a............................",
126 ".##a##.bb.##.##.##.bb.bb.bb.##.#",
127 ".##a##.bb.##.##.##.bb.bb.bb.##.#",
128 "...a............................",
129 ".##abb.##.##.##.##.##.bb.bb.bb.#",
130 ".##abb.##.##.##.##.##.bb.bb.bb.#",
131 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
132 ".##a##.##.##.##.##.##.##.##.##.#",
133 ".##a##.##.##.##.##.##.##.##.##.#",
134 "...a............................",
135 ".##a##.##.##.##.##.##.##.##.##.#",
136 ".##a##.##.##.##.##.##.##.##.##.#"
139 static const gchar *gbdfed_48x48[] = {
140 /* width height num_colors chars_per_pixel */
148 "....#...........................................",
149 ".aaa#aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa",
150 ".aaa#aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa",
151 ".aaa#aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa..aa.aaa.aaa",
152 "....#...........................................",
153 ".aaa#bbb.bbb.bbb.aaa.aaa.aaa.aaa.aaa.aaa.aaa.bbb",
154 ".aaa#bbb.bbb.bbb.aaa.aaa.aaa.aaa.aaa.aaa.aaa.bbb",
155 ".aaa#bbb.bbb.bbb.aaa.aaa.aaa.aaa.aaa.aaa.aaa.bbb",
156 "....#...........................................",
157 ".aaa#aaa.bbb.bbb.bbb.aaa.aaa.aaa.aaa.aaa.bbb.aaa",
158 ".aaa#aaa.bbb.bbb.bbb.aaa.aaa.aaa.aaa.aaa.bbb.aaa",
159 ".aaa#aaa.bbb.bbb.bbb.aaa.aaa.aaa.aaa.aaa.bbb.aaa",
160 "....#...........................................",
161 ".aaa#aaa.aaa.bbb.bbb.bbb.aaa.aaa.aaa.bbb.aaa.aaa",
162 ".aaa#aaa.aaa.bbb.bbb.bbb.aaa.aaa.aaa.bbb.aaa.aaa",
163 ".aaa#aaa.aaa.bbb.bbb.bbb.aaa.aaa.aaa.bbb.aaa.aaa",
164 "....#...........................................",
165 ".aaa#aaa.aaa.aaa.bbb.bbb.bbb.aaa.bbb.aaa.aaa.aaa",
166 ".aaa#aaa.aaa.aaa.bbb.bbb.bbb.aaa.bbb.aaa.aaa.aaa",
167 ".aaa#aaa.aaa.aaa.bbb.bbb.bbb.aaa.bbb.aaa.aaa.aaa",
168 "....#...........................................",
169 ".aaa#aaa.aaa.aaa.aaa.bbb.aaa.bbb.aaa.aaa.aaa.aaa",
170 ".aaa#aaa.aaa.aaa.aaa.bbb.aaa.bbb.aaa.aaa.aaa.aaa",
171 ".aaa#aaa.aaa.aaa.aaa.bbb.aaa.bbb.aaa.aaa.aaa.aaa",
172 "....#...........................................",
173 ".aaa#aaa.aaa.aaa.bbb.aaa.bbb.bbb.bbb.aaa.aaa.aaa",
174 ".aaa#aaa.aaa.aaa.bbb.aaa.bbb.bbb.bbb.aaa.aaa.aaa",
175 ".aaa#aaa.aaa.aaa.bbb.aaa.bbb.bbb.bbb.aaa.aaa.aaa",
176 "....#...........................................",
177 ".aaa#aaa.aaa.bbb.aaa.aaa.aaa.bbb.bbb.bbb.aaa.aaa",
178 ".aaa#aaa.aaa.bbb.aaa.aaa.aaa.bbb.bbb.bbb.aaa.aaa",
179 ".aaa#aaa.aaa.bbb.aaa.aaa.aaa.bbb.bbb.bbb.aaa.aaa",
180 "....#...........................................",
181 ".aaa#aaa.bbb.aaa.aaa.aaa.aaa.aaa.bbb.bbb.bbb.aaa",
182 ".aaa#aaa.bbb.aaa.aaa.aaa.aaa.aaa.bbb.bbb.bbb.aaa",
183 ".aaa#aaa.bbb.aaa.aaa.aaa.aaa.aaa.bbb.bbb.bbb.aaa",
184 "....#...........................................",
185 ".aaa#bbb.aaa.aaa.aaa.aaa.aaa.aaa.aaa.bbb.bbb.bbb",
186 ".aaa#bbb.aaa.aaa.aaa.aaa.aaa.aaa.aaa.bbb.bbb.bbb",
187 ".aaa#bbb.aaa.aaa.aaa.aaa.aaa.aaa.aaa.bbb.bbb.bbb",
188 "################################################",
189 ".aaa#aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa",
190 ".aaa#aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa",
191 ".aaa#aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa",
192 "....#...........................................",
193 ".aaa#aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa",
194 ".aaa#aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa",
195 ".aaa#aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa.aaa"
198 static gboolean icons_set = FALSE;
200 /**************************************************************************
202 * GTK signal handlers.
204 **************************************************************************/
207 quit_application(GtkWidget *w, GdkEvent *ev, gpointer data)
211 for (i = modified = 0; i < num_editors; i++) {
212 if (fontgrid_get_font_modified(FONTGRID(editors[i].fgrid)))
218 sprintf(buffer1, "Save Font: One font was modified. Save?");
220 sprintf(buffer1, "Save Font: %d fonts were modified. Save?",
222 if (guiutil_yes_or_no(editors[0].shell, buffer1, TRUE)) {
225 * Go through each editor and ask if the font should be saved if
226 * it has been modified.
228 for (i = 0; i < num_editors; i++) {
229 if (fontgrid_get_font_modified(FONTGRID(editors[i].fgrid))) {
231 * Ask if this font should be saved.
234 sprintf(buffer1, "Save Font: Save %s?", editors[i].file);
236 sprintf(buffer1, "Save Font: Save unnamed%d.bdf?", i);
239 * Always ask this question using the shell window of the
240 * first editor so the dialog box doesn't move around.
242 if (guiutil_yes_or_no(editors[0].shell, buffer1, TRUE))
243 guifile_save_as_wait(w, GUINT_TO_POINTER(i));
250 * Ask if the user really wants to exit if their preferences specify this
251 * question should be asked.
253 if (options.really_exit &&
254 !guiutil_yes_or_no(editors[0].shell, "Really Quit?", TRUE))
258 * Call all the cleanup routines in case something really needs to be
262 guiedit_preference_cleanup();
263 guiutil_cursor_cleanup();
272 show_editor(GtkWidget *w, gpointer data)
274 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
277 * Nothing seems to force the original window to the top of the stack
278 * on the screen, but this supposedly does everything necessary.
280 gtk_widget_show_all(ed->shell);
281 gtk_window_present(GTK_WINDOW(ed->shell));
285 goto_other_page(GtkWidget *w, gpointer editor)
287 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(editor);
291 fontgrid_get_page_info(FONTGRID(ed->fgrid), &pi);
293 if (!pi.unencoded_page) {
294 opage = ed->last_pageno;
295 ed->last_pageno = pi.current_page;
297 opage = ed->last_upageno;
298 ed->last_upageno = pi.current_page;
301 if (opage != -1 && opage != pi.current_page)
302 fontgrid_goto_page(FONTGRID(ed->fgrid), opage);
306 toggle_encoding_view(GtkWidget *w, gpointer editor)
308 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(editor);
312 if (fontgrid_viewing_unencoded(FONTGRID(ed->fgrid)))
316 lw = GTK_LABEL(GTK_BIN(ed->view_unencoded)->child);
317 gtk_label_set_text(lw, label);
319 fontgrid_switch_encoding_view(FONTGRID(ed->fgrid));
323 toggle_view_orientation(GtkWidget *w, gpointer editor)
325 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(editor);
329 if (fontgrid_get_orientation(FONTGRID(ed->fgrid)) ==
330 GTK_ORIENTATION_VERTICAL) {
331 fontgrid_set_orientation(FONTGRID(ed->fgrid),
332 GTK_ORIENTATION_HORIZONTAL);
333 label = "Vertical View";
335 fontgrid_set_orientation(FONTGRID(ed->fgrid),
336 GTK_ORIENTATION_VERTICAL);
337 label = "Horizontal View";
339 lw = GTK_LABEL(GTK_BIN(ed->view_orientation)->child);
340 gtk_label_set_text(lw, label);
344 set_code_base(GtkWidget *w, gpointer editor)
346 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(editor);
349 if (w == ed->view_oct)
351 else if (w == ed->view_dec)
356 fontgrid_set_code_base(FONTGRID(ed->fgrid), base);
359 * Make sure the font info editor is updated when the code base
362 guiedit_update_code_base(ed);
363 guigedit_set_code_base(base);
367 page_change(GtkWidget *w, gpointer pinfo, gpointer editor)
369 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(editor);
370 FontgridPageInfo *pi = (FontgridPageInfo *) pinfo;
374 if (pi->previous_page < 0) {
375 gtk_widget_set_sensitive(ed->prev, FALSE);
376 gtk_widget_set_sensitive(ed->first, FALSE);
378 gtk_widget_set_sensitive(ed->prev, TRUE);
379 gtk_widget_set_sensitive(ed->first, TRUE);
382 if (pi->next_page < 0) {
383 gtk_widget_set_sensitive(ed->next, FALSE);
384 gtk_widget_set_sensitive(ed->last, FALSE);
386 gtk_widget_set_sensitive(ed->next, TRUE);
387 gtk_widget_set_sensitive(ed->last, TRUE);
391 * Update the page number field with the current page.
393 sprintf(buffer1, "%d", pi->current_page);
394 gtk_entry_set_text(GTK_ENTRY(ed->pageno), buffer1);
395 gtk_editable_set_position(GTK_EDITABLE(ed->pageno), -1);
398 * Finally, modify the label on the Encoded/Unencoded view menu item.
400 label = (pi->unencoded_page) ? "Encoded" : "Unencoded";
401 lw = GTK_LABEL(GTK_BIN(ed->view_unencoded)->child);
402 gtk_label_set_text(lw, label);
406 first_page(GtkWidget *w, gpointer editor)
408 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(editor);
410 fontgrid_goto_first_page(FONTGRID(ed->fgrid));
413 * Force the focus back to the Fontgrid.
415 gtk_widget_grab_focus(ed->fgrid);
419 previous_page(GtkWidget *w, gpointer editor)
421 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(editor);
423 fontgrid_goto_previous_page(FONTGRID(ed->fgrid));
426 * Force the focus back to the Fontgrid.
428 gtk_widget_grab_focus(ed->fgrid);
432 next_page(GtkWidget *w, gpointer editor)
434 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(editor);
436 fontgrid_goto_next_page(FONTGRID(ed->fgrid));
439 * Force the focus back to the Fontgrid.
441 gtk_widget_grab_focus(ed->fgrid);
445 last_page(GtkWidget *w, gpointer editor)
447 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(editor);
449 fontgrid_goto_last_page(FONTGRID(ed->fgrid));
452 * Force the focus back to the Fontgrid.
454 gtk_widget_grab_focus(ed->fgrid);
458 goto_page_or_code(GtkWidget *w, gpointer editor)
460 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(editor);
465 fontgrid_get_page_info(FONTGRID(ed->fgrid), &pi);
467 if (!pi.unencoded_page)
468 ed->last_pageno = pi.current_page;
470 ed->last_upageno = pi.current_page;
472 if (w == ed->pageno) {
473 text = gtk_entry_get_text(GTK_ENTRY(ed->pageno));
474 fontgrid_goto_page(FONTGRID(ed->fgrid),
475 _bdf_atol((char *) text, 0, 10));
477 text = gtk_entry_get_text(GTK_ENTRY(ed->charno));
478 code = _bdf_atol((char *) text, 0,
479 fontgrid_get_code_base(FONTGRID(ed->fgrid)));
480 fontgrid_goto_code(FONTGRID(ed->fgrid), code);
485 update_selection_info(GtkWidget *w, gpointer sinfo, gpointer editor)
487 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(editor);
488 FontgridSelectionInfo *si = (FontgridSelectionInfo *) sinfo;
489 short as, ds, rt, lt;
491 guint b1 = 0, b2 = 0, b3, b4;
493 as = ds = rt = lt = 0;
494 if (si->start == si->end) {
495 if (si->num_glyphs != 0 && si->glyphs != 0) {
496 b1 = (si->start >> 8) & 0xff;
497 b2 = si->start & 0xff;
499 as = si->glyphs->bbx.ascent;
500 ds = si->glyphs->bbx.descent;
501 lt = si->glyphs->bbx.x_offset;
502 rt = si->glyphs->bbx.width + lt;
503 if (si->glyphs->name != 0)
504 (void) strcpy(buffer1, si->glyphs->name);
506 sprintf(buffer1, "char%d", si->glyphs->encoding);
509 * If the glyph test dialog is active, send it the glyph if this
510 * is an end selection event.
512 if (si->reason == FONTGRID_END_SELECTION && glyphtest != 0)
513 glyphtest_add_glyph(GLYPHTEST(glyphtest),
514 fontgrid_get_font(FONTGRID(ed->fgrid)),
517 sprintf(buffer1, "char%d", si->start);
521 sprintf(buffer2, "\"%s\" %o (%o, %o)", buffer1,
525 sprintf(buffer2, "\"%s\" %d (%d, %d)", buffer1,
529 sprintf(buffer2, "\"%s\" %04X (%02X, %02X)", buffer1,
536 * A range of glyphs has been selected.
538 if (si->end < si->start) {
545 b1 = (start >> 8) & 0xff;
547 b3 = (end >> 8) & 0xff;
552 sprintf(buffer2, "Selection %o (%o, %o) - %o (%o, %o)",
553 start, b1, b2, end, b3, b4);
556 sprintf(buffer2, "Selection %d (%d, %d) - %d (%d, %d)",
557 start, b1, b2, end, b3, b4);
560 sprintf(buffer2, "Selection %04X (%02X, %02X) - %04X (%02X, %02X)",
561 start, b1, b2, end, b3, b4);
567 * Update the glyph info label.
569 gtk_label_set_text(GTK_LABEL(ed->charinfo), buffer2);
572 * Update the metrics label.
574 sprintf(buffer1, "ascent %hd descent %hd right %hd left %hd",
576 gtk_label_set_text(GTK_LABEL(ed->metrics), buffer1);
578 switch (si->reason) {
579 case FONTGRID_START_SELECTION:
581 case FONTGRID_EXTEND_SELECTION:
583 case FONTGRID_END_SELECTION:
585 case FONTGRID_ACTIVATE:
586 guigedit_edit_glyph(ed, si);
588 case FONTGRID_BASE_CHANGE:
594 handle_modified_signal(GtkWidget *w, gpointer minfo, gpointer editor)
596 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(editor);
597 gchar *prgname = g_get_prgname();
598 FontgridModificationInfo *mi;
600 mi = (FontgridModificationInfo *) minfo;
603 * Check to see what change was made so updates can be handled
606 if (mi->reason == FONTGRID_NAME_MODIFIED)
607 gtk_entry_set_text(GTK_ENTRY(ed->fontname), mi->name);
608 else if (mi->reason == FONTGRID_PROPERTIES_MODIFIED)
610 * Make sure the font info editing dialog knows that the list of
611 * font properties changed.
613 guiedit_update_font_properties(ed);
614 else if (mi->reason == FONTGRID_GLYPHS_DELETED ||
615 mi->reason == FONTGRID_GLYPHS_PASTED)
616 guiedit_update_font_details(ed);
617 else if ((mi->reason == FONTGRID_DEVICE_WIDTH_MODIFIED ||
618 mi->reason == FONTGRID_GLYPHS_MODIFIED) && glyphtest != 0)
620 * Update the glyph test widget with the new device width.
622 glyphtest_update_device_width(GLYPHTEST(glyphtest),
623 fontgrid_get_font(FONTGRID(ed->fgrid)));
629 sprintf(buffer1, "%s - (unnamed%d) [modified]", prgname, ed->id);
631 sprintf(buffer1, "%s - %s [modified]", prgname, ed->file);
633 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
637 view_font_messages(GtkWidget *w, gpointer editor)
639 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(editor);
640 GtkWidget *dialog, *frame, *button, *label, *vbox, *sw;
644 if (ed->messages_dialog == 0) {
646 * Special case of no messages and the menu item hasn't been
647 * checked for sensitivity yet.
649 if (fontgrid_get_font_messages(FONTGRID(ed->fgrid)) == 0)
652 dialog = ed->messages_dialog = gtk_dialog_new();
653 (void) g_signal_connect(G_OBJECT(dialog), "delete_event",
654 G_CALLBACK(gtk_widget_hide), 0);
656 frame = gtk_frame_new(0);
657 label = ed->messages_label = gtk_label_new("");
658 gtk_container_add(GTK_CONTAINER(frame), label);
660 vbox = GTK_DIALOG(dialog)->vbox;
661 gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 0);
663 sw = gtk_scrolled_window_new(NULL, NULL);
664 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
667 gtk_box_pack_start(GTK_BOX(vbox), sw, FALSE, FALSE, 0);
670 * Add the text widget.
672 text = gtk_text_buffer_new(NULL);
673 ed->messages_text = gtk_text_view_new_with_buffer(text);
674 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(ed->messages_text),
676 gtk_widget_set_size_request(ed->messages_text, 500, 200);
678 gtk_text_view_set_editable(GTK_TEXT_VIEW(ed->messages_text), FALSE);
679 gtk_container_add(GTK_CONTAINER(sw), ed->messages_text);
681 button = gtk_button_new_with_label("Close");
682 (void) g_signal_connect_object(G_OBJECT(button), "clicked",
683 G_CALLBACK(gtk_widget_hide),
686 gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->action_area),
689 gtk_widget_show_all(GTK_DIALOG(ed->messages_dialog)->vbox);
690 gtk_widget_show_all(GTK_DIALOG(ed->messages_dialog)->action_area);
692 text = gtk_text_view_get_buffer(GTK_TEXT_VIEW(ed->messages_text));
695 * Update the label with the font name in case it changed since the last
696 * time the messages were shown.
699 sprintf(buffer1, "%s: Messages", ed->file);
701 sprintf(buffer1, "unnamed%d.bdf: Messages", ed->id);
702 gtk_label_set_text(GTK_LABEL(ed->messages_label), buffer1);
705 * Now change the text itself.
707 if ((msgs = fontgrid_get_font_messages(FONTGRID(ed->fgrid))) == 0)
709 gtk_text_buffer_set_text(text, msgs, -1);
711 guiutil_show_dialog_centered(ed->messages_dialog, ed->shell);
714 /**************************************************************************
718 **************************************************************************/
721 make_accel_menu_item(GtkWidget *menu, const gchar *text, const gchar *accel,
726 GdkModifierType mods;
728 mi = gtk_menu_item_new_with_mnemonic(text);
730 gtk_accelerator_parse(accel, &key, &mods);
731 gtk_widget_add_accelerator(mi, "activate", ag, key, mods,
732 GTK_ACCEL_VISIBLE|GTK_ACCEL_LOCKED);
733 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mi);
739 * Handle all the menu checking needed to enable or disable menu items on
743 menu_popup(GtkWidget *w, GdkEvent *event, gpointer data)
753 * Get a pointer to the editor.
755 ed = editors + GPOINTER_TO_UINT(data);
757 font = fontgrid_get_font(FONTGRID(ed->fgrid));
759 if (event->type == GDK_MAP) {
760 if (w == ed->file_menu) {
761 if (font && font->modified)
762 gtk_widget_set_sensitive(ed->file_save, TRUE);
764 gtk_widget_set_sensitive(ed->file_save, FALSE);
766 if (font && font->glyphs_used > 0)
767 gtk_widget_set_sensitive(ed->file_export, TRUE);
769 gtk_widget_set_sensitive(ed->file_export, FALSE);
770 } else if (w == ed->edit_menu) {
772 * If the fontgrid clipboard is empty, then disable the paste,
773 * overlay, and insert menu options.
775 flag = fontgrid_clipboard_empty(FONTGRID(ed->fgrid)) ?
777 gtk_widget_set_sensitive(ed->edit_paste, flag);
778 gtk_widget_set_sensitive(ed->edit_overlay, flag);
779 gtk_widget_set_sensitive(ed->edit_insert, flag);
782 * If there is no selection, disable the cut and copy menu
785 flag = fontgrid_has_selection(FONTGRID(ed->fgrid), 0) ?
787 gtk_widget_set_sensitive(ed->edit_cut, flag);
788 gtk_widget_set_sensitive(ed->edit_copy, flag);
790 flag = (font && font->glyphs_used > 0) ? TRUE : FALSE;
793 * Disable glyph rename when viewing unecoded glyphs because their
794 * encoding values are not actual.
796 if (fontgrid_viewing_unencoded(FONTGRID(ed->fgrid)) || !flag)
797 gtk_widget_set_sensitive(ed->edit_rename_glyphs, FALSE);
799 gtk_widget_set_sensitive(ed->edit_rename_glyphs, TRUE);
801 gtk_widget_set_sensitive(ed->edit_test_glyphs, flag);
802 } else if (w == ed->edit_rename_menu) {
803 if (options.adobe_name_file != 0)
804 gtk_widget_set_sensitive(ed->edit_adobe_names, TRUE);
806 gtk_widget_set_sensitive(ed->edit_adobe_names, FALSE);
807 if (options.unicode_name_file != 0)
808 gtk_widget_set_sensitive(ed->edit_unicode_names, TRUE);
810 gtk_widget_set_sensitive(ed->edit_unicode_names, FALSE);
811 } else if (w == ed->name_submenu) {
812 flag = (!font || bdf_has_xlfd_name(font)) ? FALSE : TRUE;
813 gtk_widget_set_sensitive(ed->edit_make_xlfd, flag);
814 } else if (w == ed->view_menu) {
815 if (fontgrid_get_font_messages(FONTGRID(ed->fgrid)))
816 gtk_widget_set_sensitive(ed->view_messages, TRUE);
818 gtk_widget_set_sensitive(ed->view_messages, FALSE);
819 } else if (w == ed->win_menu) {
821 * Go through and update the file names that might have changed
822 * since the last time this menu popped up.
824 for (i = 0, kids = GTK_MENU(w)->menu_shell.children; kids != 0;
825 kids = kids->next, i++) {
826 if (editors[i].file == 0)
827 sprintf(buffer1, "(unnamed%d)", i);
829 strcpy(buffer1, editors[i].file);
830 label = gtk_container_get_children(GTK_CONTAINER(kids->data));
831 gtk_label_set_text(GTK_LABEL(label->data), buffer1);
835 * Add any new editors that were created since the last time this
838 for (; i < num_editors; i++) {
839 if (editors[i].file == 0)
840 sprintf(buffer1, "(unnamed%d)", editors[i].id);
842 strcpy(buffer1, editors[i].file);
844 mitem = gtk_menu_item_new_with_label(buffer1);
845 (void) g_signal_connect(G_OBJECT(mitem), "activate",
846 G_CALLBACK(show_editor),
847 GUINT_TO_POINTER(i));
848 gtk_menu_shell_append(GTK_MENU_SHELL(ed->win_menu), mitem);
849 gtk_widget_show(mitem);
853 * Disable the item for this editor.
855 gtk_widget_set_sensitive(ed->win_menu_item, FALSE);
857 } else if (event->type == GDK_UNMAP) {
859 * Enable everything again, so it doesn't get forgotten.
861 gtk_widget_set_sensitive(ed->file_save, TRUE);
862 gtk_widget_set_sensitive(ed->file_export, TRUE);
863 gtk_widget_set_sensitive(ed->edit_paste, TRUE);
864 gtk_widget_set_sensitive(ed->edit_overlay, TRUE);
865 gtk_widget_set_sensitive(ed->edit_insert, TRUE);
866 gtk_widget_set_sensitive(ed->edit_cut, TRUE);
867 gtk_widget_set_sensitive(ed->edit_copy, TRUE);
868 gtk_widget_set_sensitive(ed->edit_rename_glyphs, TRUE);
869 gtk_widget_set_sensitive(ed->edit_adobe_names, TRUE);
870 gtk_widget_set_sensitive(ed->edit_unicode_names, TRUE);
871 gtk_widget_set_sensitive(ed->edit_test_glyphs, TRUE);
872 gtk_widget_set_sensitive(ed->edit_make_xlfd, TRUE);
873 gtk_widget_set_sensitive(ed->win_menu_item, TRUE);
874 gtk_widget_set_sensitive(ed->view_messages, TRUE);
880 #if (GTK_MAJOR_VERSION >= 2 && GTK_MINOR_VERSION >= 10)
882 open_recent_font(GtkWidget *w, gpointer data)
884 gchar *p, *uri = gtk_recent_chooser_get_current_uri(GTK_RECENT_CHOOSER(w));
885 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
891 * Skip the URI prefix to get to the path. The URI's are strictly local
894 for (p = uri; *p && *p != ':'; p++);
898 if (*p == '/' && *(p + 1) == '/')
900 guifile_load_bdf_font(ed, (const gchar *) p);
905 make_recent_menu(guint ed_id)
908 GtkRecentFilter *filter;
909 GtkRecentManager *manager;
911 manager = gtk_recent_manager_get_default();
912 menu = gtk_recent_chooser_menu_new_for_manager(manager);
913 gtk_recent_chooser_set_limit(GTK_RECENT_CHOOSER(menu), 10);
914 gtk_recent_chooser_set_sort_type(GTK_RECENT_CHOOSER(menu),
915 GTK_RECENT_SORT_MRU);
916 gtk_recent_chooser_set_show_tips(GTK_RECENT_CHOOSER(menu), TRUE);
917 gtk_recent_chooser_menu_set_show_numbers(GTK_RECENT_CHOOSER_MENU(menu),
919 gtk_recent_chooser_set_local_only(GTK_RECENT_CHOOSER(menu), TRUE);
920 filter = gtk_recent_filter_new();
921 gtk_recent_filter_add_pattern(filter, "*.[Bb][Dd][Ff]");
922 gtk_recent_chooser_set_filter(GTK_RECENT_CHOOSER(menu), filter);
924 (void) g_signal_connect(G_OBJECT(menu), "item_activated",
925 G_CALLBACK(open_recent_font),
926 GUINT_TO_POINTER(ed_id));
933 make_file_menu(gbdfed_editor_t *ed, GtkWidget *menubar)
935 GtkWidget *file, *menu, *submenu, *mitem, *sep;
938 * Create the File menu.
940 file = gtk_menu_item_new_with_mnemonic("_File");
942 ed->file_menu = menu = gtk_menu_new();
943 (void) g_signal_connect(G_OBJECT(menu), "map_event",
944 G_CALLBACK(menu_popup),
945 GUINT_TO_POINTER(ed->id));
947 mitem = make_accel_menu_item(menu, "_New", "<Control>N", ed->ag);
948 (void) g_signal_connect(G_OBJECT(mitem), "activate",
949 G_CALLBACK(guifile_new_editor), 0);
951 mitem = make_accel_menu_item(menu, "_Open", "<Control>O", ed->ag);
952 (void) g_signal_connect(G_OBJECT(mitem), "activate",
953 G_CALLBACK(guifile_import_bdf_font),
954 GUINT_TO_POINTER(ed->id));
956 ed->file_save = make_accel_menu_item(menu, "_Save", "<Control>S", ed->ag);
957 (void) g_signal_connect(G_OBJECT(ed->file_save), "activate",
958 G_CALLBACK(guifile_save),
959 GUINT_TO_POINTER(ed->id));
960 mitem = make_accel_menu_item(menu, "Save _As...", "<Control>W", ed->ag);
961 (void) g_signal_connect(G_OBJECT(mitem), "activate",
962 G_CALLBACK(guifile_save_as),
963 GUINT_TO_POINTER(ed->id));
968 sep = gtk_menu_item_new();
969 gtk_widget_set_sensitive(sep, FALSE);
970 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
973 * Create the Import and Export menu items with their submenus.
975 mitem = gtk_menu_item_new_with_mnemonic("_Import");
976 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
978 submenu = gtk_menu_new();
979 gtk_menu_item_set_submenu(GTK_MENU_ITEM(mitem), submenu);
981 mitem = make_accel_menu_item(submenu, "_PK/GF Font", "<Control>K", ed->ag);
982 (void) g_signal_connect(G_OBJECT(mitem), "activate",
983 G_CALLBACK(guifile_import_pkgf_font),
984 GUINT_TO_POINTER(ed->id));
985 mitem = make_accel_menu_item(submenu, "_Console Font", "<Control>L",
987 (void) g_signal_connect(G_OBJECT(mitem), "activate",
988 G_CALLBACK(guifile_import_console_font),
989 GUINT_TO_POINTER(ed->id));
991 mitem = make_accel_menu_item(submenu, "_HBF Font", "<Control>H",
993 (void) g_signal_connect(G_OBJECT(mitem), "activate",
994 G_CALLBACK(guifile_import_hbf_font),
995 GUINT_TO_POINTER(ed->id));
998 mitem = make_accel_menu_item(submenu, "_Windows Font", "<Control>B",
1001 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1002 G_CALLBACK(guifile_import_windows_font),
1003 GUINT_TO_POINTER(ed->id));
1004 #ifdef HAVE_FREETYPE
1005 mitem = make_accel_menu_item(submenu, "_OpenType Font", "<Control>Y",
1007 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1008 G_CALLBACK(guifile_import_otf_font),
1009 GUINT_TO_POINTER(ed->id));
1010 #endif /* HAVE_FREETYPE */
1016 sep = gtk_menu_item_new();
1017 gtk_widget_set_sensitive(sep, FALSE);
1018 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), sep);
1020 mitem = make_accel_menu_item(submenu, "_X Server Font", "<Control>G",
1022 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1023 G_CALLBACK(guifile_import_xserver_font),
1024 GUINT_TO_POINTER(ed->id));
1027 ed->file_export = gtk_menu_item_new_with_mnemonic("Ex_port");
1028 gtk_menu_shell_append(GTK_MENU_SHELL(menu), ed->file_export);
1030 submenu = gtk_menu_new();
1031 gtk_menu_item_set_submenu(GTK_MENU_ITEM(ed->file_export), submenu);
1033 mitem = make_accel_menu_item(submenu, "_PSF Font", "<Control>F",
1035 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1036 G_CALLBACK(guifile_export_psf_font),
1037 GUINT_TO_POINTER(ed->id));
1038 mitem = gtk_menu_item_new_with_mnemonic("_HEX");
1039 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1040 G_CALLBACK(guifile_export_hex_font),
1041 GUINT_TO_POINTER(ed->id));
1042 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), mitem);
1043 mitem = gtk_menu_item_new_with_mnemonic("_C Header");
1044 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1045 G_CALLBACK(guifile_export_header_font),
1046 GUINT_TO_POINTER(ed->id));
1047 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), mitem);
1052 sep = gtk_menu_item_new();
1053 gtk_widget_set_sensitive(sep, FALSE);
1054 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
1056 #if (GTK_MAJOR_VERSION >=2 && GTK_MINOR_VERSION >= 10)
1058 * Only add the Recent Fonts menu if the GTK version supports it.
1060 mitem = gtk_menu_item_new_with_mnemonic("_Recent Fonts");
1061 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1062 gtk_menu_item_set_submenu(GTK_MENU_ITEM(mitem), make_recent_menu(ed->id));
1067 sep = gtk_menu_item_new();
1068 gtk_widget_set_sensitive(sep, FALSE);
1069 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
1073 mitem = make_accel_menu_item(menu, "E_xit", "<Control>F4", ed->ag);
1075 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1076 G_CALLBACK(quit_application),
1077 GUINT_TO_POINTER(ed->id));
1079 mitem = make_accel_menu_item(menu, "Clos_e", "<Control>F4", ed->ag);
1081 (void) g_signal_connect_object(G_OBJECT(mitem), "activate",
1082 G_CALLBACK(gtk_widget_hide),
1083 (gpointer) ed->shell,
1087 gtk_menu_item_set_submenu(GTK_MENU_ITEM(file), menu);
1093 make_xlfd_name(GtkWidget *w, gpointer data)
1095 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
1097 fontgrid_make_xlfd_font_name(FONTGRID(ed->fgrid));
1101 update_name_from_props(GtkWidget *w, gpointer data)
1103 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
1105 fontgrid_update_font_name_from_properties(FONTGRID(ed->fgrid));
1109 update_props_from_name(GtkWidget *w, gpointer data)
1111 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
1113 fontgrid_update_properties_from_font_name(FONTGRID(ed->fgrid));
1117 make_edit_menu(gbdfed_editor_t *ed, GtkWidget *menubar)
1119 GtkWidget *edit, *menu, *submenu, *mitem, *sep;
1122 * Create the Edit menu.
1124 edit = gtk_menu_item_new_with_mnemonic("_Edit");
1126 ed->edit_menu = menu = gtk_menu_new();
1127 (void) g_signal_connect(G_OBJECT(menu), "map_event",
1128 G_CALLBACK(menu_popup),
1129 GUINT_TO_POINTER(ed->id));
1131 ed->edit_copy = make_accel_menu_item(menu, "_Copy", "<Control>C", ed->ag);
1132 (void) g_signal_connect(G_OBJECT(ed->edit_copy), "activate",
1133 G_CALLBACK(guiedit_copy_selection),
1134 GUINT_TO_POINTER(ed->id));
1136 ed->edit_cut = make_accel_menu_item(menu, "C_ut", "<Control>X", ed->ag);
1137 (void) g_signal_connect(G_OBJECT(ed->edit_cut), "activate",
1138 G_CALLBACK(guiedit_cut_selection),
1139 GUINT_TO_POINTER(ed->id));
1141 ed->edit_paste = make_accel_menu_item(menu, "_Paste", "<Control>V",
1143 (void) g_signal_connect(G_OBJECT(ed->edit_paste), "activate",
1144 G_CALLBACK(guiedit_paste_selection),
1145 GUINT_TO_POINTER(ed->id));
1147 ed->edit_overlay = make_accel_menu_item(menu, "_Overlay",
1148 "<Shift><Control>V", ed->ag);
1149 (void) g_signal_connect(G_OBJECT(ed->edit_overlay), "activate",
1150 G_CALLBACK(guiedit_overlay_selection),
1151 GUINT_TO_POINTER(ed->id));
1153 ed->edit_insert = make_accel_menu_item(menu, "_Insert",
1154 "<Control><Alt>V", ed->ag);
1155 (void) g_signal_connect(G_OBJECT(ed->edit_insert), "activate",
1156 G_CALLBACK(guiedit_insert_selection),
1157 GUINT_TO_POINTER(ed->id));
1162 sep = gtk_menu_item_new();
1163 gtk_widget_set_sensitive(sep, FALSE);
1164 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
1166 mitem = make_accel_menu_item(menu, "P_roperties", "<Control>P", ed->ag);
1167 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1168 G_CALLBACK(guiedit_show_font_properties),
1169 GUINT_TO_POINTER(ed->id));
1171 mitem = make_accel_menu_item(menu, "Co_mments", "<Control>M", ed->ag);
1172 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1173 G_CALLBACK(guiedit_show_font_comments),
1174 GUINT_TO_POINTER(ed->id));
1176 mitem = make_accel_menu_item(menu, "_Font Info", "<Control>I", ed->ag);
1177 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1178 G_CALLBACK(guiedit_show_font_info),
1179 GUINT_TO_POINTER(ed->id));
1183 sep = gtk_menu_item_new();
1184 gtk_widget_set_sensitive(sep, FALSE);
1185 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
1188 * Create the Font Name submenu.
1190 mitem = gtk_menu_item_new_with_mnemonic("Font _Name");
1191 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1193 ed->name_submenu = submenu = gtk_menu_new();
1194 gtk_menu_item_set_submenu(GTK_MENU_ITEM(mitem), submenu);
1195 (void) g_signal_connect(G_OBJECT(submenu), "map_event",
1196 G_CALLBACK(menu_popup),
1197 GUINT_TO_POINTER(ed->id));
1199 ed->edit_make_xlfd = gtk_menu_item_new_with_mnemonic("Make _XLFD Name");
1200 (void) g_signal_connect(G_OBJECT(ed->edit_make_xlfd), "activate",
1201 G_CALLBACK(make_xlfd_name),
1202 GUINT_TO_POINTER(ed->id));
1203 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), ed->edit_make_xlfd);
1205 mitem = gtk_menu_item_new_with_mnemonic("Update _Name From Properties");
1206 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1207 G_CALLBACK(update_name_from_props),
1208 GUINT_TO_POINTER(ed->id));
1209 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), mitem);
1211 mitem = gtk_menu_item_new_with_mnemonic("Update _Properties From Name");
1212 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1213 G_CALLBACK(update_props_from_name),
1214 GUINT_TO_POINTER(ed->id));
1215 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), mitem);
1216 mitem = gtk_menu_item_new_with_mnemonic("Update _Average Width");
1217 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), mitem);
1222 sep = gtk_menu_item_new();
1223 gtk_widget_set_sensitive(sep, FALSE);
1224 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
1227 * Make the glyph naming menus and submenus.
1229 ed->edit_rename_glyphs = gtk_menu_item_new_with_mnemonic("Ren_ame Glyphs");
1230 gtk_menu_shell_append(GTK_MENU_SHELL(menu), ed->edit_rename_glyphs);
1232 ed->edit_rename_menu = submenu = gtk_menu_new();
1233 (void) g_signal_connect(G_OBJECT(submenu), "map_event",
1234 G_CALLBACK(menu_popup),
1235 GUINT_TO_POINTER(ed->id));
1236 gtk_menu_item_set_submenu(GTK_MENU_ITEM(ed->edit_rename_glyphs), submenu);
1238 ed->edit_unicode_names = gtk_menu_item_new_with_mnemonic("_Unicode Names");
1239 (void) g_signal_connect(G_OBJECT(ed->edit_unicode_names), "activate",
1240 G_CALLBACK(guiedit_set_unicode_glyph_names),
1241 GUINT_TO_POINTER(ed->id));
1242 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), ed->edit_unicode_names);
1244 ed->edit_adobe_names = gtk_menu_item_new_with_mnemonic("_Adobe Names");
1245 (void) g_signal_connect(G_OBJECT(ed->edit_adobe_names), "activate",
1246 G_CALLBACK(guiedit_set_adobe_glyph_names),
1247 GUINT_TO_POINTER(ed->id));
1248 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), ed->edit_adobe_names);
1250 mitem = gtk_menu_item_new_with_mnemonic("_Hexadecimal Values");
1251 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), mitem);
1252 submenu = gtk_menu_new();
1253 gtk_menu_item_set_submenu(GTK_MENU_ITEM(mitem), submenu);
1255 mitem = gtk_menu_item_new_with_mnemonic("_uniXXXX");
1256 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1257 G_CALLBACK(guiedit_set_uni_glyph_names),
1258 GUINT_TO_POINTER(ed->id));
1259 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), mitem);
1261 mitem = gtk_menu_item_new_with_mnemonic("0_xXXXX");
1262 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1263 G_CALLBACK(guiedit_set_zerox_glyph_names),
1264 GUINT_TO_POINTER(ed->id));
1265 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), mitem);
1267 mitem = gtk_menu_item_new_with_mnemonic("U_+XXXX");
1268 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1269 G_CALLBACK(guiedit_set_uplus_glyph_names),
1270 GUINT_TO_POINTER(ed->id));
1271 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), mitem);
1273 mitem = gtk_menu_item_new_with_mnemonic("_\\uXXXX");
1274 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1275 G_CALLBACK(guiedit_set_bslashu_glyph_names),
1276 GUINT_TO_POINTER(ed->id));
1277 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), mitem);
1279 ed->edit_test_glyphs = make_accel_menu_item(menu, "_Test Glyphs",
1280 "<Control>Z", ed->ag);
1281 (void) g_signal_connect(G_OBJECT(ed->edit_test_glyphs), "activate",
1282 G_CALLBACK(guiedit_show_glyphtest),
1283 GUINT_TO_POINTER(ed->id));
1288 sep = gtk_menu_item_new();
1289 gtk_widget_set_sensitive(sep, FALSE);
1290 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
1292 mitem = make_accel_menu_item(menu, "Pr_eferences", "<Control>T", ed->ag);
1293 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1294 G_CALLBACK(guiedit_show_preferences), 0);
1296 gtk_menu_item_set_submenu(GTK_MENU_ITEM(edit), menu);
1302 make_view_menu(gbdfed_editor_t *ed, GtkWidget *menubar)
1304 GtkWidget *view, *menu, *submenu, *mitem, *sep;
1306 GtkRadioMenuItem *ri;
1309 * Create the View menu.
1311 view = gtk_menu_item_new_with_mnemonic("_View");
1313 ed->view_menu = menu = gtk_menu_new();
1314 (void) g_signal_connect(G_OBJECT(menu), "map_event",
1315 G_CALLBACK(menu_popup),
1316 GUINT_TO_POINTER(ed->id));
1318 ed->view_unencoded = mitem =
1319 make_accel_menu_item(menu, "Unencoded", "<Control>E", ed->ag);
1320 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1321 G_CALLBACK(toggle_encoding_view),
1322 GUINT_TO_POINTER(ed->id));
1325 * Create the Code Base submenu.
1327 mitem = gtk_menu_item_new_with_mnemonic("_Code Base");
1328 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1330 submenu = gtk_menu_new();
1331 gtk_menu_item_set_submenu(GTK_MENU_ITEM(mitem), submenu);
1333 ed->view_oct = mitem = gtk_radio_menu_item_new_with_mnemonic(0, "_Octal");
1334 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), mitem);
1335 ri = GTK_RADIO_MENU_ITEM(mitem);
1336 if (options.code_base == 8)
1337 gtk_check_menu_item_set_active(&ri->check_menu_item, TRUE);
1339 group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(mitem));
1340 ed->view_dec = mitem =
1341 gtk_radio_menu_item_new_with_mnemonic(group, "_Decimal");
1342 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), mitem);
1343 ri = GTK_RADIO_MENU_ITEM(mitem);
1344 if (options.code_base == 10)
1345 gtk_check_menu_item_set_active(&ri->check_menu_item, TRUE);
1347 group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(mitem));
1348 ed->view_hex = mitem =
1349 gtk_radio_menu_item_new_with_mnemonic(group, "_Hexadecimal");
1350 gtk_menu_shell_append(GTK_MENU_SHELL(submenu), mitem);
1351 ri = GTK_RADIO_MENU_ITEM(mitem);
1352 if (options.code_base == 16)
1353 gtk_check_menu_item_set_active(&ri->check_menu_item, TRUE);
1356 * Add the code base toggle handler to the three toggles.
1358 (void) g_signal_connect(G_OBJECT(ed->view_oct), "toggled",
1359 G_CALLBACK(set_code_base),
1360 GUINT_TO_POINTER(ed->id));
1361 (void) g_signal_connect(G_OBJECT(ed->view_dec), "toggled",
1362 G_CALLBACK(set_code_base),
1363 GUINT_TO_POINTER(ed->id));
1364 (void) g_signal_connect(G_OBJECT(ed->view_hex), "toggled",
1365 G_CALLBACK(set_code_base),
1366 GUINT_TO_POINTER(ed->id));
1371 sep = gtk_menu_item_new();
1372 gtk_widget_set_sensitive(sep, FALSE);
1373 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
1375 mitem = make_accel_menu_item(menu, "_Other Page", "<Shift><Control>S",
1377 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1378 G_CALLBACK(goto_other_page),
1379 GUINT_TO_POINTER(ed->id));
1381 if (options.orientation == GTK_ORIENTATION_VERTICAL)
1382 ed->view_orientation = mitem =
1383 make_accel_menu_item(menu, "Horizontal View", "<Control>Q", ed->ag);
1385 ed->view_orientation = mitem =
1386 make_accel_menu_item(menu, "Vertical View", "<Control>Q", ed->ag);
1387 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1388 G_CALLBACK(toggle_view_orientation),
1389 GUINT_TO_POINTER(ed->id));
1394 sep = gtk_menu_item_new();
1395 gtk_widget_set_sensitive(sep, FALSE);
1396 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
1401 ed->view_messages = mitem =
1402 make_accel_menu_item(menu, "_Messages", "<Control>A", ed->ag);
1403 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1404 G_CALLBACK(view_font_messages),
1405 GUINT_TO_POINTER(ed->id));
1407 gtk_menu_item_set_submenu(GTK_MENU_ITEM(view), menu);
1413 make_ops_menu(gbdfed_editor_t *ed, GtkWidget *menubar)
1415 GtkWidget *ops, *menu, *mitem;
1418 * Create the Edit menu.
1420 ops = gtk_menu_item_new_with_mnemonic("_Operations");
1422 ed->ops_menu = menu = gtk_menu_new();
1423 (void) g_signal_connect(G_OBJECT(menu), "map_event",
1424 G_CALLBACK(menu_popup),
1425 GUINT_TO_POINTER(ed->id));
1427 mitem = make_accel_menu_item(menu, "_Translate Glyphs", "<Control>D",
1429 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1430 G_CALLBACK(guiops_show_translate),
1431 GUINT_TO_POINTER(ed->id));
1433 mitem = make_accel_menu_item(menu, "_Rotate Glyphs", "<Control>R",
1435 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1436 G_CALLBACK(guiops_show_rotate),
1437 GUINT_TO_POINTER(ed->id));
1439 mitem = make_accel_menu_item(menu, "_Shear Glyphs", "<Control>J",
1441 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1442 G_CALLBACK(guiops_show_shear),
1443 GUINT_TO_POINTER(ed->id));
1445 mitem = make_accel_menu_item(menu, "_Embolden Glyphs", "<Shift><Control>B",
1447 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1448 G_CALLBACK(guiops_show_embolden),
1449 GUINT_TO_POINTER(ed->id));
1451 gtk_menu_item_set_submenu(GTK_MENU_ITEM(ops), menu);
1457 make_windows_menu(gbdfed_editor_t *ed, GtkWidget *menubar)
1459 GtkWidget *win, *menu, *mitem;
1462 win = gtk_menu_item_new_with_mnemonic("_Windows");
1464 ed->win_menu = menu = gtk_menu_new();
1465 (void) g_signal_connect(G_OBJECT(menu), "map_event",
1466 G_CALLBACK(menu_popup),
1467 GUINT_TO_POINTER(ed->id));
1469 for (i = 0; i < num_editors; i++) {
1470 if (editors[i].file == 0)
1471 sprintf(buffer1, "(unnamed%d)", editors[i].id);
1473 strcpy(buffer1, editors[i].file);
1475 ed->win_menu_item = mitem = gtk_menu_item_new_with_label(buffer1);
1476 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1477 G_CALLBACK(show_editor),
1478 GUINT_TO_POINTER(ed->id));
1479 gtk_menu_shell_append(GTK_MENU_SHELL(ed->win_menu), mitem);
1482 gtk_menu_item_set_submenu(GTK_MENU_ITEM(win), menu);
1488 make_help_menu(gbdfed_editor_t *ed, GtkWidget *menubar)
1490 GtkWidget *help, *menu, *mitem, *sep;
1493 * Create the Edit menu.
1495 help = gtk_menu_item_new_with_mnemonic("_Help");
1496 gtk_menu_item_set_right_justified(GTK_MENU_ITEM(help), TRUE);
1498 menu = gtk_menu_new();
1500 mitem = gtk_menu_item_new_with_mnemonic("The _Program");
1501 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1502 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1503 G_CALLBACK(guihelp_show_help),
1504 GINT_TO_POINTER(GUIHELP_PROGRAM));
1506 mitem = gtk_menu_item_new_with_mnemonic("_Font Grid");
1507 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1508 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1509 G_CALLBACK(guihelp_show_help),
1510 GINT_TO_POINTER(GUIHELP_FONTGRID));
1512 mitem = gtk_menu_item_new_with_mnemonic("_Glyph Editor");
1513 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1514 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1515 G_CALLBACK(guihelp_show_help),
1516 GINT_TO_POINTER(GUIHELP_GLYPH_EDITOR));
1518 mitem = gtk_menu_item_new_with_mnemonic("_Configuration File");
1519 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1520 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1521 G_CALLBACK(guihelp_show_help),
1522 GINT_TO_POINTER(GUIHELP_CONFIG_FILE));
1524 mitem = gtk_menu_item_new_with_mnemonic("P_references Dialog");
1525 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1526 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1527 G_CALLBACK(guihelp_show_help),
1528 GINT_TO_POINTER(GUIHELP_PREFERENCES));
1533 sep = gtk_menu_item_new();
1534 gtk_widget_set_sensitive(sep, FALSE);
1535 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
1537 mitem = gtk_menu_item_new_with_mnemonic("_Windows Font Notes");
1538 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1539 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1540 G_CALLBACK(guihelp_show_help),
1541 GINT_TO_POINTER(GUIHELP_FNT));
1543 mitem = gtk_menu_item_new_with_mnemonic("_OpenType Font Notes");
1544 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1545 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1546 G_CALLBACK(guihelp_show_help),
1547 GINT_TO_POINTER(GUIHELP_OTF));
1549 mitem = gtk_menu_item_new_with_mnemonic("P_SF Font Notes");
1550 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1551 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1552 G_CALLBACK(guihelp_show_help),
1553 GINT_TO_POINTER(GUIHELP_PSF));
1555 mitem = gtk_menu_item_new_with_mnemonic("_HEX Font Notes");
1556 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1557 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1558 G_CALLBACK(guihelp_show_help),
1559 GINT_TO_POINTER(GUIHELP_HEX));
1564 sep = gtk_menu_item_new();
1565 gtk_widget_set_sensitive(sep, FALSE);
1566 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
1568 mitem = gtk_menu_item_new_with_mnemonic("C_olor Notes");
1569 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1570 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1571 G_CALLBACK(guihelp_show_help),
1572 GINT_TO_POINTER(GUIHELP_COLOR));
1577 sep = gtk_menu_item_new();
1578 gtk_widget_set_sensitive(sep, FALSE);
1579 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
1581 mitem = gtk_menu_item_new_with_mnemonic("T_ips");
1582 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1583 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1584 G_CALLBACK(guihelp_show_help),
1585 GINT_TO_POINTER(GUIHELP_TIPS));
1590 sep = gtk_menu_item_new();
1591 gtk_widget_set_sensitive(sep, FALSE);
1592 gtk_menu_shell_append(GTK_MENU_SHELL(menu), sep);
1594 sprintf(buffer1, "_About %s", g_get_prgname());
1595 mitem = gtk_menu_item_new_with_mnemonic(buffer1);
1596 gtk_menu_shell_append(GTK_MENU_SHELL(menu), mitem);
1597 (void) g_signal_connect(G_OBJECT(mitem), "activate",
1598 G_CALLBACK(guihelp_show_help),
1599 GINT_TO_POINTER(GUIHELP_ABOUT));
1601 gtk_menu_item_set_submenu(GTK_MENU_ITEM(help), menu);
1606 #define UPDMSG "Font Name: XLFD name has been modified.\nDo you want to update the font properties from the name?"
1609 update_font_name(GtkWidget *w, gpointer data)
1611 gbdfed_editor_t *ed = editors + GPOINTER_TO_UINT(data);
1615 name = (gchar *) gtk_entry_get_text(GTK_ENTRY(ed->fontname));
1617 font = fontgrid_get_font(FONTGRID(ed->fgrid));
1618 if (font && strcmp(name, font->name) == 0)
1620 * There was no actual change to the name.
1624 fontgrid_set_font_name(FONTGRID(ed->fgrid), name);
1627 * If the new name is an XLFD name, then offer to update the
1628 * font properties from the name.
1630 if (font && bdf_has_xlfd_name(font)) {
1631 if (guiutil_yes_or_no(ed->shell, UPDMSG, TRUE)) {
1632 fontgrid_update_properties_from_font_name(FONTGRID(ed->fgrid));
1635 * If the font info dialog is up, make sure it is updated with
1636 * the font property changes.
1638 guiedit_update_font_properties(ed);
1644 gbdfed_make_editor(gchar *filename, gboolean cmdline)
1647 GtkWidget *mb, *mitem, *table;
1648 GtkWidget *vbox, *hbox, *bbox, *frame;
1649 gbdfed_editor_t *ed;
1652 GList *icon_list = 0;
1653 FontgridPageInfo pageinfo;
1658 * Attempt to load the specified font before doing anything else.
1660 if (filename != 0) {
1662 * Change code to put up an error dialog if the font won't load.
1664 if ((in = fopen(filename, "r")) == 0) {
1665 fprintf(stderr, "%s: unable to open BDF font '%s'.\n",
1666 g_get_prgname(), filename);
1667 if (num_editors > 0 && !cmdline)
1671 font = bdf_load_font(in, &options.font_opts, 0, 0);
1674 fprintf(stderr, "%s: problem loading BDF font '%s'.\n",
1675 g_get_prgname(), filename);
1680 * Create the icon list if it hasn't already been created.
1682 if (icons_set == FALSE) {
1684 * Create the 16x16 icon.
1686 icon_list = g_list_append(icon_list,
1687 gdk_pixbuf_new_from_xpm_data(gbdfed_48x48));
1688 icon_list = g_list_append(icon_list,
1689 gdk_pixbuf_new_from_xpm_data(gbdfed_32x32));
1690 icon_list = g_list_append(icon_list,
1691 gdk_pixbuf_new_from_xpm_data(gbdfed_16x16));
1693 gtk_window_set_default_icon_list(icon_list);
1699 * Create a new editor structure.
1701 if (num_editors == 0)
1702 editors = g_malloc(sizeof(gbdfed_editor_t));
1704 editors = g_realloc(editors,
1705 sizeof(gbdfed_editor_t) * (num_editors + 1));
1707 ed = editors + num_editors;
1708 (void) memset(ed, 0, sizeof(gbdfed_editor_t));
1709 ed->id = num_editors++;
1712 * Construct the path and filename from the one passed. This makes copies
1715 if (font != 0 && filename != 0) {
1716 if (filename[0] != G_DIR_SEPARATOR) {
1717 path = g_get_current_dir();
1718 sprintf(buffer1, "%s%c%s", path, G_DIR_SEPARATOR, filename);
1721 strcpy(buffer1, filename);
1723 ed->file = g_path_get_basename(buffer1);
1724 ed->path = g_path_get_dirname(buffer1);
1728 * Create the top level window for the editor.
1730 ed->shell = gtk_window_new(GTK_WINDOW_TOPLEVEL);
1733 * This is a bit risky, but it allows the shell to shrink to fit new
1734 * fonts when they are added.
1736 gtk_window_set_resizable(GTK_WINDOW(ed->shell), TRUE);
1739 (void) g_signal_connect(G_OBJECT(ed->shell), "destroy_event",
1740 G_CALLBACK(quit_application),
1741 GUINT_TO_POINTER(ed->id));
1742 (void) g_signal_connect(G_OBJECT(ed->shell), "delete_event",
1743 G_CALLBACK(quit_application),
1744 GUINT_TO_POINTER(ed->id));
1746 (void) g_signal_connect(G_OBJECT(ed->shell), "destroy_event",
1747 G_CALLBACK(gtk_widget_hide), 0);
1748 (void) g_signal_connect(G_OBJECT(ed->shell), "delete_event",
1749 G_CALLBACK(gtk_widget_hide), 0);
1753 * Determine the name for the window.
1756 sprintf(buffer1, "%s - (unnamed%d)", g_get_prgname(), ed->id);
1758 if (font && font->modified)
1759 sprintf(buffer1, "%s - %s [modified]", g_get_prgname(), ed->file);
1761 sprintf(buffer1, "%s - %s", g_get_prgname(), ed->file);
1763 gtk_window_set_title(GTK_WINDOW(ed->shell), buffer1);
1766 * Create the vertical box that will contain the widgets.
1768 table = gtk_table_new(5, 1, FALSE);
1769 gtk_container_add(GTK_CONTAINER(ed->shell), table);
1771 ed->ag = gtk_accel_group_new();
1773 mb = gtk_menu_bar_new();
1774 gtk_table_attach(GTK_TABLE(table), mb, 0, 1, 0, 1, GTK_FILL, GTK_FILL,
1778 * Create the File menu.
1780 mitem = make_file_menu(ed, mb);
1781 gtk_menu_shell_append(GTK_MENU_SHELL(mb), mitem);
1784 * Create the Edit menu.
1786 mitem = make_edit_menu(ed, mb);
1787 gtk_menu_shell_append(GTK_MENU_SHELL(mb), mitem);
1790 * Create the View menu.
1792 mitem = make_view_menu(ed, mb);
1793 gtk_menu_shell_append(GTK_MENU_SHELL(mb), mitem);
1796 * Create the Operations menu.
1798 mitem = make_ops_menu(ed, mb);
1799 gtk_menu_shell_append(GTK_MENU_SHELL(mb), mitem);
1802 * Create the Windows menu.
1804 mitem = make_windows_menu(ed, mb);
1805 gtk_menu_shell_append(GTK_MENU_SHELL(mb), mitem);
1808 * Create the Help menu.
1810 mitem = make_help_menu(ed, mb);
1811 gtk_menu_shell_append(GTK_MENU_SHELL(mb), mitem);
1814 * Attach the accelerators to the editor.
1816 gtk_window_add_accel_group(GTK_WINDOW(ed->shell), ed->ag);
1819 * 1. Add the font name widget.
1821 frame = gtk_frame_new(0);
1822 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
1823 gtk_table_attach(GTK_TABLE(table), frame, 0, 1, 1, 2, GTK_FILL, GTK_FILL,
1826 ed->fontname = gtk_widget_new(gtk_entry_get_type(),
1827 "max_length", 128, NULL);
1828 mitem = labcon_new_label_defaults("Font:", ed->fontname, 0);
1829 gtk_container_add(GTK_CONTAINER(frame), mitem);
1830 g_signal_connect(G_OBJECT(ed->fontname), "activate",
1831 G_CALLBACK(update_font_name), GUINT_TO_POINTER(ed->id));
1834 * 2. Add the glyph information widgets.
1836 frame = gtk_frame_new(0);
1837 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
1838 gtk_table_attach(GTK_TABLE(table), frame, 0, 1, 2, 3, GTK_FILL, GTK_FILL,
1841 vbox = gtk_vbox_new(TRUE, 0);
1842 ed->charinfo = gtk_label_new("\"None\" (0000) (00,00)");
1843 ed->metrics = gtk_label_new("ascent 0 descent 0 right 0 left 0");
1844 gtk_misc_set_alignment(GTK_MISC(ed->charinfo), 0.0, 0.5);
1845 gtk_misc_set_alignment(GTK_MISC(ed->metrics), 0.0, 0.5);
1846 gtk_box_pack_start(GTK_BOX(vbox), ed->charinfo, TRUE, TRUE, 0);
1847 gtk_box_pack_start(GTK_BOX(vbox), ed->metrics, TRUE, TRUE, 0);
1849 mitem = labcon_new_label_defaults("Glyph:", vbox, mitem);
1850 gtk_container_add(GTK_CONTAINER(frame), mitem);
1852 frame = gtk_frame_new(0);
1853 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
1854 gtk_table_attach(GTK_TABLE(table), frame, 0, 1, 3, 4, GTK_FILL, GTK_FILL,
1857 hbox = gtk_hbox_new(FALSE, 2);
1859 bbox = gtk_hbox_new(FALSE, 0);
1861 ed->first = gtk_button_new_with_label("First Page");
1862 (void) g_signal_connect(G_OBJECT(ed->first), "released",
1863 G_CALLBACK(first_page),
1864 GUINT_TO_POINTER(ed->id));
1866 ed->prev = gtk_button_new_with_label("Previous Page");
1867 (void) g_signal_connect(G_OBJECT(ed->prev), "released",
1868 G_CALLBACK(previous_page),
1869 GUINT_TO_POINTER(ed->id));
1871 ed->next = gtk_button_new_with_label("Next Page");
1872 (void) g_signal_connect(G_OBJECT(ed->next), "released",
1873 G_CALLBACK(next_page),
1874 GUINT_TO_POINTER(ed->id));
1876 ed->last = gtk_button_new_with_label("Last Page");
1877 (void) g_signal_connect(G_OBJECT(ed->last), "released",
1878 G_CALLBACK(last_page),
1879 GUINT_TO_POINTER(ed->id));
1881 gtk_box_pack_start(GTK_BOX(bbox), ed->first, FALSE, FALSE, 0);
1882 gtk_box_pack_start(GTK_BOX(bbox), ed->prev, FALSE, FALSE, 0);
1883 gtk_box_pack_start(GTK_BOX(bbox), ed->next, FALSE, FALSE, 0);
1884 gtk_box_pack_start(GTK_BOX(bbox), ed->last, FALSE, FALSE, 0);
1886 gtk_box_pack_start(GTK_BOX(hbox), bbox, FALSE, FALSE, 0);
1888 mitem = gtk_label_new("Page:");
1889 ed->pageno = gtk_widget_new(gtk_entry_get_type(),
1891 "width-request", 70,
1893 (void) g_signal_connect(G_OBJECT(ed->pageno), "activate",
1894 G_CALLBACK(goto_page_or_code),
1895 GUINT_TO_POINTER(ed->id));
1897 gtk_box_pack_start(GTK_BOX(hbox), mitem, FALSE, FALSE, 0);
1898 gtk_box_pack_start(GTK_BOX(hbox), ed->pageno, FALSE, FALSE, 0);
1900 mitem = gtk_label_new("Code:");
1901 ed->charno = gtk_widget_new(gtk_entry_get_type(),
1903 "width-request", 70,
1905 (void) g_signal_connect(G_OBJECT(ed->charno), "activate",
1906 G_CALLBACK(goto_page_or_code),
1907 GUINT_TO_POINTER(ed->id));
1909 gtk_box_pack_start(GTK_BOX(hbox), mitem, FALSE, FALSE, 0);
1910 gtk_box_pack_start(GTK_BOX(hbox), ed->charno, FALSE, FALSE, 0);
1912 gtk_container_add(GTK_CONTAINER(frame), hbox);
1915 * Now add the font grid itself.
1917 ed->fgrid = fontgrid_newv(font,
1918 options.font_opts.point_size,
1919 options.font_opts.font_spacing,
1921 options.overwrite_mode,
1924 options.initial_glyph,
1926 options.orientation,
1927 options.font_opts.bits_per_pixel,
1928 options.font_opts.resolution_x,
1929 options.font_opts.resolution_y,
1931 (void) g_signal_connect(G_OBJECT(ed->fgrid), "turn_to_page",
1932 G_CALLBACK(page_change),
1933 GUINT_TO_POINTER(ed->id));
1934 (void) g_signal_connect(G_OBJECT(ed->fgrid), "selection-start",
1935 G_CALLBACK(update_selection_info),
1936 GUINT_TO_POINTER(ed->id));
1937 (void) g_signal_connect(G_OBJECT(ed->fgrid), "selection-extend",
1938 G_CALLBACK(update_selection_info),
1939 GUINT_TO_POINTER(ed->id));
1940 (void) g_signal_connect(G_OBJECT(ed->fgrid), "selection-end",
1941 G_CALLBACK(update_selection_info),
1942 GUINT_TO_POINTER(ed->id));
1943 (void) g_signal_connect(G_OBJECT(ed->fgrid), "activate",
1944 G_CALLBACK(update_selection_info),
1945 GUINT_TO_POINTER(ed->id));
1946 (void) g_signal_connect(G_OBJECT(ed->fgrid), "modified",
1947 G_CALLBACK(handle_modified_signal),
1948 GUINT_TO_POINTER(ed->id));
1949 gtk_table_attach(GTK_TABLE(table), ed->fgrid, 0, 1, 4, 5,
1950 GTK_FILL|GTK_EXPAND|GTK_SHRINK,
1951 GTK_FILL|GTK_EXPAND|GTK_SHRINK, 0, 0);
1954 * Set up the initial page information.
1956 page_change(ed->fgrid, &pageinfo, GUINT_TO_POINTER(ed->id));
1959 * Show the editor if it the first one created or is not being created
1960 * from the command line.
1963 gtk_widget_show_all(ed->shell);
1967 * Get the initial selection info to set up the glyph info labels.
1969 * NOTE: This has to be done here because for some reason labels
1970 * do not display properly if changed before the editor is fully
1973 FontgridSelectionInfo sinfo;
1974 if (fontgrid_has_selection(FONTGRID(ed->fgrid), &sinfo) == TRUE)
1975 update_selection_info(ed->fgrid, (gpointer) &sinfo,
1976 GUINT_TO_POINTER(ed->id));
1980 * Set the font name in the entry field if the font exists.
1982 gtk_entry_set_text(GTK_ENTRY(ed->fontname),
1983 fontgrid_get_font_name(FONTGRID(ed->fgrid)));
1986 * Change the focus to the Fontgrid.
1988 gtk_widget_grab_focus(ed->fgrid);
1994 handle_unknown_options(bdf_options_t *opts, char **params,
1995 unsigned int nparams, void *client_data)
1998 gbdfed_options_t *op;
2000 op = (gbdfed_options_t *) client_data;
2006 * Handle the 2 bits per pixel color list.
2008 if (strncmp(params[0], "2bpp_grays", 10) == 0) {
2009 for (idx = 1; idx < 5; idx++)
2010 op->colors[idx] = (unsigned short) _bdf_atos(params[idx], 0, 10);
2015 * Handle the 4 bits per pixel color list.
2017 if (strncmp(params[0], "4bpp_grays", 10) == 0) {
2018 for (idx = 1; idx < 17; idx++)
2019 op->colors[idx-1+4] = (unsigned short) _bdf_atos(params[idx], 0, 10);
2023 if (params[0][0] == 'a' &&
2024 strncmp(params[0], "adobe_name_file", 15) == 0) {
2025 if (op->adobe_name_file != 0)
2026 g_free(op->adobe_name_file);
2027 if (params[1] == 0 || params[1][0] == 0)
2028 op->adobe_name_file = 0;
2030 op->adobe_name_file = g_strdup(params[1]);
2034 if (params[0][0] == 'c') {
2035 if (strncmp(params[0], "close_accelerator", 17) == 0) {
2036 if (params[0][17] == 0) {
2038 * We have the accelerator itself. Add code to convert Xt key
2041 if (op->accelerator != 0)
2042 g_free(op->accelerator);
2043 if (params[1] == 0 || params[1][0] == 0)
2044 op->accelerator = 0;
2046 op->accelerator = g_strdup(params[1]);
2050 * Ignore instances of 'close_accelerator_text'. GTK+ figures this
2057 if (strncmp(params[0], "code_base", 9) == 0) {
2058 switch (params[1][0]) {
2059 case 'o': case 'O': op->code_base = 8; break;
2060 case 'd': case 'D': op->code_base = 10; break;
2061 case 'h': case 'H': op->code_base = 16; break;
2062 default: op->code_base = 16;
2068 * Ignore the old grayscale specification keywords.
2070 if (strncmp(params[0], "color", 5) == 0) {
2072 * Quietly ignore the old color list.
2078 if (params[0][0] == 'f' &&
2079 strncmp(params[0], "font_grid_horizontal", 20) == 0) {
2080 switch (params[1][0]) {
2081 case '0': case 'F': case 'f': case 'N': case 'n':
2082 op->orientation = GTK_ORIENTATION_VERTICAL;
2084 case '1': case 'T': case 't': case 'Y': case 'y':
2085 op->orientation = GTK_ORIENTATION_HORIZONTAL;
2091 if (params[0][0] == 'g') {
2092 if (strncmp(params[0], "grid_overwrite_mode", 19) == 0) {
2093 switch (params[1][0]) {
2094 case '0': case 'F': case 'f': case 'N': case 'n':
2095 op->overwrite_mode = FALSE;
2097 case '1': case 'T': case 't': case 'Y': case 'y':
2098 op->overwrite_mode = TRUE;
2104 if (strncmp(params[0], "generate_sbit_metrics", 21) == 0) {
2105 switch (params[1][0]) {
2106 case '0': case 'F': case 'f': case 'N': case 'n':
2109 case '1': case 'T': case 't': case 'Y': case 'y':
2117 if (params[0][0] == 'm' && strncmp(params[0], "make_backups", 12) == 0) {
2118 switch (params[1][0]) {
2119 case '0': case 'F': case 'f': case 'N': case 'n':
2120 op->backups = FALSE;
2122 case '1': case 'T': case 't': case 'Y': case 'y':
2129 if ((params[0][0] == 'n' && strncmp(params[0], "name_file", 9) == 0) ||
2130 (params[0][0] == 'u' &&
2131 strncmp(params[0], "unicode_name_file", 17) == 0)) {
2132 if (op->unicode_name_file != 0)
2133 g_free(op->unicode_name_file);
2134 if (params[1] == 0 || params[1][0] == 0)
2135 op->unicode_name_file = 0;
2137 op->unicode_name_file = g_strdup(params[1]);
2141 if (params[0][0] == 'o' && strncmp(params[0], "orientation", 11) == 0) {
2142 switch (params[1][0]) {
2144 op->orientation = GTK_ORIENTATION_HORIZONTAL;
2147 op->orientation = GTK_ORIENTATION_VERTICAL;
2153 if (params[0][0] == 'p') {
2154 if (strncmp(params[0], "pixel_size", 10) == 0) {
2155 op->pixel_size = _bdf_atoul(params[1], 0, 10);
2156 if (op->pixel_size < 2)
2158 else if (op->pixel_size > 20)
2159 op->pixel_size = 20;
2163 if (strncmp(params[0], "power2", 6) == 0) {
2164 switch (params[1][0]) {
2165 case '0': case 'F': case 'f': case 'N': case 'n':
2168 case '1': case 'T': case 't': case 'Y': case 'y':
2175 if (strncmp(params[0], "percentage_only", 15) == 0)
2177 * Ignore this option. No longer needed.
2181 if (strncmp(params[0], "progress_bar", 12) == 0)
2183 * The progress bar is no longer being used as of version 5.0.
2188 if (params[0][0] == 'r') {
2189 if (strncmp(params[0], "resolution", 10) == 0) {
2190 op->resolution = _bdf_atoul(params[1], 0, 10);
2194 if (strncmp(params[0], "really_exit", 11) == 0) {
2195 switch (params[1][0]) {
2196 case '0': case 'F': case 'f': case 'N': case 'n':
2197 op->really_exit = FALSE;
2199 case '1': case 'T': case 't': case 'Y': case 'y':
2200 op->really_exit = TRUE;
2207 if (params[0][0] == 's') {
2208 if (strncmp(params[0], "skip_blank_pages", 16) == 0) {
2209 switch (params[1][0]) {
2210 case '0': case 'F': case 'f': case 'N': case 'n':
2211 op->no_blanks = FALSE;
2213 case '1': case 'T': case 't': case 'Y': case 'y':
2214 op->no_blanks = TRUE;
2220 if (strncmp(params[0], "show_cap_height", 15) == 0) {
2221 switch (params[1][0]) {
2222 case '0': case 'F': case 'f': case 'N': case 'n':
2223 op->show_cap_height = FALSE;
2225 case '1': case 'T': case 't': case 'Y': case 'y':
2226 op->show_cap_height = TRUE;
2232 if (strncmp(params[0], "show_x_height", 13) == 0) {
2233 switch (params[1][0]) {
2234 case '0': case 'F': case 'f': case 'N': case 'n':
2235 op->show_x_height = FALSE;
2237 case '1': case 'T': case 't': case 'Y': case 'y':
2238 op->show_x_height = TRUE;
2251 fprintf(stderr, "Usage: %s [font1.bdf .....]\n", g_get_prgname());
2256 editor_setup(int argc, char *argv[])
2261 gboolean need_editor;
2265 * Get the default BDF options.
2267 bdf_default_options(&options.font_opts);
2269 options.accelerator = options.accelerator_text =
2270 options.unicode_name_file = options.adobe_name_file = 0;
2271 options.pixel_size = 10;
2272 options.resolution = 0;
2273 options.no_blanks = options.really_exit =
2274 options.overwrite_mode = options.power2 =
2275 options.backups = TRUE;
2276 options.show_cap_height = options.show_x_height =
2277 options.sbit = options.gbdfed_opts = FALSE;
2278 options.initial_glyph = -1;
2279 options.code_base = 16;
2281 options.orientation = GTK_ORIENTATION_HORIZONTAL;
2284 * Set the default colors for 2 bits per pixel.
2286 options.colors[0] = 0;
2287 options.colors[1] = 175;
2288 options.colors[2] = 207;
2289 options.colors[3] = 239;
2292 * Set the default colors for 4 bits per pixel.
2294 options.colors[4] = 0;
2295 options.colors[5] = 31;
2296 options.colors[6] = 63;
2297 options.colors[7] = 95;
2298 options.colors[8] = 127;
2299 options.colors[9] = 159;
2300 options.colors[10] = 167;
2301 options.colors[11] = 175;
2302 options.colors[12] = 183;
2303 options.colors[13] = 191;
2304 options.colors[14] = 199;
2305 options.colors[15] = 207;
2306 options.colors[16] = 215;
2307 options.colors[17] = 223;
2308 options.colors[18] = 231;
2309 options.colors[19] = 239;
2312 * Attempt to load the user config file.
2314 if ((ap = getenv("HOME")) != 0) {
2315 sprintf(buffer1, "%s/.gbdfedrc", ap);
2316 if ((in = fopen(buffer1, "r")) != 0) {
2317 bdf_load_options(in, &options.font_opts, handle_unknown_options,
2322 * Try reading the older ".xmbdfedrc".
2324 sprintf(buffer1, "%s/.xmbdfedrc", ap);
2325 if ((in = fopen(buffer1, "r")) != 0) {
2326 bdf_load_options(in, &options.font_opts,
2327 handle_unknown_options, (void *) &options);
2334 * Determine the horizontal and vertical resolutions if they have not been
2335 * set on the command line or from the config file.
2337 if (options.resolution != 0)
2338 options.font_opts.resolution_x = options.font_opts.resolution_y =
2341 screen = gdk_drawable_get_screen(GDK_DRAWABLE(gdk_get_default_root_window()));
2342 if (options.font_opts.resolution_x == 0)
2343 options.font_opts.resolution_x =
2344 (unsigned int) ((((double) gdk_screen_get_width(screen)) * 25.4) /
2345 ((double) gdk_screen_get_width_mm(screen)) + 0.5);
2347 if (options.font_opts.resolution_y == 0)
2348 options.font_opts.resolution_y =
2349 (unsigned int) ((((double) gdk_screen_get_height(screen)) * 25.4) /
2350 ((double) gdk_screen_get_height_mm(screen)) + 0.5);
2353 * Handle the case of no command line options here.
2356 (void) gbdfed_make_editor(0, TRUE);
2361 * If a filename is not present on the command line, make sure an
2362 * editor is created after the command line is parsed.
2367 * Now parse the options from the command line.
2372 if (strcmp(ap + 1, "nm") == 0)
2373 options.font_opts.correct_metrics = 0;
2374 else if (strcmp(ap + 1, "nu") == 0)
2375 options.font_opts.keep_unencoded = 0;
2376 else if (strcmp(ap + 1, "nc") == 0)
2377 options.font_opts.keep_comments = 0;
2378 else if (strcmp(ap + 1, "np") == 0)
2379 options.font_opts.pad_cells = 0;
2380 else if (strcmp(ap + 1, "bp") == 0)
2381 options.no_blanks = FALSE;
2382 else if (strcmp(ap + 1, "ed") == 0)
2383 options.really_exit = FALSE;
2384 else if (strcmp(ap + 1, "im") == 0)
2385 options.overwrite_mode = FALSE;
2386 else if (strcmp(ap + 1, "o") == 0) {
2389 options.orientation =
2390 (argv[0][0] == 'v' || argv[0][0] == 'V') ?
2391 GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL;
2392 } else if (strcmp(ap + 1, "ps") == 0) {
2395 options.font_opts.point_size = _bdf_atoul(*argv, 0, 10);
2396 } else if (strcmp(ap + 1, "res") == 0) {
2399 options.resolution = _bdf_atoul(*argv, 0, 10);
2400 options.font_opts.resolution_x =
2401 options.font_opts.resolution_y = options.resolution;
2402 } else if (strcmp(ap + 1, "hres") == 0) {
2405 options.font_opts.resolution_x = _bdf_atoul(*argv, 0, 10);
2406 } else if (strcmp(ap + 1, "vres") == 0) {
2409 options.font_opts.resolution_y = _bdf_atoul(*argv, 0, 10);
2410 } else if (strcmp(ap + 1, "bpp") == 0) {
2413 options.font_opts.bits_per_pixel = _bdf_atoul(*argv, 0, 10);
2414 } else if (strcmp(ap + 1, "g") == 0) {
2419 switch (*(ap + 1)) {
2420 case 'u': case 'x': base = 16; ap += 2; break;
2421 case 'o': base = 8; ap += 2; break;
2422 case 'd': base = 10; ap += 2; break;
2424 } else if ((*ap == 'U' && (*(ap + 1) == '+' ||
2425 *(ap + 1) == '-')) ||
2426 (*ap == '0' && (*(ap + 1) == 'x' ||
2427 *(ap + 1) == 'X'))) {
2430 } else if (*ap == '0')
2433 options.initial_glyph = _bdf_atol(ap, 0, base);
2434 } else if (strcmp(ap + 1, "sp") == 0) {
2437 switch (argv[0][0]) {
2439 options.font_opts.font_spacing = BDF_CHARCELL; break;
2441 options.font_opts.font_spacing = BDF_MONOWIDTH; break;
2443 options.font_opts.font_spacing = BDF_PROPORTIONAL; break;
2445 } else if (strcmp(ap + 1, "eol") == 0) {
2448 switch (argv[0][0]) {
2450 options.font_opts.eol = BDF_DOS_EOL; break;
2452 options.font_opts.eol = BDF_MAC_EOL; break;
2454 options.font_opts.eol = BDF_UNIX_EOL; break;
2456 } else if (strcmp(ap + 1, "cb") == 0) {
2459 switch (argv[0][0]) {
2461 options.code_base = 10; break;
2463 options.code_base = 16; break;
2465 options.code_base = 8; break;
2469 fprintf(stderr, "%s: unknown parameter '%s'.\n",
2470 g_get_prgname(), ap);
2474 need_editor = FALSE;
2475 (void) gbdfed_make_editor(argv[0], TRUE);
2482 if (need_editor == TRUE)
2484 * If an editor was not created, make one here.
2486 (void) gbdfed_make_editor(0, TRUE);
2490 main(int argc, char* argv[])
2495 * Make sure the BDF library is initialized.
2499 gtk_init(&argc, &argv);
2504 editor_setup(argc, argv);