/* X Communication module for terminals which understand the X protocol.
- Copyright (C) 1989, 93, 94, 95, 1996 Free Software Foundation, Inc.
+ Copyright (C) 1989, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include "window.h"
#include "keyboard.h"
#include "intervals.h"
+#include "process.h"
#ifdef USE_X_TOOLKIT
#include <X11/Shell.h>
is the frame to apply to. */
extern struct frame *updating_frame;
-extern waiting_for_input;
+extern int waiting_for_input;
/* This is a frame waiting to be autoraised, within XTread_socket. */
struct frame *pending_autoraise_frame;
static void show_mouse_face ();
static void do_line_dance ();
-static int XTcursor_to ();
-static int XTclear_end_of_line ();
+static void XTcursor_to ();
+static void XTclear_end_of_line ();
static int x_io_error_quitter ();
int x_catch_errors ();
void x_uncatch_errors ();
should never be called except during an update, the only exceptions
being XTcursor_to, XTwrite_glyphs and XTreassert_line_highlight. */
-static
+static void
XTupdate_begin (f)
struct frame *f;
{
UNBLOCK_INPUT;
}
-static
+static void
XTupdate_end (f)
struct frame *f;
{
/* This is called after a redisplay on frame F. */
-static
+static void
XTframe_up_to_date (f)
FRAME_PTR f;
{
if (FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc
|| f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
{
- note_mouse_highlight (FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame,
- FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_x,
- FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y);
+ if (FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame)
+ note_mouse_highlight (FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame,
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_x,
+ FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y);
FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc = 0;
}
UNBLOCK_INPUT;
Call this when about to modify line at position VPOS
and not change whether it is highlighted. */
+void
XTreassert_line_highlight (new, vpos)
int new, vpos;
{
/* Call this when about to modify line at position VPOS
and change whether it is highlighted. */
-static
+static void
XTchange_line_highlight (new_highlight, vpos, first_unused_hpos)
int new_highlight, vpos, first_unused_hpos;
{
When starting Emacs, no X window is mapped. And nothing must be done
to Emacs's own window if it is suspended (though that rarely happens). */
-static
+static void
XTset_terminal_modes ()
{
}
Exiting will make the X-windows go away, and suspending
requires no action. */
-static
+static void
XTreset_terminal_modes ()
{
/* XTclear_frame (); */
This is where display update commands will take effect.
This does not affect the place where the cursor-box is displayed. */
-static int
+static void
XTcursor_to (row, col)
register int row, col;
{
struct cmpchar_info *cmpcharp;
{
/* Holds characters to be displayed. */
- XChar2b *buf = (XChar2b *) alloca (FRAME_WINDOW_WIDTH (f) * sizeof (*buf));
- register XChar2b *cp; /* Steps through buf[]. */
+ XChar2b *x_2byte_buffer
+ = (XChar2b *) alloca (FRAME_WINDOW_WIDTH (f) * sizeof (*x_2byte_buffer));
+ register XChar2b *cp; /* Steps through x_2byte_buffer[]. */
+ char *x_1byte_buffer
+ = (char *) alloca (FRAME_WINDOW_WIDTH (f) * sizeof (*x_1byte_buffer));
register int tlen = GLYPH_TABLE_LENGTH;
register Lisp_Object *tbase = GLYPH_TABLE_BASE;
Window window = FRAME_X_WINDOW (f);
/* Get the face-code of the next GLYPH. */
int cf, len;
GLYPH g = *gp;
- int ch, first_ch, charset;
+ int ch, charset;
+ Lisp_Object first_ch;
/* HIGHEST and LOWEST are used while drawing a composite
character. The meanings are described later. */
int highest, lowest;
GLYPH_FOLLOW_ALIASES (tbase, tlen, g);
cf = (cmpcharp ? cmpcharp->face_work : FAST_GLYPH_FACE (g));
ch = FAST_GLYPH_CHAR (g);
- if (gidx == 0) first_ch = ch;
+ if (gidx == 0) XSETFASTINT (first_ch, ch);
charset = CHAR_CHARSET (ch);
if (charset == CHARSET_COMPOSITION)
{
/* Find the run of consecutive glyphs which can be drawn with
the same GC (i.e. the same charset and the same face-code).
- Extract their character codes into BUF.
+ Extract their character codes into X_2BYTE_BUFFER.
If CMPCHARP is not NULL, face-code is not checked because we
use only the face specified in `cmpcharp->face_work'. */
- cp = buf;
+ cp = x_2byte_buffer;
while (n > 0)
{
int this_charset, c1, c2;
}
/* LEN gets the length of the run. */
- len = cp - buf;
+ len = cp - x_2byte_buffer;
/* Now output this run of chars, with the font and pixel values
determined by the face code CF. */
{
struct ccl_program *ccl = fontp->font_encoder;
if (CHARSET_DIMENSION (charset) == 1)
- for (cp = buf; cp < buf + len; cp++)
+ for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
{
ccl->reg[0] = charset;
ccl->reg[1] = cp->byte2;
ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
- cp->byte2 = ccl->reg[1];
+ /* We assume that MSBs are appropriately
+ set/reset by CCL program. */
+ if (font->max_byte1 == 0) /* 1-byte font */
+ cp->byte2 = ccl->reg[1];
+ else
+ cp->byte1 = ccl->reg[1], cp->byte2 = ccl->reg[2];
}
else
- for (cp = buf; cp < buf + len; cp++)
+ for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
{
ccl->reg[0] = charset;
ccl->reg[1] = cp->byte1, ccl->reg[2] = cp->byte2;
ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
- cp->byte1 = ccl->reg[1], cp->byte2 = ccl->reg[2];
+ /* We assume that MSBs are appropriately
+ set/reset by CCL program. */
+ if (font->max_byte1 == 0) /* 1-byte font */
+ cp->byte2 = ccl->reg[1];
+ else
+ cp->byte1 = ccl->reg[1], cp->byte2 = ccl->reg[2];
}
}
else if (fontp->encoding[charset])
int enc = fontp->encoding[charset];
if ((enc == 1 || enc == 2) && CHARSET_DIMENSION (charset) == 2)
- for (cp = buf; cp < buf + len; cp++)
+ for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
cp->byte1 |= 0x80;
if (enc == 1 || enc == 3)
- for (cp = buf; cp < buf + len; cp++)
+ for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
cp->byte2 |= 0x80;
}
}
font = FACE_FONT (face);
if (font == (XFontStruct *) FACE_DEFAULT)
font = f->output_data.x->font;
- baseline = FONT_BASE (font);
+ baseline = FONT_BASE (f->output_data.x->font);
if (charset == charset_latin_iso8859_1)
{
if (font->max_char_or_byte2 < 0x80)
font = NULL;
else
{
- for (cp = buf; cp < buf + len; cp++)
+ for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
cp->byte2 |= 0x80;
}
}
{
/* Fill a area for the current run in background pixle of GC. */
XGCValues xgcv;
- unsigned long mask = GCForeground | GCBackground;
- unsigned long fore, back;
+ unsigned long mask = GCForeground | GCBackground | GCFillStyle;
/* The current code at first set foreground to background,
fill the area, then recover the original foreground.
XGetGCValues (FRAME_X_DISPLAY (f), gc, mask, &xgcv);
XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.background);
+ XSetFillStyle (FRAME_X_DISPLAY (f), gc, FillSolid);
XFillRectangle (FRAME_X_DISPLAY (f), window, gc,
left, top, run_width, line_height);
XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.foreground);
if (background_filled)
XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
left + glyph_width * i,
- top + baseline, buf + i, 1);
+ top + baseline, x_2byte_buffer + i, 1);
else
XDrawImageString16 (FRAME_X_DISPLAY (f), window, gc,
left + glyph_width * i,
- top + baseline, buf + i, 1);
+ top + baseline, x_2byte_buffer + i, 1);
}
else
{
- if (background_filled)
- XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
- left, top + baseline, buf, len);
+ /* See if this whole buffer can be output as 8-bit chars.
+ If so, copy x_2byte_buffer to x_1byte_buffer
+ and do it as 8-bit chars. */
+ for (i = 0; i < len; i++)
+ {
+ if (x_2byte_buffer[i].byte1 != 0)
+ break;
+ x_1byte_buffer[i] = x_2byte_buffer[i].byte2;
+ }
+
+ if (i == len)
+ {
+ if (background_filled)
+ XDrawString (FRAME_X_DISPLAY (f), window, gc,
+ left, top + baseline, x_1byte_buffer, len);
+ else
+ XDrawImageString (FRAME_X_DISPLAY (f), window, gc,
+ left, top + baseline, x_1byte_buffer, len);
+ }
else
- XDrawImageString16 (FRAME_X_DISPLAY (f), window, gc,
- left, top + baseline, buf, len);
+ {
+ /* We can't output them as 8-bit chars,
+ so do it as 16-bit chars. */
+
+ if (background_filled)
+ XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
+ left, top + baseline, x_2byte_buffer, len);
+ else
+ XDrawImageString16 (FRAME_X_DISPLAY (f), window, gc,
+ left, top + baseline, x_2byte_buffer, len);
+ }
}
}
else
{
+ /* Handle composite characters. */
XCharStruct *pcm; /* Pointer to per char metric info. */
if ((cmpcharp->cmp_rule || relative_compose)
}
else
{
- pcm = PER_CHAR_METRIC (font, buf);
+ pcm = PER_CHAR_METRIC (font, x_2byte_buffer);
highest = pcm->ascent + 1;
lowest = - pcm->descent;
}
* FONT_WIDTH (f->output_data.x->font));
/* Draw the first character at the normal position. */
XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
- left + x_offset, top + baseline, buf, 1);
+ left + x_offset, top + baseline, x_2byte_buffer, 1);
i = 1;
gidx++;
}
if (relative_compose)
{
- pcm = PER_CHAR_METRIC (font, buf + i);
- if (- pcm->descent >= relative_compose)
+ pcm = PER_CHAR_METRIC (font, x_2byte_buffer + i);
+ if (NILP (Vignore_relative_composition)
+ || NILP (Faref (Vignore_relative_composition,
+ make_number (cmpcharp->glyph[gidx]))))
{
- /* Draw above the current glyphs. */
- y_offset = highest + pcm->descent;
- highest += pcm->ascent + pcm->descent;
+ if (- pcm->descent >= relative_compose)
+ {
+ /* Draw above the current glyphs. */
+ y_offset = highest + pcm->descent;
+ highest += pcm->ascent + pcm->descent;
+ }
+ else if (pcm->ascent <= 0)
+ {
+ /* Draw beneath the current glyphs. */
+ y_offset = lowest - pcm->ascent;
+ lowest -= pcm->ascent + pcm->descent;
+ }
}
- else if (pcm->ascent <= 0)
+ else
{
- /* Draw beneath the current glyphs. */
- y_offset = lowest - pcm->ascent;
- lowest -= pcm->ascent + pcm->descent;
+ /* Draw the glyph at normal position. If
+ it sticks out of HIGHEST or LOWEST,
+ update them appropriately. */
+ if (pcm->ascent > highest)
+ highest = pcm->ascent;
+ else if (- pcm->descent < lowest)
+ lowest = - pcm->descent;
}
}
else if (cmpcharp->cmp_rule)
gref = gref / 3 + (gref == 4) * 2;
nref = nref / 3 + (nref == 4) * 2;
- pcm = PER_CHAR_METRIC (font, buf + i);
+ pcm = PER_CHAR_METRIC (font, x_2byte_buffer + i);
bottom = ((gref == 0 ? highest : gref == 1 ? 0
: gref == 2 ? lowest
: (highest + lowest) / 2)
}
XDrawString16 (FRAME_X_DISPLAY (f), window, gc,
left + x_offset, top + baseline - y_offset,
- buf + i, 1);
+ x_2byte_buffer + i, 1);
}
}
if (require_clipping)
`highlight', set up by XTreassert_line_highlight or XTchange_line_highlight,
controls the pixel values used for foreground and background. */
-static
+static void
XTwrite_glyphs (start, len)
register GLYPH *start;
int len;
to column FIRST_UNUSED (exclusive). The idea is that everything
from FIRST_UNUSED onward is already erased. */
-static
+static void
XTclear_end_of_line (first_unused)
register int first_unused;
{
UNBLOCK_INPUT;
}
-static
+static void
XTclear_frame ()
{
int mask;
return x.tv_sec < y.tv_sec;
}
+void
XTflash (f)
struct frame *f;
{
#define XRINGBELL XBell (FRAME_X_DISPLAY (selected_frame), 0)
+void
XTring_bell ()
{
if (FRAME_X_DISPLAY (selected_frame) == 0)
These are not supposed to be used because we are supposed to turn
off the feature of using them. */
-static
+static void
XTinsert_glyphs (start, len)
register char *start;
register int len;
abort ();
}
-static
+static void
XTdelete_glyphs (n)
register int n;
{
This, and those operations, are used only within an update
that is bounded by calls to XTupdate_begin and XTupdate_end. */
-static
+static void
XTset_terminal_window (n)
register int n;
{
/* Perform an insert-lines or delete-lines operation,
inserting N lines or deleting -N lines at vertical position VPOS. */
+void
XTins_del_lines (vpos, n)
int vpos, n;
{
/* Just discard the mouse face information for frame F, if any.
This is used when the size of F is changed. */
+void
cancel_mouse_face (f)
FRAME_PTR f;
{
BLOCK_INPUT;
- if (! NILP (last_mouse_scroll_bar))
+ if (! NILP (last_mouse_scroll_bar) && insist == 0)
x_scroll_bar_report_motion (fp, bar_window, part, x, y, time);
else
{
}
}
- if (f1 == 0 && insist)
+ if (f1 == 0 && insist > 0)
f1 = selected_frame;
if (f1)
Clear out the scroll bars, and ask for expose events, so we can
redraw them. */
+void
x_scroll_bar_clear (f)
FRAME_PTR f;
{
if (event.xclient.data.l[0]
== dpyinfo->Xatom_wm_take_focus)
{
- f = x_window_to_frame (dpyinfo, event.xclient.window);
- /* Since we set WM_TAKE_FOCUS, we must call
- XSetInputFocus explicitly. But not if f is null,
- since that might be an event for a deleted frame. */
+ /* Use x_any_window_to_frame because this
+ could be the shell widget window
+ if the frame has no title bar. */
+ f = x_any_window_to_frame (dpyinfo, event.xclient.window);
#ifdef HAVE_X_I18N
/* Not quite sure this is needed -pd */
- if (f)
+ if (f && FRAME_XIC (f))
XSetICFocus (FRAME_XIC (f));
#endif
+ /* Since we set WM_TAKE_FOCUS, we must call
+ XSetInputFocus explicitly. But not if f is null,
+ since that might be an event for a deleted frame. */
if (f)
- XSetInputFocus (event.xclient.display,
- event.xclient.window,
- RevertToPointerRoot,
- event.xclient.data.l[1]);
+ {
+ Display *d = event.xclient.display;
+ /* Catch and ignore errors, in case window has been
+ iconified by a window manager such as GWM. */
+ int count = x_catch_errors (d);
+ XSetInputFocus (d, event.xclient.window,
+ RevertToPointerRoot,
+ event.xclient.data.l[1]);
+ /* This is needed to detect the error
+ if there is an error. */
+ XSync (d, False);
+ x_uncatch_errors (d, count);
+ }
/* Not certain about handling scroll bars here */
}
else if (event.xclient.data.l[0]
if (! x_window_to_frame (dpyinfo, event.xselection.requestor))
goto OTHER;
#endif /* not USE_X_TOOLKIT */
- x_handle_selection_notify (&event);
+ x_handle_selection_notify (&event.xselection);
break;
case SelectionClear: /* Someone has grabbed ownership. */
if (!x_any_window_to_frame (dpyinfo, event.xproperty.window))
goto OTHER;
#endif /* not USE_X_TOOLKIT */
- x_handle_property_notify (&event);
+ x_handle_property_notify (&event.xproperty);
break;
case ReparentNotify:
#ifdef HAVE_X_I18N
if (FRAME_XIC (f))
{
+ /* The necessity of the following line took me
+ a full work-day to decipher from the docs!! */
+ if (XFilterEvent (&event, None))
+ break;
nbytes = XmbLookupString (FRAME_XIC (f),
&event.xkey, copy_buffer,
80, &keysym,
f->output_data.x->win_gravity = NorthWestGravity;
x_wm_set_size_hint (f, (long) 0, 0);
}
+#ifdef USE_MOTIF
+ /* Some window managers pass (0,0) as the location of
+ the window, and the Motif event handler stores it
+ in the emacs widget, which messes up Motif menus. */
+ if (event.xconfigure.x == 0 && event.xconfigure.y == 0)
+ {
+ event.xconfigure.x = f->output_data.x->widget->core.x;
+ event.xconfigure.y = f->output_data.x->widget->core.y;
+ }
+#endif
}
goto OTHER;
int c = FAST_GLYPH_CHAR (f->phys_cursor_glyph);
int charset = CHAR_CHARSET (c);
+ XGCValues xgcv;
+ unsigned long mask = GCForeground;
+
+ xgcv.foreground = f->output_data.x->cursor_pixel;
+
+ /* cursor_gc's foreground color is typically the same as the normal
+ background color, which can cause the cursor box to be invisible. */
+ if (FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc)
+ XChangeGC (FRAME_X_DISPLAY (f),
+ FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc,
+ mask, &xgcv);
+ else
+ FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc
+ = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), mask, &xgcv);
+
/* If cursor is on a multi-column character, multiply WIDTH by columns. */
width *= (charset == CHARSET_COMPOSITION
? cmpchar_table[COMPOSITE_CHAR_ID (c)]->width
: CHARSET_WIDTH (charset));
XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- f->output_data.x->cursor_gc,
+ FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc,
left, top, width - 1, height - 1);
}
/* Display the cursor on frame F, or clear it, according to ON.
Also set the frame's cursor position to X and Y. */
+void
x_display_cursor (f, on, x, y)
struct frame *f;
int on;
{
BLOCK_INPUT;
+ if ((unsigned) x >= FRAME_WIDTH (f) + FRAME_LEFT_SCROLL_BAR_WIDTH (f)
+ || (unsigned) y >= FRAME_HEIGHT (f))
+ abort ();
+
if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor)
x_display_box_cursor (f, on, x, y);
else if (FRAME_DESIRED_CURSOR (f) == bar_cursor)
/* Display the cursor on frame F, or clear it, according to ON.
Don't change the cursor's position. */
+void
x_update_cursor (f, on)
struct frame *f;
int on;
/* Refresh bitmap kitchen sink icon for frame F
when we get an expose event for it. */
+void
refreshicon (f)
struct frame *f;
{
f->scroll_bar_cols = (f->scroll_bar_pixel_width + wid-1) / wid;
}
else
- f->scroll_bar_cols = 2;
+ {
+ int wid = FONT_WIDTH (f->output_data.x->font);
+ f->scroll_bar_cols = (14 + wid - 1) / wid;
+ }
/* Now make the frame display the given font. */
if (FRAME_X_WINDOW (f) != 0)
/* Calculate the absolute position in frame F
from its current recorded position values and gravity. */
+void
x_calc_absolute_position (f)
struct frame *f;
{
position values). It is -1 when calling from x_set_frame_parameters,
which means, do adjust for borders but don't change the gravity. */
+void
x_set_offset (f, xoff, yoff, change_gravity)
struct frame *f;
register int xoff, yoff;
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;
\f
/* focus shifting, raising and lowering. */
+void
x_focus_on_frame (f)
struct frame *f;
{
#endif /* ! 0 */
}
+void
x_unfocus_frame (f)
struct frame *f;
{
/* Raise frame F. */
+void
x_raise_frame (f)
struct frame *f;
{
/* Lower frame F. */
+void
x_lower_frame (f)
struct frame *f;
{
but it will become visible later when the window manager
finishes with it. */
+void
x_make_frame_visible (f)
struct frame *f;
{
because the window manager may choose the position
and we don't want to override it. */
- if (! FRAME_VISIBLE_P (f)
+ if (! FRAME_VISIBLE_P (f) && ! FRAME_ICONIFIED_P (f)
&& f->output_data.x->win_gravity == NorthWestGravity
&& previously_visible)
{
/* It could be confusing if a real alarm arrives while processing
the fake one. Turn it off and let the handler reset it. */
alarm (0);
- input_poll_signal ();
+ input_poll_signal (0);
}
/* Once we have handled input events,
we should have received the MapNotify if one is coming.
/* Make the frame visible (mapped and not iconified). */
+void
x_make_frame_invisible (f)
struct frame *f;
{
/* Change window state from mapped to iconified. */
+void
x_iconify_frame (f)
struct frame *f;
{
\f
/* Destroy the X window of frame F. */
+void
x_destroy_window (f)
struct frame *f;
{
dpyinfo->mouse_face_end_row
= dpyinfo->mouse_face_end_col = -1;
dpyinfo->mouse_face_window = Qnil;
+ dpyinfo->mouse_face_deferred_gc = 0;
+ dpyinfo->mouse_face_mouse_frame = 0;
}
UNBLOCK_INPUT;
If USER_POSITION is nonzero, we set the USPosition
flag (this is useful when FLAGS is 0). */
+void
x_wm_set_size_hint (f, flags, user_position)
struct frame *f;
long flags;
}
/* Used for IconicState or NormalState */
+void
x_wm_set_window_state (f, state)
struct frame *f;
int state;
#endif /* not USE_X_TOOLKIT */
}
+void
x_wm_set_icon_pixmap (f, pixmap_id)
struct frame *f;
int pixmap_id;
#endif /* not USE_X_TOOLKIT */
}
+void
x_wm_set_icon_position (f, icon_x, icon_y)
struct frame *f;
int icon_x, icon_y;
int size;
int maxnames;
{
- Lisp_Object list, patterns, newlist = Qnil, key, tem, second_best;
+ Lisp_Object list = Qnil, patterns, newlist = Qnil, key, tem, second_best;
Display *dpy = f != NULL ? FRAME_X_DISPLAY (f) : x_display_list->display;
- patterns = Fassoc (pattern, Valternative_fontname_alist);
+ patterns = Fassoc (pattern, Valternate_fontname_alist);
if (NILP (patterns))
patterns = Fcons (pattern, Qnil);
+ /* We try at least 10 fonts because X server will return auto-scaled
+ fonts at the head. */
+ if (maxnames < 10) maxnames = 10;
+
for (; CONSP (patterns); patterns = XCONS (patterns)->cdr)
{
int num_fonts;
char **names;
pattern = XCONS (patterns)->car;
- /* See if we cached the result for this particular query. */
+ /* 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 = XCONS (FRAME_X_DISPLAY_INFO (f)->name_list_element)->cdr,
key = Fcons (pattern, make_number (maxnames)),
!NILP (list = Fassoc (key, tem))))
/* Make a list of the fonts that have the right width. */
for (; CONSP (list); list = XCONS (list)->cdr)
{
+ int found_size;
+
tem = XCONS (list)->car;
if (!CONSP (tem) || NILP (XCONS (tem)->car))
if (thisinfo)
{
- XCONS (tem)->cdr = make_number (thisinfo->max_bounds.width);
+ XCONS (tem)->cdr
+ = (thisinfo->min_bounds.width == 0
+ ? make_number (0)
+ : make_number (thisinfo->max_bounds.width));
XFreeFont (dpy, thisinfo);
}
else
as 0 not to try to open it again. */
XCONS (tem)->cdr = make_number (0);
}
- if (XINT (XCONS (tem)->cdr) == size)
+
+ found_size = XINT (XCONS (tem)->cdr);
+ if (found_size == size)
newlist = Fcons (XCONS (tem)->car, newlist);
- else if (NILP (second_best))
- second_best = tem;
- else if (XINT (XCONS (tem)->cdr) < size)
+ else if (found_size > 0)
{
- if (XINT (XCONS (second_best)->cdr) > size
- || XINT (XCONS (second_best)->cdr) < XINT (XCONS (tem)->cdr))
- second_best = tem;
- }
- else
- {
- if (XINT (XCONS (second_best)->cdr) > size
- && XINT (XCONS (second_best)->cdr) > XINT (XCONS (tem)->cdr))
+ if (NILP (second_best))
second_best = tem;
+ else if (found_size < size)
+ {
+ if (XINT (XCONS (second_best)->cdr) > size
+ || XINT (XCONS (second_best)->cdr) < found_size)
+ second_best = tem;
+ }
+ else
+ {
+ if (XINT (XCONS (second_best)->cdr) > size
+ && XINT (XCONS (second_best)->cdr) > found_size)
+ second_best = tem;
+ }
}
}
if (!NILP (newlist))
fontp->full_name = fontp->name;
fontp->size = font->max_bounds.width;
- fontp->height = font->ascent + font->descent;
+ fontp->height = font->max_bounds.ascent + font->max_bounds.descent;
if (NILP (font_names))
{
#endif /* ! 0 */
dpyinfo->x_id_name
- = (char *) xmalloc (XSTRING (Vinvocation_name)->size
- + XSTRING (Vsystem_name)->size
+ = (char *) xmalloc (STRING_BYTES (XSTRING (Vinvocation_name))
+ + STRING_BYTES (XSTRING (Vsystem_name))
+ 2);
sprintf (dpyinfo->x_id_name, "%s@%s",
XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
dpyinfo->connection = connection;
{
- char null_bits[] = { 0x00 };
+ char null_bits[1];
+
+ null_bits[0] = 0x00;
dpyinfo->null_pixel
= XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window,
#endif /* ! defined (SIGIO) */
#ifdef USE_LUCID
+#ifdef HAVE_X11R5 /* It seems X11R4 lacks XtCvtStringToFont, and XPointer. */
/* Make sure that we have a valid font for dialog boxes
so that Xt does not crash. */
{
x_uncatch_errors (dpy, count);
}
#endif
+#endif
UNBLOCK_INPUT;
\f
/* Set up use of X before we make the first connection. */
+void
x_initialize ()
{
clear_frame_hook = XTclear_frame;