diff options
Diffstat (limited to 'src/xfns.c')
-rw-r--r-- | src/xfns.c | 393 |
1 files changed, 315 insertions, 78 deletions
diff --git a/src/xfns.c b/src/xfns.c index 0c06abb44d4..52cbd758d88 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -41,6 +41,7 @@ Boston, MA 02110-1301, USA. */ #include "keyboard.h" #include "blockinput.h" #include <epaths.h> +#include "character.h" #include "charset.h" #include "coding.h" #include "fontset.h" @@ -48,6 +49,10 @@ Boston, MA 02110-1301, USA. */ #include "termhooks.h" #include "atimer.h" +#ifdef USE_FONT_BACKEND +#include "font.h" +#endif /* USE_FONT_BACKEND */ + #ifdef HAVE_X_WINDOWS #include <ctype.h> @@ -303,10 +308,10 @@ x_window_to_frame (dpyinfo, wdesc) if (wdesc == None) return 0; - for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail)) + for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) { frame = XCAR (tail); - if (!GC_FRAMEP (frame)) + if (!FRAMEP (frame)) continue; f = XFRAME (frame); if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo) @@ -355,10 +360,10 @@ x_any_window_to_frame (dpyinfo, wdesc) if (wdesc == None) return NULL; found = NULL; - for (tail = Vframe_list; GC_CONSP (tail) && !found; tail = XCDR (tail)) + for (tail = Vframe_list; CONSP (tail) && !found; tail = XCDR (tail)) { frame = XCAR (tail); - if (!GC_FRAMEP (frame)) + if (!FRAMEP (frame)) continue; f = XFRAME (frame); @@ -410,10 +415,10 @@ x_non_menubar_window_to_frame (dpyinfo, wdesc) if (wdesc == None) return 0; - for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail)) + for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) { frame = XCAR (tail); - if (!GC_FRAMEP (frame)) + if (!FRAMEP (frame)) continue; f = XFRAME (frame); if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo) @@ -458,10 +463,10 @@ x_menubar_window_to_frame (dpyinfo, wdesc) if (wdesc == None) return 0; - for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail)) + for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) { frame = XCAR (tail); - if (!GC_FRAMEP (frame)) + if (!FRAMEP (frame)) continue; f = XFRAME (frame); if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo) @@ -505,10 +510,10 @@ x_top_window_to_frame (dpyinfo, wdesc) if (wdesc == None) return 0; - for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail)) + for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail)) { frame = XCAR (tail); - if (!GC_FRAMEP (frame)) + if (!FRAMEP (frame)) continue; f = XFRAME (frame); if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo) @@ -545,6 +550,8 @@ x_top_window_to_frame (dpyinfo, wdesc) +static void x_default_font_parameter P_ ((struct frame *, Lisp_Object)); + static Lisp_Object unwind_create_frame P_ ((Lisp_Object)); static Lisp_Object unwind_create_tip_frame P_ ((Lisp_Object)); @@ -1546,55 +1553,30 @@ x_encode_text (string, coding_system, selectionp, text_bytes, stringp, freep) int selectionp; int *freep; { - unsigned char *str = SDATA (string); - int chars = SCHARS (string); - int bytes = SBYTES (string); - int charset_info; - int bufsize; - unsigned char *buf; + int result = string_xstring_p (string); struct coding_system coding; - extern Lisp_Object Qcompound_text_with_extensions; - charset_info = find_charset_in_text (str, chars, bytes, NULL, Qnil); - if (charset_info == 0) + if (result == 0) { /* No multibyte character in OBJ. We need not encode it. */ - *text_bytes = bytes; + *text_bytes = SBYTES (string); *stringp = 1; *freep = 0; - return str; + return SDATA (string); } setup_coding_system (coding_system, &coding); - if (selectionp - && SYMBOLP (coding.pre_write_conversion) - && !NILP (Ffboundp (coding.pre_write_conversion))) - { - struct gcpro gcpro1; - /* We don't need to GCPRO string. */ - GCPRO1 (coding_system); - string = run_pre_post_conversion_on_str (string, &coding, 1); - UNGCPRO; - str = SDATA (string); - chars = SCHARS (string); - bytes = SBYTES (string); - } - coding.src_multibyte = 1; - coding.dst_multibyte = 0; - coding.mode |= CODING_MODE_LAST_BLOCK; - if (coding.type == coding_type_iso2022) - coding.flags |= CODING_FLAG_ISO_SAFE; + coding.mode |= (CODING_MODE_SAFE_ENCODING | CODING_MODE_LAST_BLOCK); /* We suppress producing escape sequences for composition. */ - coding.composing = COMPOSITION_DISABLED; - bufsize = encoding_buffer_size (&coding, bytes); - buf = (unsigned char *) xmalloc (bufsize); - encode_coding (&coding, str, buf, bytes, bufsize); + coding.common_flags &= ~CODING_ANNOTATION_MASK; + coding.dst_bytes = SCHARS (string) * 2; + coding.destination = (unsigned char *) xmalloc (coding.dst_bytes); + encode_coding_object (&coding, string, 0, 0, + SCHARS (string), SBYTES (string), Qnil); *text_bytes = coding.produced; - *stringp = (charset_info == 1 - || (!EQ (coding_system, Qcompound_text) - && !EQ (coding_system, Qcompound_text_with_extensions))); + *stringp = (result == 1 || !EQ (coding_system, Qcompound_text)); *freep = 1; - return buf; + return coding.destination; } @@ -1973,6 +1955,7 @@ hack_wm_protocols (f, widget) #ifdef HAVE_X_I18N static XFontSet xic_create_xfontset P_ ((struct frame *, char *)); +static XFontSet xic_create_xfontset2 P_ ((struct frame *)); static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *)); @@ -2124,6 +2107,29 @@ xic_create_fontsetname (base_fontname, motif) return fontsetname; } +#ifdef DEBUG_XIC_FONTSET +static void +print_fontset_result (xfs, name, missing_list, missing_count) + XFontSet xfs; + char *name; + char **missing_list; + int missing_count; +{ + if (xfs) + fprintf (stderr, "XIC Fontset created: %s\n", name); + else + { + fprintf (stderr, "XIC Fontset failed: %s\n", name); + while (missing_count-- > 0) + { + fprintf (stderr, " missing: %s\n", *missing_list); + missing_list++; + } + } + +} +#endif + static XFontSet xic_create_xfontset (f, base_fontname) struct frame *f; @@ -2160,6 +2166,9 @@ xic_create_xfontset (f, base_fontname) xfs = XCreateFontSet (FRAME_X_DISPLAY (f), fontsetname, &missing_list, &missing_count, &def_string); +#ifdef DEBUG_XIC_FONTSET + print_fontset_result (xfs, fontsetname, missing_list, missing_count); +#endif if (missing_list) XFreeStringList (missing_list); if (! xfs) @@ -2178,6 +2187,9 @@ xic_create_xfontset (f, base_fontname) xfs = XCreateFontSet (FRAME_X_DISPLAY (f), p0, &missing_list, &missing_count, &def_string); +#ifdef DEBUG_XIC_FONTSET + print_fontset_result (xfs, p0, missing_list, missing_count); +#endif if (missing_list) XFreeStringList (missing_list); if (xfs) @@ -2186,6 +2198,20 @@ xic_create_xfontset (f, base_fontname) } } xfree (fontsetname); + if (! xfs && base_fontname != xic_defaut_fontset) + { + /* Try the default fontset name at a last resort. */ + fontsetname = xic_create_fontsetname (xic_defaut_fontset, False); + xfs = XCreateFontSet (FRAME_X_DISPLAY (f), + fontsetname, &missing_list, + &missing_count, &def_string); +#ifdef DEBUG_XIC_FONTSET + print_fontset_result (xfs, fontsetname, missing_list, missing_count); +#endif + if (missing_list) + XFreeStringList (missing_list); + xfree (fontsetname); + } } if (FRAME_XIC_BASE_FONTNAME (f)) @@ -2196,6 +2222,107 @@ xic_create_xfontset (f, base_fontname) return xfs; } +#ifdef USE_FONT_BACKEND + +static XFontSet +xic_create_xfontset2 (f) + struct frame *f; +{ + XFontSet xfs = NULL; + struct font *font = FRAME_FONT_OBJECT (f); + int pixel_size = font->pixel_size; + Lisp_Object rest, frame; + + /* See if there is another frame already using same fontset. */ + FOR_EACH_FRAME (rest, frame) + { + struct frame *cf = XFRAME (frame); + + if (cf != f && FRAME_LIVE_P (f) && FRAME_X_P (cf) + && FRAME_X_DISPLAY_INFO (cf) == FRAME_X_DISPLAY_INFO (f) + && FRAME_FONT_OBJECT (f) + && FRAME_FONT_OBJECT (f)->pixel_size == pixel_size) + { + xfs = FRAME_XIC_FONTSET (cf); + break; + } + } + + if (! xfs) + { + char buf[256]; + char **missing_list; + int missing_count; + char *def_string; + char *xlfd_format = "-*-*-medium-r-normal--%d-*-*-*-*-*"; + + sprintf (buf, xlfd_format, pixel_size); + missing_list = NULL; + xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf, + &missing_list, &missing_count, &def_string); +#ifdef DEBUG_XIC_FONTSET + print_fontset_result (xfs, buf, missing_list, missing_count); +#endif + if (missing_list) + XFreeStringList (missing_list); + if (! xfs) + { + /* List of pixel sizes most likely available. Find one that + is closest to pixel_size. */ + int sizes[] = {0, 8, 10, 11, 12, 14, 17, 18, 20, 24, 26, 34, 0}; + int *smaller, *larger; + + for (smaller = sizes; smaller[1]; smaller++) + if (smaller[1] >= pixel_size) + break; + larger = smaller + 1; + if (*larger == pixel_size) + larger++; + while (*smaller || *larger) + { + int this_size; + + if (! *larger) + this_size = *smaller--; + else if (! *smaller) + this_size = *larger++; + else if (pixel_size - *smaller < *larger - pixel_size) + this_size = *smaller--; + else + this_size = *larger++; + sprintf (buf, xlfd_format, this_size); + missing_list = NULL; + xfs = XCreateFontSet (FRAME_X_DISPLAY (f), buf, + &missing_list, &missing_count, &def_string); +#ifdef DEBUG_XIC_FONTSET + print_fontset_result (xfs, buf, missing_list, missing_count); +#endif + if (missing_list) + XFreeStringList (missing_list); + if (xfs) + break; + } + } + if (! xfs) + { + char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*"; + + missing_list = NULL; + xfs = XCreateFontSet (FRAME_X_DISPLAY (f), last_resort, + &missing_list, &missing_count, &def_string); +#ifdef DEBUG_XIC_FONTSET + print_fontset_result (xfs, last_resort, missing_list, missing_count); +#endif + if (missing_list) + XFreeStringList (missing_list); + } + + } + + return xfs; +} +#endif /* USE_FONT_BACKEND */ + /* Free the X fontset of frame F if it is the last frame using it. */ void @@ -2268,6 +2395,11 @@ create_frame_xic (f) return; /* Create X fontset. */ +#ifdef USE_FONT_BACKEND + if (enable_font_backend) + xfs = xic_create_xfontset2 (f); + else +#endif xfs = xic_create_xfontset (f, (FRAME_FONTSET (f) < 0) ? NULL : (char *) SDATA (fontset_ascii (FRAME_FONTSET (f)))); @@ -2426,6 +2558,11 @@ xic_set_xfontset (f, base_fontname) xic_free_xfontset (f); +#ifdef USE_FONT_BACKEND + if (enable_font_backend) + xfs = xic_create_xfontset2 (f); + else +#endif xfs = xic_create_xfontset (f, base_fontname); attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL); @@ -3045,6 +3182,44 @@ unwind_create_frame (frame) return Qnil; } +#ifdef USE_FONT_BACKEND +static void +x_default_font_parameter (f, parms) + struct frame *f; + Lisp_Object parms; +{ + struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); + Lisp_Object font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", + RES_TYPE_STRING); + + if (! STRINGP (font)) + { + char *names[] + = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1", + "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1", + "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1", + /* This was formerly the first thing tried, but it finds + too many fonts and takes too long. */ + "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1", + /* If those didn't work, look for something which will + at least work. */ + "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1", + "fixed", + NULL }; + int i; + + for (i = 0; names[i]; i++) + { + font = font_open_by_name (f, names[i]); + if (! NILP (font)) + break; + } + if (NILP (font)) + error ("No suitable font was found"); + } + x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING); +} +#endif /* USE_FONT_BACKEND */ DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 1, 1, 0, @@ -3222,43 +3397,75 @@ This function is an internal primitive--use `make-frame' instead. */) specbind (Qx_resource_name, name); } + f->resx = dpyinfo->resx; + f->resy = dpyinfo->resy; + +#ifdef USE_FONT_BACKEND + if (enable_font_backend) + { + /* Perhaps, we must allow frame parameter, say `font-backend', + to specify which font backends to use. */ +#ifdef HAVE_FREETYPE +#ifdef HAVE_XFT + register_font_driver (&xftfont_driver, f); +#else /* not HAVE_XFT */ + register_font_driver (&ftxfont_driver, f); +#endif /* not HAVE_XFT */ +#endif /* HAVE_FREETYPE */ + register_font_driver (&xfont_driver, f); + + x_default_parameter (f, parms, Qfont_backend, Qnil, + "fontBackend", "FontBackend", RES_TYPE_STRING); + } +#endif /* USE_FONT_BACKEND */ + /* Extract the window parameters from the supplied values that are needed to determine window geometry. */ +#ifdef USE_FONT_BACKEND + if (enable_font_backend) + x_default_font_parameter (f, parms); +else +#endif /* USE_FONT_BACKEND */ { Lisp_Object font; font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING); - BLOCK_INPUT; - /* First, try whatever font the caller has specified. */ - if (STRINGP (font)) - { - tem = Fquery_fontset (font, Qnil); - if (STRINGP (tem)) - font = x_new_fontset (f, SDATA (tem)); - else - font = x_new_font (f, SDATA (font)); - } - - /* Try out a font which we hope has bold and italic variations. */ - if (!STRINGP (font)) - font = x_new_font (f, "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1"); + /* If the caller has specified no font, try out fonts which we + hope have bold and italic variations. */ if (!STRINGP (font)) - font = x_new_font (f, "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1"); - if (! STRINGP (font)) - font = x_new_font (f, "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1"); - if (! STRINGP (font)) - /* This was formerly the first thing tried, but it finds too many fonts - and takes too long. */ - font = x_new_font (f, "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1"); - /* If those didn't work, look for something which will at least work. */ - if (! STRINGP (font)) - font = x_new_font (f, "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1"); - UNBLOCK_INPUT; - if (! STRINGP (font)) - font = build_string ("fixed"); + { + char *names[] + = { "-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1", + "-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1", + "-*-*-medium-r-normal-*-*-140-*-*-c-*-iso8859-1", + /* This was formerly the first thing tried, but it finds + too many fonts and takes too long. */ + "-*-*-medium-r-*-*-*-*-*-*-c-*-iso8859-1", + /* If those didn't work, look for something which will + at least work. */ + "-*-fixed-*-*-*-*-*-140-*-*-c-*-iso8859-1", + NULL }; + int i; + + BLOCK_INPUT; + for (i = 0; names[i]; i++) + { + Lisp_Object list; - x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil)); + list = x_list_fonts (f, build_string (names[i]), 0, 1); + if (CONSP (list)) + { + font = XCAR (list); + break; + } + } + UNBLOCK_INPUT; + if (! STRINGP (font)) + font = build_string ("fixed"); + } + x_default_parameter (f, parms, Qfont, font, + "font", "Font", RES_TYPE_STRING); } #ifdef USE_LUCID @@ -4803,8 +5010,35 @@ x_create_tip_frame (dpyinfo, parms, text) specbind (Qx_resource_name, name); } + f->resx = dpyinfo->resx; + f->resy = dpyinfo->resy; + +#ifdef USE_FONT_BACKEND + if (enable_font_backend) + { + /* Perhaps, we must allow frame parameter, say `font-backend', + to specify which font backends to use. */ +#ifdef HAVE_FREETYPE +#ifdef HAVE_XFT + register_font_driver (&xftfont_driver, f); +#else /* not HAVE_XFT */ + register_font_driver (&ftxfont_driver, f); +#endif /* not HAVE_XFT */ +#endif /* HAVE_FREETYPE */ + register_font_driver (&xfont_driver, f); + + x_default_parameter (f, parms, Qfont_backend, Qnil, + "fontBackend", "FontBackend", RES_TYPE_STRING); + } +#endif /* USE_FONT_BACKEND */ + /* Extract the window parameters from the supplied values that are needed to determine window geometry. */ +#ifdef USE_FONT_BACKEND + if (enable_font_backend) + x_default_font_parameter (f, parms); +else +#endif /* USE_FONT_BACKEND */ { Lisp_Object font; @@ -4816,7 +5050,7 @@ x_create_tip_frame (dpyinfo, parms, text) { tem = Fquery_fontset (font, Qnil); if (STRINGP (tem)) - font = x_new_fontset (f, SDATA (tem)); + font = x_new_fontset (f, tem); else font = x_new_font (f, SDATA (font)); } @@ -4839,8 +5073,7 @@ x_create_tip_frame (dpyinfo, parms, text) if (! STRINGP (font)) font = build_string ("fixed"); - x_default_parameter (f, parms, Qfont, font, - "font", "Font", RES_TYPE_STRING); + x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil)); } x_default_parameter (f, parms, Qborder_width, make_number (2), @@ -5761,6 +5994,9 @@ frame_parm_handler x_frame_parm_handlers[] = x_set_fringe_width, x_set_wait_for_wm, x_set_fullscreen, +#ifdef USE_FONT_BACKEND + x_set_font_backend +#endif /* USE_FONT_BACKEND */ }; void @@ -5971,6 +6207,7 @@ the tool bar buttons. */); find_ccl_program_func = x_find_ccl_program; query_font_func = x_query_font; set_frame_fontset_func = x_set_font; + get_font_repertory_func = x_get_font_repertory; check_window_system_func = check_x; hourglass_atimer = NULL; |