/* X Communication module for terminals which understand the X protocol.
- Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000
+ Copyright (C) 1989, 93, 94, 95, 96, 1997, 1998, 1999, 2000, 2001
Free Software Foundation, Inc.
This file is part of GNU Emacs.
extern Lisp_Object Qhelp_echo;
\f
-/* Non-zero means Emacs uses toolkit scroll bars. */
+/* Non-nil means Emacs uses toolkit scroll bars. */
-int x_toolkit_scroll_bars_p;
+Lisp_Object Vx_toolkit_scroll_bars;
/* If a string, XTread_socket generates an event to display that string.
(The display is done in read_char.) */
DRAW_IMAGE_SUNKEN
};
+static void x_set_window_size_1 P_ ((struct frame *, int, int, int));
static const XColor *x_color_cells P_ ((struct frame *, int *));
static void x_update_window_end P_ ((struct window *, int, int));
static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
static void x_produce_image_glyph P_ ((struct it *it));
-/* Return a pointer to per-char metric information in FONT of a
- character pointed by B which is a pointer to an XChar2b. */
-
-#define PER_CHAR_METRIC(font, b) \
- ((font)->per_char \
- ? ((font)->per_char + (b)->byte2 - (font)->min_char_or_byte2 \
- + (((font)->min_byte1 || (font)->max_byte1) \
- ? (((b)->byte1 - (font)->min_byte1) \
- * ((font)->max_char_or_byte2 - (font)->min_char_or_byte2 + 1)) \
- : 0)) \
- : &((font)->max_bounds))
-
-
/* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
is not contained in the font. */
prepare_image_for_display (it->f, img);
it->ascent = it->phys_ascent = image_ascent (img, face);
- it->descent = it->phys_descent = img->height + 2 * img->margin - it->ascent;
- it->pixel_width = img->width + 2 * img->margin;
+ it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
+ it->pixel_width = img->width + 2 * img->hmargin;
it->nglyphs = 1;
cmp->font = (void *) font;
/* Initialize the bounding box. */
- pcm = x_per_char_metric (font, &char2b);
- if (pcm)
+ if (font_info
+ && (pcm = x_per_char_metric (font, &char2b)))
{
width = pcm->width;
ascent = pcm->ascent;
boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
}
- pcm = x_per_char_metric (font, &char2b);
- if (pcm)
+ if (font_info
+ && (pcm = x_per_char_metric (font, &char2b)))
{
width = pcm->width;
ascent = pcm->ascent;
else
{
width = FONT_WIDTH (font);
- ascent = font->ascent;
- descent = font->descent;
+ ascent = 1;
+ descent = 0;
}
if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
struct frame *f;
enum face_id face_id;
{
- int height = 1;
+ int height = FONT_HEIGHT (FRAME_FONT (f));
/* This function is called so early when Emacs starts that the face
cache and mode line face are not yet initialized. */
{
struct face *face = FACE_FROM_ID (f, face_id);
if (face)
- height = FONT_HEIGHT (face->font) + 2 * face->box_line_width;
+ {
+ if (face->font)
+ height = FONT_HEIGHT (face->font);
+ height += 2 * face->box_line_width;
+ }
}
return height;
int face_id;
struct face *face;
- /* What face has to be used for the mouse face? */
+ /* What face has to be used last for the mouse face? */
face_id = FRAME_X_DISPLAY_INFO (s->f)->mouse_face_face_id;
face = FACE_FROM_ID (s->f, face_id);
+ if (face == NULL)
+ face = FACE_FROM_ID (s->f, MOUSE_FACE_ID);
+
if (s->first_glyph->type == CHAR_GLYPH)
face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch);
else
/* If there is a margin around the image, adjust x- and y-position
by that margin. */
- if (s->img->margin)
- {
- x += s->img->margin;
- y += s->img->margin;
- }
+ x += s->img->hmargin;
+ y += s->img->vmargin;
if (s->img->pixmap)
{
/* If there is a margin around the image, adjust x- and y-position
by that margin. */
- if (s->img->margin)
- {
- x += s->img->margin;
- y += s->img->margin;
- }
+ x += s->img->hmargin;
+ y += s->img->vmargin;
if (s->hl == DRAW_IMAGE_SUNKEN
|| s->hl == DRAW_IMAGE_RAISED)
/* If there is a margin around the image, adjust x- and y-position
by that margin. */
- if (s->img->margin)
- {
- x += s->img->margin;
- y += s->img->margin;
- }
+ x += s->img->hmargin;
+ y += s->img->vmargin;
if (s->img->pixmap)
{
{
int x, y;
int box_line_width = s->face->box_line_width;
- int margin = s->img->margin;
int height;
Pixmap pixmap = None;
flickering. */
s->stippled_p = s->face->stipple != 0;
if (height > s->img->height
- || margin
+ || s->img->hmargin
+ || s->img->vmargin
|| s->img->mask
|| s->img->pixmap == 0
|| s->width != s->background_width)
XRectangle *r;
enum glyph_row_area area;
{
- int x;
struct glyph *first = row->glyphs[area];
struct glyph *end = row->glyphs[area] + row->used[area];
struct glyph *last;
- int first_x;
-
- /* Set x to the window-relative start position for drawing glyphs of
- AREA. The first glyph of the text area can be partially visible.
- The first glyphs of other areas cannot. */
- if (area == LEFT_MARGIN_AREA)
- x = 0;
- else if (area == TEXT_AREA)
- x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
- else
- x = (window_box_width (w, LEFT_MARGIN_AREA)
- + window_box_width (w, TEXT_AREA));
+ int first_x, start_x, x;
if (area == TEXT_AREA && row->fill_line_p)
/* If row extends face to end of line write the whole line. */
- x_draw_glyphs (w, x, row, area,
+ x_draw_glyphs (w, 0, row, area,
0, row->used[area],
row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
NULL, NULL, 0);
else
{
+ /* Set START_X to the window-relative start position for drawing glyphs of
+ AREA. The first glyph of the text area can be partially visible.
+ The first glyphs of other areas cannot. */
+ if (area == LEFT_MARGIN_AREA)
+ start_x = 0;
+ else if (area == TEXT_AREA)
+ start_x = row->x + window_box_width (w, LEFT_MARGIN_AREA);
+ else
+ start_x = (window_box_width (w, LEFT_MARGIN_AREA)
+ + window_box_width (w, TEXT_AREA));
+ x = start_x;
+
/* Find the first glyph that must be redrawn. */
while (first < end
&& x + first->pixel_width < r->x)
/* Repaint. */
if (last > first)
- x_draw_glyphs (w, first_x, row, area,
+ x_draw_glyphs (w, first_x - start_x, row, area,
first - row->glyphs[area],
last - row->glyphs[area],
row->inverse_p ? DRAW_INVERSE_VIDEO : DRAW_NORMAL_TEXT,
happen when toolkit scroll bars are used and a window is split.
Reconfiguring the scroll bar will generate an expose for a newly
created window. */
- if (w->current_matrix == NULL)
+ if (w->current_matrix == NULL || w == updated_window)
return;
TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
clear_mouse_face (dpyinfo)
struct x_display_info *dpyinfo;
{
- if (tip_frame)
+#if 0 /* This prevents redrawing tool bar items when changing from one
+ to another while a tooltip is open, so don't do it. */
+ if (!NILP (tip_frame))
return;
+#endif
if (! NILP (dpyinfo->mouse_face_window))
show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
Toolkit scroll bars
************************************************************************/
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
static void x_scroll_bar_to_input_event P_ ((XEvent *, struct input_event *));
static void x_send_scroll_bar_event P_ ((Lisp_Object, int, int, int));
BLOCK_INPUT;
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
x_create_toolkit_scroll_bar (f, bar);
#else /* not USE_TOOLKIT_SCROLL_BARS */
{
XSETVECTOR (XSCROLL_BAR (bar->next)->prev, bar);
/* Map the window/widget. */
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
{
Widget scroll_bar = SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar);
XtConfigureWidget (scroll_bar,
struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (bar->window)));
BLOCK_INPUT;
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
XtDestroyWidget (SCROLL_BAR_X_WIDGET (FRAME_X_DISPLAY (f), bar));
#else
XDestroyWindow (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (bar));
UNBLOCK_INPUT;
}
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
#else /* not USE_TOOLKIT_SCROLL_BARS */
/* Set the scroll bar's current state, unless we're currently being
case KeyPress:
f = x_any_window_to_frame (dpyinfo, event.xkey.window);
-#ifdef USE_MOTIF
+#if defined USE_MOTIF && defined USE_TOOLKIT_SCROLL_BARS
/* I couldn't find a way to prevent LessTif scroll bars
from consuming key events. */
if (f == 0)
f = x_any_window_to_frame (dpyinfo, XtWindow (widget));
}
}
-#endif /* USE_MOTIF */
+#endif /* USE_MOTIF and USE_TOOLKIT_SCROLL_BARS */
if (f != 0)
{
{
register int i;
register int c;
- unsigned char *p, *pend;
int nchars, len;
for (i = 0; i < nbytes; i++)
f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
if (f)
{
- Lisp_Object frame;
int from_menu_bar_p = 0;
if (f == dpyinfo->mouse_face_mouse_frame)
int n;
XSETFRAME (frame, f);
+ help_echo = Qnil;
n = gen_help_event (bufp, numchars,
Qnil, frame, Qnil, Qnil, 0);
bufp += n, count += n, numchars -= n;
signal (signalnum, x_connection_signal);
#endif /* USG */
}
+
\f
-/* Handling X errors. */
+/************************************************************************
+ Handling X errors
+ ************************************************************************/
-/* Handle the loss of connection to display DISPLAY. */
+/* Handle the loss of connection to display DPY. ERROR_MESSAGE is
+ the text of an error message that lead to the connection loss. */
static SIGTYPE
-x_connection_closed (display, error_message)
- Display *display;
+x_connection_closed (dpy, error_message)
+ Display *dpy;
char *error_message;
{
- struct x_display_info *dpyinfo = x_display_info_for_display (display);
+ struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
Lisp_Object frame, tail;
+ int count;
+ char *msg;
+
+ msg = (char *) alloca (strlen (error_message) + 1);
+ strcpy (msg, error_message);
+ handling_signal = 0;
+
+ /* Prevent being called recursively because of an error condition
+ below. Otherwise, we might end up with printing ``can't find per
+ display information'' in the recursive call instead of printing
+ the original message here. */
+ count = x_catch_errors (dpy);
+
+ /* We have to close the display to inform Xt that it doesn't
+ exist anymore. If we don't, Xt will continue to wait for
+ events from the display. As a consequence, a sequence of
- /* Indicate that this display is dead. */
+ M-x make-frame-on-display RET :1 RET
+ ...kill the new frame, so that we get an IO error...
+ M-x make-frame-on-display RET :1 RET
+
+ will indefinitely wait in Xt for events for display `:1', opened
+ in the first class to make-frame-on-display.
-#if 0 /* Closing the display caused a bus error on OpenWindows. */
+ Closing the display is reported to lead to a bus error on
+ OpenWindows in certain situations. I suspect that is a bug
+ in OpenWindows. I don't know how to cicumvent it here. */
+
#ifdef USE_X_TOOLKIT
- XtCloseDisplay (display);
-#endif
+ /* If DPYINFO is null, this means we didn't open the display
+ in the first place, so don't try to close it. */
+ if (dpyinfo)
+ XtCloseDisplay (dpy);
#endif
+ /* Indicate that this display is dead. */
if (dpyinfo)
dpyinfo->display = 0;
if (dpyinfo)
x_delete_display (dpyinfo);
+ x_uncatch_errors (dpy, count);
+
if (x_display_list == 0)
{
- fprintf (stderr, "%s\n", error_message);
+ fprintf (stderr, "%s\n", msg);
shut_down_emacs (0, 0, Qnil);
exit (70);
}
TOTALLY_UNBLOCK_INPUT;
clear_waiting_for_input ();
- handling_signal = 0;
- error ("%s", error_message);
+ error ("%s", msg);
}
+
/* This is the usual handler for X protocol errors.
It kills all frames on the display that we got the error for.
If that was the only one, it prints an error message and kills Emacs. */
x_connection_closed (display, buf1);
}
+
/* This is the first-level handler for X protocol errors.
It calls x_error_quitter or x_error_catcher. */
f->output_data.x->font->fid);
frame_update_line_height (f);
- x_set_window_size (f, 0, f->width, f->height);
+
+ /* Don't change the size of a tip frame; there's no point in
+ doing it because it's done in Fx_show_tip, and it leads to
+ problems because the tip frame has no widget. */
+ if (NILP (tip_frame) || XFRAME (tip_frame) != f)
+ x_set_window_size (f, 0, f->width, f->height);
}
else
/* If we are setting a new frame's font for the first time,
{
#ifdef USE_XIM
#ifdef HAVE_X11R6_XIM
- XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
- NULL, EMACS_CLASS,
- xim_instantiate_callback, NULL);
+ if (dpyinfo->display)
+ XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
+ NULL, EMACS_CLASS,
+ xim_instantiate_callback, NULL);
#endif /* not HAVE_X11R6_XIM */
- XCloseIM (dpyinfo->xim);
+ if (dpyinfo->display)
+ XCloseIM (dpyinfo->xim);
dpyinfo->xim = NULL;
XFree (dpyinfo->xim_styles);
#endif /* USE_XIM */
- PIXEL_WIDTH (f)
+ f->output_data.x->left_pos);
- if (flags & YNegative)
- {
- int menubar_height = 0;
+ {
+ int height = PIXEL_HEIGHT (f);
-#ifdef USE_X_TOOLKIT
- if (f->output_data.x->menubar_widget)
- menubar_height
- = (f->output_data.x->menubar_widget->core.height
- + f->output_data.x->menubar_widget->core.border_width);
+#if defined USE_X_TOOLKIT && defined USE_MOTIF
+ /* Something is fishy here. When using Motif, starting Emacs with
+ `-g -0-0', the frame appears too low by a few pixels.
+
+ This seems to be so because initially, while Emacs is starting,
+ the column widget's height and the frame's pixel height are
+ different. The column widget's height is the right one. In
+ later invocations, when Emacs is up, the frame's pixel height
+ is right, though.
+
+ It's not obvious where the initial small difference comes from.
+ 2000-12-01, gerd. */
+
+ XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL);
#endif
-
- f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
- - 2 * f->output_data.x->border_width
- - win_y
- - PIXEL_HEIGHT (f)
- - menubar_height
- + f->output_data.x->top_pos);
- }
+ if (flags & YNegative)
+ f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height
+ - 2 * f->output_data.x->border_width
+ - win_y
+ - height
+ + f->output_data.x->top_pos);
+ }
+
/* The left_pos and top_pos
are now relative to the top and left screen edges,
so the flags should correspond. */
UNBLOCK_INPUT;
}
-/* Call this to change the size of frame F's x-window.
- If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
- for this size change and subsequent size changes.
- Otherwise we leave the window gravity unchanged. */
-void
-x_set_window_size (f, change_gravity, cols, rows)
+/* Change the size of frame F's X window to COLS/ROWS in the case F
+ doesn't have a widget. If CHANGE_GRAVITY is 1, we change to
+ top-left-corner window gravity for this size change and subsequent
+ size changes. Otherwise we leave the window gravity unchanged. */
+
+static void
+x_set_window_size_1 (f, change_gravity, cols, rows)
struct frame *f;
int change_gravity;
int cols, rows;
{
-#ifndef USE_X_TOOLKIT
int pixelwidth, pixelheight;
-#endif
-
- BLOCK_INPUT;
-
-#ifdef USE_X_TOOLKIT
- {
- /* The x and y position of the widget is clobbered by the
- call to XtSetValues within EmacsFrameSetCharSize.
- This is a real kludge, but I don't understand Xt so I can't
- figure out a correct fix. Can anyone else tell me? -- rms. */
- int xpos = f->output_data.x->widget->core.x;
- int ypos = f->output_data.x->widget->core.y;
- EmacsFrameSetCharSize (f->output_data.x->edit_widget, cols, rows);
- f->output_data.x->widget->core.x = xpos;
- f->output_data.x->widget->core.y = ypos;
- }
-
-#else /* not USE_X_TOOLKIT */
check_frame_size (f, &rows, &cols);
f->output_data.x->vertical_scroll_bar_extra
SET_FRAME_GARBAGED (f);
XFlush (FRAME_X_DISPLAY (f));
+}
+
+
+/* Call this to change the size of frame F's x-window.
+ If CHANGE_GRAVITY is 1, we change to top-left-corner window gravity
+ for this size change and subsequent size changes.
+ Otherwise we leave the window gravity unchanged. */
+
+void
+x_set_window_size (f, change_gravity, cols, rows)
+ struct frame *f;
+ int change_gravity;
+ int cols, rows;
+{
+ BLOCK_INPUT;
+#ifdef USE_X_TOOLKIT
+
+ if (f->output_data.x->widget != None)
+ {
+ /* The x and y position of the widget is clobbered by the
+ call to XtSetValues within EmacsFrameSetCharSize.
+ This is a real kludge, but I don't understand Xt so I can't
+ figure out a correct fix. Can anyone else tell me? -- rms. */
+ int xpos = f->output_data.x->widget->core.x;
+ int ypos = f->output_data.x->widget->core.y;
+ EmacsFrameSetCharSize (f->output_data.x->edit_widget, cols, rows);
+ f->output_data.x->widget->core.x = xpos;
+ f->output_data.x->widget->core.y = ypos;
+ }
+ else
+ x_set_window_size_1 (f, change_gravity, cols, rows);
+
+#else /* not USE_X_TOOLKIT */
+
+ x_set_window_size_1 (f, change_gravity, cols, rows);
+
#endif /* not USE_X_TOOLKIT */
/* If cursor was outside the new size, mark it as off. */
UNBLOCK_INPUT;
#endif /* not USE_X_TOOLKIT */
}
+
\f
-/* Destroy the X window of frame F. */
+/* Free X resources of frame F. */
void
-x_destroy_window (f)
+x_free_frame_resources (f)
struct frame *f;
{
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
/* If a display connection is dead, don't try sending more
commands to the X server. */
- if (dpyinfo->display != 0)
+ if (dpyinfo->display)
{
- if (f->output_data.x->icon_desc != 0)
+ if (f->output_data.x->icon_desc)
XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
+
#ifdef HAVE_X_I18N
if (FRAME_XIC (f))
free_frame_xic (f);
#endif
- XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->window_desc);
+
+ if (FRAME_X_WINDOW (f))
+ XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+
#ifdef USE_X_TOOLKIT
if (f->output_data.x->widget)
XtDestroyWidget (f->output_data.x->widget);
unload_color (f, f->output_data.x->cursor_foreground_pixel);
unload_color (f, f->output_data.x->border_pixel);
unload_color (f, f->output_data.x->mouse_pixel);
+
if (f->output_data.x->scroll_bar_background_pixel != -1)
unload_color (f, f->output_data.x->scroll_bar_background_pixel);
if (f->output_data.x->scroll_bar_foreground_pixel != -1)
unload_color (f, f->output_data.x->white_relief.pixel);
if (f->output_data.x->black_relief.allocated_p)
unload_color (f, f->output_data.x->black_relief.pixel);
+
+ if (FRAME_FACE_CACHE (f))
+ free_frame_faces (f);
- free_frame_faces (f);
+ x_free_gcs (f);
XFlush (FRAME_X_DISPLAY (f));
}
xfree (f->output_data.x->saved_menu_event);
xfree (f->output_data.x);
- f->output_data.x = 0;
+ f->output_data.x = NULL;
+
if (f == dpyinfo->x_focus_frame)
dpyinfo->x_focus_frame = 0;
if (f == dpyinfo->x_focus_event_frame)
if (f == dpyinfo->x_highlight_frame)
dpyinfo->x_highlight_frame = 0;
- dpyinfo->reference_count--;
-
if (f == dpyinfo->mouse_face_mouse_frame)
{
dpyinfo->mouse_face_beg_row
UNBLOCK_INPUT;
}
+
+
+/* Destroy the X window of frame F. */
+
+void
+x_destroy_window (f)
+ struct frame *f;
+{
+ struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+
+ /* If a display connection is dead, don't try sending more
+ commands to the X server. */
+ if (dpyinfo->display != 0)
+ x_free_frame_resources (f);
+
+ dpyinfo->reference_count--;
+}
+
\f
/* Setting window manager hints. */
}
-/* Return a list of names of available fonts matching PATTERN on frame
- F. If SIZE is not 0, it is the size (maximum bound width) of fonts
- to be listed. Frame F NULL means we have not yet created any
- frame on X, and consult the first display in x_display_list.
- MAXNAMES sets a limit on how many fonts to match. */
+/* Return a list of names of available fonts matching PATTERN on frame F.
+
+ If SIZE is > 0, it is the size (maximum bounds width) of fonts
+ to be listed.
+
+ SIZE < 0 means include scalable fonts.
+
+ Frame F null means we have not yet created any frame on X, and
+ consult the first display in x_display_list. MAXNAMES sets a limit
+ on how many fonts to match. */
Lisp_Object
x_list_fonts (f, pattern, size, maxnames)
- FRAME_PTR f;
+ struct frame *f;
Lisp_Object pattern;
int size;
int maxnames;
{
Lisp_Object list = Qnil, patterns, newlist = Qnil, key = Qnil;
Lisp_Object tem, second_best;
- Display *dpy = f != NULL ? FRAME_X_DISPLAY (f) : x_display_list->display;
+ struct x_display_info *dpyinfo
+ = f ? FRAME_X_DISPLAY_INFO (f) : x_display_list;
+ Display *dpy = dpyinfo->display;
int try_XLoadQueryFont = 0;
int count;
+ int allow_scalable_fonts_p = 0;
+
+ if (size < 0)
+ {
+ allow_scalable_fonts_p = 1;
+ size = 0;
+ }
patterns = Fassoc (pattern, Valternate_fontname_alist);
if (NILP (patterns))
pattern = XCAR (patterns);
/* See if we cached the result for this particular query.
The cache is an alist of the form:
- (((PATTERN . MAXNAMES) (FONTNAME . WIDTH) ...) ...)
- */
- if (f && (tem = XCDR (FRAME_X_DISPLAY_INFO (f)->name_list_element),
- key = Fcons (pattern, make_number (maxnames)),
- !NILP (list = Fassoc (key, tem))))
+ ((((PATTERN . MAXNAMES) . SCALABLE) (FONTNAME . WIDTH) ...) ...) */
+ tem = XCDR (dpyinfo->name_list_element);
+ key = Fcons (Fcons (pattern, make_number (maxnames)),
+ allow_scalable_fonts_p ? Qt : Qnil);
+ list = Fassoc (key, tem);
+ if (!NILP (list))
{
list = Fcdr_safe (list);
/* We have a cashed list. Don't have to get the list again. */
int average_width = -1, dashes = 0;
/* Count the number of dashes in NAMES[I]. If there are
- 14 dashes, and the field value following 12th dash
- (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
- is usually too ugly to be used for editing. Let's
- ignore it. */
+ 14 dashes, and the field value following 12th dash
+ (AVERAGE_WIDTH) is 0, this is a auto-scaled font which
+ is usually too ugly to be used for editing. Let's
+ ignore it. */
while (*p)
if (*p++ == '-')
{
else if (dashes == 12) /* AVERAGE_WIDTH field */
average_width = atoi (p);
}
- if (dashes < 14 || average_width != 0)
+
+ if (allow_scalable_fonts_p
+ || dashes < 14 || average_width != 0)
{
tem = build_string (names[i]);
if (NILP (Fassoc (tem, list)))
}
/* Now store the result in the cache. */
- if (f != NULL)
- XCDR (FRAME_X_DISPLAY_INFO (f)->name_list_element)
- = Fcons (Fcons (key, list),
- XCDR (FRAME_X_DISPLAY_INFO (f)->name_list_element));
+ XCDR (dpyinfo->name_list_element)
+ = Fcons (Fcons (key, list), XCDR (dpyinfo->name_list_element));
label_cached:
if (NILP (list)) continue; /* Try the remaining alternatives. */
if (!INTEGERP (XCDR (tem)))
{
/* Since we have not yet known the size of this font, we
- must try slow function call XLoadQueryFont. */
+ must try slow function call XLoadQueryFont. */
XFontStruct *thisinfo;
BLOCK_INPUT;
fontp->size = font->max_bounds.width;
fontp->height = FONT_HEIGHT (font);
- {
- /* For some font, ascent and descent in max_bounds field is
- larger than the above value. */
- int max_height = font->max_bounds.ascent + font->max_bounds.descent;
- if (max_height > fontp->height)
- fontp->height = max_height;
- }
if (NILP (font_names))
{
the cache for x_list_fonts. */
Lisp_Object lispy_name = build_string (fontname);
Lisp_Object lispy_full_name = build_string (fontp->full_name);
+ Lisp_Object key = Fcons (Fcons (lispy_name, make_number (256)),
+ Qnil);
XCDR (dpyinfo->name_list_element)
- = Fcons (Fcons (Fcons (lispy_name, make_number (256)),
+ = Fcons (Fcons (key,
Fcons (Fcons (lispy_full_name,
make_number (fontp->size)),
Qnil)),
XCDR (dpyinfo->name_list_element));
if (full_name)
- XCDR (dpyinfo->name_list_element)
- = Fcons (Fcons (Fcons (lispy_full_name, make_number (256)),
- Fcons (Fcons (lispy_full_name,
- make_number (fontp->size)),
- Qnil)),
- XCDR (dpyinfo->name_list_element));
+ {
+ key = Fcons (Fcons (lispy_full_name, make_number (256)),
+ Qnil);
+ XCDR (dpyinfo->name_list_element)
+ = Fcons (Fcons (key,
+ Fcons (Fcons (lispy_full_name,
+ make_number (fontp->size)),
+ Qnil)),
+ XCDR (dpyinfo->name_list_element));
+ }
}
/* The slot `encoding' specifies how to map a character
{
extern int gray_bitmap_width, gray_bitmap_height;
- extern unsigned char *gray_bitmap_bits;
+ extern char *gray_bitmap_bits;
dpyinfo->gray
= XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window,
gray_bitmap_bits,
estimate_mode_line_height_hook = x_estimate_mode_line_height;
scroll_region_ok = 1; /* we'll scroll partial frames */
- char_ins_del_ok = 0; /* just as fast to write the line */
+ char_ins_del_ok = 1;
line_ins_del_ok = 1; /* we'll just blt 'em */
fast_clear_end_of_line = 1; /* X does this well */
memory_below_frame = 0; /* we don't remember what scrolls
}
#endif
-#if USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_TOOLKIT_SCROLL_BARS
xaw3d_arrow_scroll = False;
xaw3d_pick_top = True;
#endif
wide as that tab on the display.");
x_stretch_cursor_p = 0;
- DEFVAR_BOOL ("x-toolkit-scroll-bars-p", &x_toolkit_scroll_bars_p,
- "If not nil, Emacs uses toolkit scroll bars.");
-#if USE_TOOLKIT_SCROLL_BARS
- x_toolkit_scroll_bars_p = 1;
+ DEFVAR_LISP ("x-toolkit-scroll-bars", &Vx_toolkit_scroll_bars,
+ "What X toolkit scroll bars Emacs uses.\n\
+A value of nil means Emacs doesn't use X toolkit scroll bars.\n\
+Otherwise, value is a symbol describing the X toolkit.");
+#ifdef USE_TOOLKIT_SCROLL_BARS
+#ifdef USE_MOTIF
+ Vx_toolkit_scroll_bars = intern ("motif");
+#elif defined HAVE_XAW3D
+ Vx_toolkit_scroll_bars = intern ("xaw3d");
+#else
+ Vx_toolkit_scroll_bars = intern ("xaw");
+#endif
#else
- x_toolkit_scroll_bars_p = 0;
+ Vx_toolkit_scroll_bars = Qnil;
#endif
staticpro (&last_mouse_motion_frame);