X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/47854a55680b5809811caf72f66ecbe8289c2855..c4605e09f3345588614ea2f2d8ceb9a99022aff5:/src/xfns.c diff --git a/src/xfns.c b/src/xfns.c index 96631d98f5..25ace42197 100644 --- a/src/xfns.c +++ b/src/xfns.c @@ -1,13 +1,14 @@ /* Functions for the X window system. Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. + 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 + Free Software Foundation, Inc. This file is part of GNU Emacs. -GNU Emacs is free software; you can redistribute it and/or modify +GNU Emacs is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 3, or (at your option) -any later version. +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. GNU Emacs is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,9 +16,7 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ +along with GNU Emacs. If not, see . */ #include #include @@ -41,6 +40,7 @@ Boston, MA 02110-1301, USA. */ #include "keyboard.h" #include "blockinput.h" #include +#include "character.h" #include "charset.h" #include "coding.h" #include "fontset.h" @@ -48,6 +48,7 @@ Boston, MA 02110-1301, USA. */ #include "termhooks.h" #include "atimer.h" #include "termchar.h" +#include "font.h" #ifdef HAVE_X_WINDOWS @@ -55,15 +56,11 @@ Boston, MA 02110-1301, USA. */ #include #include -#ifndef VMS #if 1 /* Used to be #ifdef EMACS_BITMAP_FILES, but this should always work. */ #include "bitmaps/gray.xbm" #else #include #endif -#else -#include "[.bitmaps]gray.xbm" -#endif #ifdef USE_GTK #include "gtkutil.h" @@ -148,10 +145,6 @@ int gray_bitmap_width = gray_width; int gray_bitmap_height = gray_height; char *gray_bitmap_bits = gray_bits; -/* Non-zero means we're allowed to display an hourglass cursor. */ - -int display_hourglass_p; - /* Non-zero means prompt with the old GTK file selection dialog. */ int x_gtk_use_old_file_dialog; @@ -203,6 +196,7 @@ Lisp_Object Qnone; Lisp_Object Qsuppress_icon; Lisp_Object Qundefined_color; Lisp_Object Qcompound_text, Qcancel_timer; +static Lisp_Object Qfont_param; /* In dispnew.c */ @@ -310,10 +304,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) @@ -362,10 +356,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); @@ -417,10 +411,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) @@ -465,10 +459,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) @@ -512,10 +506,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) @@ -552,6 +546,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)); @@ -1551,55 +1547,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; } @@ -1945,7 +1916,7 @@ hack_wm_protocols (f, widget) #ifdef HAVE_X_I18N -static XFontSet xic_create_xfontset P_ ((struct frame *, char *)); +static XFontSet xic_create_xfontset P_ ((struct frame *)); static XIMStyle best_xim_style P_ ((XIMStyles *, XIMStyles *)); @@ -2097,75 +2068,124 @@ 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) +xic_create_xfontset (f) struct frame *f; - char *base_fontname; { XFontSet xfs = NULL; - char **missing_list = NULL; - int missing_count; - char *def_string; + struct font *font = FRAME_FONT (f); + int pixel_size = font->pixel_size; Lisp_Object rest, frame; - if (!base_fontname) - base_fontname = xic_defaut_fontset; - /* 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_XIC_BASE_FONTNAME (cf) - && !strcmp (FRAME_XIC_BASE_FONTNAME (cf), base_fontname)) + && FRAME_FONT (f) + && FRAME_FONT (f)->pixel_size == pixel_size) { xfs = FRAME_XIC_FONTSET (cf); break; } } - if (!xfs) + if (! xfs) { - char *fontsetname = xic_create_fontsetname (base_fontname, False); - - /* New fontset. */ - xfs = XCreateFontSet (FRAME_X_DISPLAY (f), - fontsetname, &missing_list, - &missing_count, &def_string); + 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) { - /* FONTSETNAME contains a list of font names (specific fonts - first, general fonts last), but giving that to - XCreateFontSet at once occasionally fails (bug of X?). - So, we try to call XCreateFontSet for each fontname. */ - char *p0 = fontsetname, *p1; - - while (p0) + /* 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) { - p1 = strchr (p0, ','); - if (p1) - *p1 = '\0'; - xfs = XCreateFontSet (FRAME_X_DISPLAY (f), - p0, &missing_list, - &missing_count, &def_string); + 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; - p0 = p1 ? p1 + 1 : NULL; } } - xfree (fontsetname); - } + if (! xfs) + { + char *last_resort = "-*-*-*-r-normal--*-*-*-*-*-*"; - if (FRAME_XIC_BASE_FONTNAME (f)) - xfree (FRAME_XIC_BASE_FONTNAME (f)); - FRAME_XIC_BASE_FONTNAME (f) = xstrdup (base_fontname); + 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); + } + + } - /* No need to free def_string. */ return xfs; } @@ -2241,10 +2261,7 @@ create_frame_xic (f) return; /* Create X fontset. */ - xfs = xic_create_xfontset - (f, (FRAME_FONTSET (f) < 0) ? NULL - : (char *) SDATA (fontset_ascii (FRAME_FONTSET (f)))); - + xfs = xic_create_xfontset (f); xim = FRAME_X_XIM (f); if (xim) { @@ -2399,7 +2416,7 @@ xic_set_xfontset (f, base_fontname) xic_free_xfontset (f); - xfs = xic_create_xfontset (f, base_fontname); + xfs = xic_create_xfontset (f); attr = XVaCreateNestedList (0, XNFontSet, xfs, NULL); if (FRAME_XIC_STYLE (f) & XIMPreeditPosition) @@ -2582,6 +2599,10 @@ x_window (f, window_prompting, minibuffer_only) XtManageChild (pane_widget); XtRealizeWidget (shell_widget); + if (FRAME_X_EMBEDDED_P (f)) + XReparentWindow (FRAME_X_DISPLAY (f), XtWindow (shell_widget), + f->output_data.x->parent_desc, 0, 0); + FRAME_X_WINDOW (f) = XtWindow (frame_widget); validate_x_resource_name (); @@ -2899,15 +2920,13 @@ x_make_gc (f) /* Create the GCs of this frame. Note that many default values are used. */ - /* Normal video */ - gc_values.font = FRAME_FONT (f)->fid; gc_values.foreground = FRAME_FOREGROUND_PIXEL (f); gc_values.background = FRAME_BACKGROUND_PIXEL (f); gc_values.line_width = 0; /* Means 1 using fast algorithm. */ f->output_data.x->normal_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - GCLineWidth | GCFont | GCForeground | GCBackground, + GCLineWidth | GCForeground | GCBackground, &gc_values); /* Reverse video style. */ @@ -2916,7 +2935,7 @@ x_make_gc (f) f->output_data.x->reverse_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - GCFont | GCForeground | GCBackground | GCLineWidth, + GCForeground | GCBackground | GCLineWidth, &gc_values); /* Cursor has cursor-color background, background-color foreground. */ @@ -2929,7 +2948,7 @@ x_make_gc (f) cursor_bits, 16, 16); f->output_data.x->cursor_gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), - (GCFont | GCForeground | GCBackground + (GCForeground | GCBackground | GCFillStyle /* | GCStipple */ | GCLineWidth), &gc_values); @@ -3027,11 +3046,83 @@ unwind_create_frame (frame) } +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_param = x_get_arg (dpyinfo, parms, Qfont, NULL, NULL, + RES_TYPE_STRING); + Lisp_Object font; + if (EQ (font_param, Qunbound)) + font_param = Qnil; + font = !NILP (font_param) ? font_param + : x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING); + + if (! STRINGP (font)) + { + char *names[] + = { +#ifdef HAVE_XFT + /* This will find the normal Xft font. */ + "monospace-12", +#endif + "-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"); + } + else if (!NILP (font_param)) + { + /* Remember the explicit font parameter, so we can re-apply it after + we've applied the `default' face settings. */ + x_set_frame_parameters (f, Fcons (Fcons (Qfont_param, font_param), Qnil)); + } + x_default_parameter (f, parms, Qfont, font, "font", "Font", RES_TYPE_STRING); +} + + +DEFUN ("x-wm-set-size-hint", Fx_wm_set_size_hint, Sx_wm_set_size_hint, + 0, 1, 0, + doc: /* Send the size hints for frame FRAME to the window manager. +If FRAME is nil, use the selected frame. */) + (frame) + Lisp_Object frame; +{ + struct frame *f; + if (NILP (frame)) + frame = selected_frame; + f = XFRAME (frame); + BLOCK_INPUT; + if (FRAME_X_P (f)) + x_wm_set_size_hint (f, 0, 0); + UNBLOCK_INPUT; + return Qnil; +} + DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 1, 1, 0, doc: /* Make a new X window, which is called a "frame" in Emacs terms. Return an Emacs frame object. -ALIST is an alist of frame parameters. +PARMS is an alist of frame parameters. If the parameters specify that the frame should not have a minibuffer, and do not specify a specific minibuffer window to use, then `default-minibuffer-frame' must be a frame whose minibuffer can @@ -3066,11 +3157,7 @@ This function is an internal primitive--use `make-frame' instead. */) if (EQ (display, Qunbound)) display = Qnil; dpyinfo = check_x_display_info (display); -#ifdef MULTI_KBOARD kb = dpyinfo->terminal->kboard; -#else - kb = &the_only_kboard; -#endif if (!dpyinfo->terminal->name) error ("Terminal is not live, can't create new frames on it"); @@ -3141,7 +3228,7 @@ This function is an internal primitive--use `make-frame' instead. */) /* With FRAME_X_DISPLAY_INFO set up, this unwind-protect is safe. */ record_unwind_protect (unwind_create_frame, frame); #if GLYPH_DEBUG - image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount; + image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount; dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ @@ -3206,53 +3293,35 @@ This function is an internal primitive--use `make-frame' instead. */) specbind (Qx_resource_name, name); } - /* Extract the window parameters from the supplied values - that are needed to determine window geometry. */ - { - Lisp_Object font; - - font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING); + f->resx = dpyinfo->resx; + f->resy = dpyinfo->resy; - 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)); - } + register_font_driver (&xfont_driver, f); +#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 */ - /* 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 (!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"); + x_default_parameter (f, parms, Qfont_backend, Qnil, + "fontBackend", "FontBackend", RES_TYPE_STRING); - x_set_frame_parameters (f, Fcons (Fcons (Qfont, font), Qnil)); - } + /* Extract the window parameters from the supplied values + that are needed to determine window geometry. */ + x_default_font_parameter (f, parms); #ifdef USE_LUCID /* Prevent lwlib/xlwmenu.c from crashing because of a bug whereby it fails to get any font. */ - xlwmenu_default_font = FRAME_FONT (f); + xlwmenu_default_font = XLoadQueryFont (FRAME_X_DISPLAY (f), "fixed"); #endif - x_default_parameter (f, parms, Qborder_width, make_number (2), - "borderWidth", "BorderWidth", RES_TYPE_NUMBER); + /* Frame contents get displaced if an embedded X window has a border. */ + if (! FRAME_X_EMBEDDED_P (f)) + x_default_parameter (f, parms, Qborder_width, make_number (2), + "borderWidth", "BorderWidth", RES_TYPE_NUMBER); /* This defaults to 1 in order to match xterm. We recognize either internalBorderWidth or internalBorder (which is what xterm calls @@ -3267,7 +3336,12 @@ This function is an internal primitive--use `make-frame' instead. */) parms = Fcons (Fcons (Qinternal_border_width, value), parms); } - x_default_parameter (f, parms, Qinternal_border_width, make_number (1), + x_default_parameter (f, parms, Qinternal_border_width, +#ifdef USE_GTK /* We used to impose 0 in xg_create_frame_widgets. */ + make_number (0), +#else + make_number (1), +#endif "internalBorderWidth", "internalBorderWidth", RES_TYPE_NUMBER); x_default_parameter (f, parms, Qvertical_scroll_bars, Qleft, @@ -3323,8 +3397,6 @@ This function is an internal primitive--use `make-frame' instead. */) x_default_parameter (f, parms, Qfullscreen, Qnil, "fullscreen", "Fullscreen", RES_TYPE_SYMBOL); - f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window; - /* Compute the size of the X window. */ window_prompting = x_figure_window_size (f, parms, 1); @@ -3361,6 +3433,8 @@ This function is an internal primitive--use `make-frame' instead. */) x_default_parameter (f, parms, Qscroll_bar_width, Qnil, "scrollBarWidth", "ScrollBarWidth", RES_TYPE_NUMBER); + x_default_parameter (f, parms, Qalpha, Qnil, + "alpha", "Alpha", RES_TYPE_NUMBER); /* Dimensions, especially FRAME_LINES (f), must be done via change_frame_size. Change will not be effected unless different from the current @@ -3600,7 +3674,7 @@ If omitted or nil, that stands for the selected frame's display. */) { struct x_display_info *dpyinfo = check_x_display_info (terminal); - return make_number (dpyinfo->width); + return make_number (x_display_pixel_width (dpyinfo)); } DEFUN ("x-display-pixel-height", Fx_display_pixel_height, @@ -3614,7 +3688,7 @@ If omitted or nil, that stands for the selected frame's display. */) { struct x_display_info *dpyinfo = check_x_display_info (terminal); - return make_number (dpyinfo->height); + return make_number (x_display_pixel_height (dpyinfo)); } DEFUN ("x-display-planes", Fx_display_planes, Sx_display_planes, @@ -3964,7 +4038,7 @@ select_visual (dpyinfo) /* Determine the visual class. */ for (i = 0; visual_classes[i].name; ++i) - if (xstricmp (s, visual_classes[i].name) == 0) + if (xstrcasecmp (s, visual_classes[i].name) == 0) { class = visual_classes[i].class; break; @@ -4404,85 +4478,6 @@ no value of TYPE. */) Busy cursor ***********************************************************************/ -/* If non-null, an asynchronous timer that, when it expires, displays - an hourglass cursor on all frames. */ - -static struct atimer *hourglass_atimer; - -/* Non-zero means an hourglass cursor is currently shown. */ - -static int hourglass_shown_p; - -/* Number of seconds to wait before displaying an hourglass cursor. */ - -static Lisp_Object Vhourglass_delay; - -/* Default number of seconds to wait before displaying an hourglass - cursor. */ - -#define DEFAULT_HOURGLASS_DELAY 1 - -/* Function prototypes. */ - -static void show_hourglass P_ ((struct atimer *)); -static void hide_hourglass P_ ((void)); - -/* Return non-zero if houglass timer has been started or hourglass is shown. */ - -int -hourglass_started () -{ - return hourglass_shown_p || hourglass_atimer != NULL; -} - - -/* Cancel a currently active hourglass timer, and start a new one. */ - -void -start_hourglass () -{ - EMACS_TIME delay; - int secs, usecs = 0; - - cancel_hourglass (); - - if (INTEGERP (Vhourglass_delay) - && XINT (Vhourglass_delay) > 0) - secs = XFASTINT (Vhourglass_delay); - else if (FLOATP (Vhourglass_delay) - && XFLOAT_DATA (Vhourglass_delay) > 0) - { - Lisp_Object tem; - tem = Ftruncate (Vhourglass_delay, Qnil); - secs = XFASTINT (tem); - usecs = (XFLOAT_DATA (Vhourglass_delay) - secs) * 1000000; - } - else - secs = DEFAULT_HOURGLASS_DELAY; - - EMACS_SET_SECS_USECS (delay, secs, usecs); - hourglass_atimer = start_atimer (ATIMER_RELATIVE, delay, - show_hourglass, NULL); -} - - -/* Cancel the hourglass cursor timer if active, hide a busy cursor if - shown. */ - -void -cancel_hourglass () -{ - if (hourglass_atimer) - { - cancel_atimer (hourglass_atimer); - hourglass_atimer = NULL; - } - - if (hourglass_shown_p) - hide_hourglass (); -} - - /* Timer function of hourglass_atimer. TIMER is equal to hourglass_atimer. @@ -4491,7 +4486,7 @@ cancel_hourglass () output_data.x structure to indicate that an hourglass cursor is shown on the frames. */ -static void +void show_hourglass (timer) struct atimer *timer; { @@ -4556,7 +4551,7 @@ show_hourglass (timer) /* Hide the hourglass pointer on all frames, if it is currently shown. */ -static void +void hide_hourglass () { if (hourglass_shown_p) @@ -4713,7 +4708,7 @@ x_create_tip_frame (dpyinfo, parms, text) f->icon_name = Qnil; FRAME_X_DISPLAY_INFO (f) = dpyinfo; #if GLYPH_DEBUG - image_cache_refcount = FRAME_X_IMAGE_CACHE (f)->refcount; + image_cache_refcount = FRAME_IMAGE_CACHE (f)->refcount; dpyinfo_refcount = dpyinfo->reference_count; #endif /* GLYPH_DEBUG */ f->output_data.x->parent_desc = FRAME_X_DISPLAY_INFO (f)->root_window; @@ -4767,45 +4762,24 @@ x_create_tip_frame (dpyinfo, parms, text) specbind (Qx_resource_name, name); } - /* Extract the window parameters from the supplied values that are - needed to determine window geometry. */ - { - Lisp_Object font; + f->resx = dpyinfo->resx; + f->resy = dpyinfo->resy; - font = x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING); + register_font_driver (&xfont_driver, f); +#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 */ - 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)); - } + x_default_parameter (f, parms, Qfont_backend, Qnil, + "fontBackend", "FontBackend", RES_TYPE_STRING); - /* 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 (!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"); - - x_default_parameter (f, parms, Qfont, font, - "font", "Font", RES_TYPE_STRING); - } + /* Extract the window parameters from the supplied values that are + needed to determine window geometry. */ + x_default_font_parameter (f, parms); x_default_parameter (f, parms, Qborder_width, make_number (2), "borderWidth", "BorderWidth", RES_TYPE_NUMBER); @@ -4876,7 +4850,7 @@ x_create_tip_frame (dpyinfo, parms, text) /* x, y, width, height */ 0, 0, 1, 1, /* Border. */ - 1, + f->border_width, CopyFromParent, InputOutput, CopyFromParent, mask, &attrs); UNBLOCK_INPUT; @@ -4938,7 +4912,7 @@ x_create_tip_frame (dpyinfo, parms, text) /* Set tip_frame here, so that */ tip_frame = frame; - call1 (Qface_set_after_frame_default, frame); + call2 (Qface_set_after_frame_default, frame, Qnil); if (!EQ (bg, Fframe_parameter (frame, Qbackground_color))) Fmodify_frame_parameters (frame, Fcons (Fcons (Qbackground_color, bg), @@ -5006,9 +4980,10 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y) *root_y = XINT (top); else if (*root_y + XINT (dy) <= 0) *root_y = 0; /* Can happen for negative dy */ - else if (*root_y + XINT (dy) + height <= FRAME_X_DISPLAY_INFO (f)->height) + else if (*root_y + XINT (dy) + height + <= x_display_pixel_height (FRAME_X_DISPLAY_INFO (f))) /* It fits below the pointer */ - *root_y += XINT (dy); + *root_y += XINT (dy); else if (height + XINT (dy) <= *root_y) /* It fits above the pointer. */ *root_y -= height + XINT (dy); @@ -5020,7 +4995,8 @@ compute_tip_xy (f, parms, dx, dy, width, height, root_x, root_y) *root_x = XINT (left); else if (*root_x + XINT (dx) <= 0) *root_x = 0; /* Can happen for negative dx */ - else if (*root_x + XINT (dx) + width <= FRAME_X_DISPLAY_INFO (f)->width) + else if (*root_x + XINT (dx) + width + <= x_display_pixel_width (FRAME_X_DISPLAY_INFO (f))) /* It fits to the right of the pointer. */ *root_x += XINT (dx); else if (width + XINT (dx) <= *root_x) @@ -5074,6 +5050,9 @@ Text larger than the specified size is clipped. */) GCPRO4 (string, parms, frame, timeout); CHECK_STRING (string); + if (SCHARS (string) == 0) + string = make_unibyte_string (" ", 1); + f = check_x_frame (frame); if (NILP (timeout)) timeout = make_number (5); @@ -5269,7 +5248,7 @@ Value is t if tooltip was open, nil otherwise. */) if (FRAMEP (frame)) { - Fdelete_frame (frame, Qnil); + delete_frame (frame, Qnil); deleted = Qt; #ifdef USE_LUCID @@ -5600,6 +5579,59 @@ directories. */) return unbind_to (count, decoded_file); } + +#ifdef HAVE_FREETYPE + +DEFUN ("x-select-font", Fx_select_font, Sx_select_font, 0, 2, 0, + doc: /* Read a font name using a GTK font selection dialog. +Return a GTK-style font string corresponding to the selection. + +If FRAME is omitted or nil, it defaults to the selected frame. */) + (frame, ignored) + Lisp_Object frame, ignored; +{ + FRAME_PTR f = check_x_frame (frame); + char *name; + Lisp_Object default_font, font = Qnil; + int count = SPECPDL_INDEX (); + + check_x (); + + if (popup_activated ()) + error ("Trying to use a menu from within a menu-entry"); + + /* Prevent redisplay. */ + specbind (Qinhibit_redisplay, Qt); + record_unwind_protect (clean_up_dialog, Qnil); + + BLOCK_INPUT; + + XSETFONT (default_font, FRAME_FONT (f)); + if (FONTP (default_font)) + { + char *default_name = alloca (256); + if (font_unparse_gtkname (default_font, f, default_name, 256) < 0) + default_name = NULL; + name = xg_get_font_name (f, default_name); + } + else + name = xg_get_font_name (f, NULL); + + if (name) + { + font = build_string (name); + xfree (name); + } + + UNBLOCK_INPUT; + + if (NILP (font)) + Fsignal (Qquit, Qnil); + + return unbind_to (count, font); +} +#endif /* HAVE_FREETYPE */ + #endif /* USE_GTK */ @@ -5745,6 +5777,8 @@ frame_parm_handler x_frame_parm_handlers[] = x_set_fringe_width, x_set_wait_for_wm, x_set_fullscreen, + x_set_font_backend, + x_set_alpha }; void @@ -5766,6 +5800,8 @@ syms_of_xfns () staticpro (&Qcompound_text); Qcancel_timer = intern ("cancel-timer"); staticpro (&Qcancel_timer); + Qfont_param = intern ("font-parameter"); + staticpro (&Qfont_param); /* This is the end of symbol initialization. */ /* Text property `display' should be nonsticky by default. */ @@ -5798,15 +5834,6 @@ This variable takes effect when you create a new frame or when you set the mouse color. */); Vx_hourglass_pointer_shape = Qnil; - DEFVAR_BOOL ("display-hourglass", &display_hourglass_p, - doc: /* Non-zero means Emacs displays an hourglass pointer on window systems. */); - display_hourglass_p = 1; - - DEFVAR_LISP ("hourglass-delay", &Vhourglass_delay, - doc: /* *Seconds to wait before displaying an hourglass pointer. -Value must be an integer or float. */); - Vhourglass_delay = make_number (DEFAULT_HOURGLASS_DELAY); - #if 0 /* This doesn't really do anything. */ DEFVAR_LISP ("x-mode-pointer-shape", &Vx_mode_pointer_shape, doc: /* The shape of the pointer when over the mode line. @@ -5935,6 +5962,7 @@ the tool bar buttons. */); defsubr (&Sx_display_visual_class); defsubr (&Sx_display_backing_store); defsubr (&Sx_display_save_under); + defsubr (&Sx_wm_set_size_hint); defsubr (&Sx_create_frame); defsubr (&Sx_open_connection); defsubr (&Sx_close_connection); @@ -5944,22 +5972,8 @@ the tool bar buttons. */); defsubr (&Sx_backspace_delete_keys_p); /* Setting callback functions for fontset handler. */ - get_font_info_func = x_get_font_info; - -#if 0 /* This function pointer doesn't seem to be used anywhere. - And the pointer assigned has the wrong type, anyway. */ - list_fonts_func = x_list_fonts; -#endif - - load_font_func = x_load_font; - find_ccl_program_func = x_find_ccl_program; - query_font_func = x_query_font; - set_frame_fontset_func = x_set_font; check_window_system_func = check_x; - hourglass_atimer = NULL; - hourglass_shown_p = 0; - defsubr (&Sx_show_tip); defsubr (&Sx_hide_tip); tip_timer = Qnil; @@ -5974,6 +5988,10 @@ the tool bar buttons. */); #if defined (USE_MOTIF) || defined (USE_GTK) defsubr (&Sx_file_dialog); #endif + +#if defined (USE_GTK) && defined (HAVE_FREETYPE) + defsubr (&Sx_select_font); +#endif } #endif /* HAVE_X_WINDOWS */