/* 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.
static int XTcursor_to ();
static int XTclear_end_of_line ();
static int x_io_error_quitter ();
-void x_catch_errors ();
+int x_catch_errors ();
void x_uncatch_errors ();
\f
#if 0
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;
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 font_info *fontp;
if ((fontset < 0 && (fontset = FRAME_FONTSET (f)) < 0)
- || !(fontp = fs_load_font (f, FRAME_X_FONT_TABLE (f),
+ || !(fontp = FS_LOAD_FONT (f, FRAME_X_FONT_TABLE (f),
charset, NULL, fontset)))
goto font_not_found;
= (font->max_byte1 != 0
? (line_height + font->ascent - font->descent) / 2
: f->output_data.x->font_baseline - fontp->baseline_offset);
+ if (FONT_HEIGHT (font) <= line_height
+ && (font->ascent > baseline
+ || font->descent > line_height - baseline))
+ /* Adjust baseline for this font to show the whole
+ glyphs in a line. */
+ baseline = line_height - font->descent;
+
if (cmpcharp && cmpcharp->cmp_rule == NULL)
{
relative_compose = fontp->relative_compose;
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;
}
}
else
{
- font = FACE_FONT (face);
- if (font == (XFontStruct *) FACE_DEFAULT)
- font = f->output_data.x->font;
- baseline = FONT_BASE (font);
font_not_found:
- gc = FACE_GC (face);
+ if (charset == CHARSET_ASCII || charset == charset_latin_iso8859_1)
+ {
+ font = FACE_FONT (face);
+ if (font == (XFontStruct *) FACE_DEFAULT)
+ font = f->output_data.x->font;
+ baseline = FONT_BASE (f->output_data.x->font);
+ if (charset == charset_latin_iso8859_1)
+ {
+ if (font->max_char_or_byte2 < 0x80)
+ /* This font can't display Latin1 characters. */
+ font = NULL;
+ else
+ {
+ for (cp = x_2byte_buffer; cp < x_2byte_buffer + len; cp++)
+ cp->byte2 |= 0x80;
+ }
+ }
+ }
+ gc = FACE_GC (face);
}
/* Now override that if the cursor's on this character. */
if (font == f->output_data.x->font
&& face->background == f->output_data.x->background_pixel
- && face->foreground == f->output_data.x->foreground_pixel)
+ && face->foreground == f->output_data.x->foreground_pixel
+ && !cmpcharp)
{
gc = f->output_data.x->cursor_gc;
}
{
/* 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 exchange foreground and
- background of GC, fill the area, then recover the
- original foreground and background of GC.
- Aren't there any more smart ways? */
+ /* The current code at first set foreground to background,
+ fill the area, then recover the original foreground.
+ Aren't there any smarter ways? */
XGetGCValues (FRAME_X_DISPLAY (f), gc, mask, &xgcv);
- fore = xgcv.foreground, back = xgcv.background;
- xgcv.foreground = back, xgcv.background = fore;
- XChangeGC (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);
- xgcv.foreground = fore, xgcv.background = back;
- XChangeGC (FRAME_X_DISPLAY (f), gc, mask, &xgcv);
+ XSetForeground (FRAME_X_DISPLAY (f), gc, xgcv.foreground);
background_filled = 1;
if (cmpcharp)
if (!cmpcharp)
{
- if (require_clipping)
+ if (require_clipping || FONT_WIDTH (font) != glyph_width)
for (i = 0; i < len; i++)
{
- if (i > 0)
+ if (require_clipping && i > 0)
XSetClipOrigin (FRAME_X_DISPLAY (f), gc,
glyph_width * i, 0);
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)
}
#endif
}
- if (!font || require_clipping && !NILP (Vhighlight_wrong_size_font))
+ if (!font)
{
- /* Show rectangles to show that we found no font or a font
- of inappropriate size. */
+ /* Show rectangles to indicate that we found no font. */
+ int limit = cmpcharp ? 1 : len;
- if (cmpcharp)
- XDrawRectangle
- (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
- left, top, run_width - 1, line_height - 1);
- else
- for (i = 0; i < len; i++)
- XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
- left + glyph_width * i, top,
- glyph_width -1, line_height - 1);
+ for (i = 0; i < limit; i++)
+ XDrawRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+ left + glyph_width * i, top,
+ glyph_width - 1, line_height - 1);
+ }
+ else if (require_clipping && !NILP (Vhighlight_wrong_size_font))
+ {
+ /* Show ??? to indicate that we found a font of
+ inappropriate size. */
+ int limit = cmpcharp ? 1 : len;
+
+ for (i = 0; i < limit; i++)
+ {
+ XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+ left + glyph_width * i, top + line_height - 1,
+ left + glyph_width * i + 1, top + line_height - 1);
+ XDrawLine (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
+ left + glyph_width * i, top + line_height - 3,
+ left + glyph_width * i, top + line_height - 1);
+ }
}
-
+
/* We should probably check for XA_UNDERLINE_POSITION and
XA_UNDERLINE_THICKNESS properties on the font, but let's
just get the thing working, and come back to that. */
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
{
Window win, child;
int win_x, win_y;
int parent_x, parent_y;
+ int count;
win = root;
structure is changing at the same time this function
is running. So at least we must not crash from them. */
- x_catch_errors (FRAME_X_DISPLAY (*fp));
+ count = x_catch_errors (FRAME_X_DISPLAY (*fp));
if (FRAME_X_DISPLAY_INFO (*fp)->grabbed && last_mouse_frame
&& FRAME_LIVE_P (last_mouse_frame))
if (x_had_errors_p (FRAME_X_DISPLAY (*fp)))
f1 = 0;
- x_uncatch_errors (FRAME_X_DISPLAY (*fp));
+ x_uncatch_errors (FRAME_X_DISPLAY (*fp), count);
/* If not, is it one of our scroll bars? */
if (! f1)
}
}
- if (f1 == 0 && insist)
+ if (f1 == 0 && insist > 0)
f1 = selected_frame;
if (f1)
{
f->async_visible = 1;
f->async_iconified = 0;
+ f->output_data.x->has_been_visible = 1;
SET_FRAME_GARBAGED (f);
}
else
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]
{
f->async_visible = 1;
f->async_iconified = 0;
+ f->output_data.x->has_been_visible = 1;
SET_FRAME_GARBAGED (f);
}
else
/* We can't distinguish, from the event, whether the window
has become iconified or invisible. So assume, if it
was previously visible, than now it is iconified.
- We depend on x_make_frame_invisible to mark it invisible. */
+ But x_make_frame_invisible clears both
+ the visible flag and the iconified flag;
+ and that way, we know the window is not iconified now. */
if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f))
- f->async_iconified = 1;
+ {
+ f->async_iconified = 1;
- bufp->kind = iconify_event;
- XSETFRAME (bufp->frame_or_window, f);
- bufp++;
- count++;
- numchars--;
+ bufp->kind = iconify_event;
+ XSETFRAME (bufp->frame_or_window, f);
+ bufp++;
+ count++;
+ numchars--;
+ }
}
goto OTHER;
{
f->async_visible = 1;
f->async_iconified = 0;
+ f->output_data.x->has_been_visible = 1;
/* wait_reading_process_input will notice this and update
the frame's display structures. */
#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,
goto OTHER;
case ConfigureNotify:
- f = x_any_window_to_frame (dpyinfo, event.xconfigure.window);
- if (f
-#ifdef USE_X_TOOLKIT
- && (event.xconfigure.window == XtWindow (f->output_data.x->widget))
-#endif
- )
+ f = x_top_window_to_frame (dpyinfo, event.xconfigure.window);
+ if (f)
{
#ifndef USE_X_TOOLKIT
/* In the toolkit version, change_frame_size
}
#endif
- /* Formerly, in the USE_X_TOOLKIT version,
- we did not test send_event here. */
- if (1
-#ifndef USE_X_TOOLKIT
- && ! event.xconfigure.send_event
-#endif
- )
- {
- Window win, child;
- int win_x, win_y;
-
- /* Find the position of the outside upper-left corner of
- the window, in the root coordinate system. Don't
- refer to the parent window here; we may be processing
- this event after the window manager has changed our
- parent, but before we have reached the ReparentNotify. */
- XTranslateCoordinates (FRAME_X_DISPLAY (f),
-
- /* From-window, to-window. */
- event.xconfigure.window,
- FRAME_X_DISPLAY_INFO (f)->root_window,
-
- /* From-position, to-position. */
- -event.xconfigure.border_width,
- -event.xconfigure.border_width,
- &win_x, &win_y,
-
- /* Child of win. */
- &child);
- event.xconfigure.x = win_x;
- event.xconfigure.y = win_y;
- }
-
f->output_data.x->pixel_width = event.xconfigure.width;
f->output_data.x->pixel_height = event.xconfigure.height;
- f->output_data.x->left_pos = event.xconfigure.x;
- f->output_data.x->top_pos = event.xconfigure.y;
/* What we have now is the position of Emacs's own window.
Convert that to the position of the window manager window. */
- {
- int x, y;
- x_real_positions (f, &x, &y);
- f->output_data.x->left_pos = x;
- f->output_data.x->top_pos = y;
- /* Formerly we did not do this in the USE_X_TOOLKIT
- version. Let's try making them the same. */
-/* #ifndef USE_X_TOOLKIT */
- if (y != event.xconfigure.y)
- {
- /* Since the WM decorations come below top_pos now,
- we must put them below top_pos in the future. */
- f->output_data.x->win_gravity = NorthWestGravity;
- x_wm_set_size_hint (f, (long) 0, 0);
- }
-/* #endif */
- }
+ x_real_positions (f, &f->output_data.x->left_pos,
+ &f->output_data.x->top_pos);
+
+ if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
+ {
+ /* Since the WM decorations come below top_pos now,
+ we must put them below top_pos in the future. */
+ 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);
}
{
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)
return 0;
}
\f
+#define X_ERROR_MESSAGE_SIZE 200
+
+/* If non-nil, this should be a string.
+ It means catch X errors and store the error message in this string. */
+
+static Lisp_Object x_error_message_string;
+
+/* An X error handler which stores the error message in
+ x_error_message_string. This is called from x_error_handler if
+ x_catch_errors is in effect. */
+
+static int
+x_error_catcher (display, error)
+ Display *display;
+ XErrorEvent *error;
+{
+ XGetErrorText (display, error->error_code,
+ XSTRING (x_error_message_string)->data,
+ X_ERROR_MESSAGE_SIZE);
+}
+
+/* Begin trapping X errors for display DPY. Actually we trap X errors
+ for all displays, but DPY should be the display you are actually
+ operating on.
+
+ After calling this function, X protocol errors no longer cause
+ Emacs to exit; instead, they are recorded in the string
+ stored in x_error_message_string.
+
+ Calling x_check_errors signals an Emacs error if an X error has
+ occurred since the last call to x_catch_errors or x_check_errors.
+
+ Calling x_uncatch_errors resumes the normal error handling. */
+
+void x_check_errors ();
+static Lisp_Object x_catch_errors_unwind ();
+
+int
+x_catch_errors (dpy)
+ Display *dpy;
+{
+ int count = specpdl_ptr - specpdl;
+
+ /* Make sure any errors from previous requests have been dealt with. */
+ XSync (dpy, False);
+
+ record_unwind_protect (x_catch_errors_unwind, x_error_message_string);
+
+ x_error_message_string = make_uninit_string (X_ERROR_MESSAGE_SIZE);
+ XSTRING (x_error_message_string)->data[0] = 0;
+
+ return count;
+}
+
+/* Unbind the binding that we made to check for X errors. */
+
+static Lisp_Object
+x_catch_errors_unwind (old_val)
+ Lisp_Object old_val;
+{
+ x_error_message_string = old_val;
+ return Qnil;
+}
+
+/* If any X protocol errors have arrived since the last call to
+ x_catch_errors or x_check_errors, signal an Emacs error using
+ sprintf (a buffer, FORMAT, the x error message text) as the text. */
+
+void
+x_check_errors (dpy, format)
+ Display *dpy;
+ char *format;
+{
+ /* Make sure to catch any errors incurred so far. */
+ XSync (dpy, False);
+
+ if (XSTRING (x_error_message_string)->data[0])
+ error (format, XSTRING (x_error_message_string)->data);
+}
+
+/* Nonzero if we had any X protocol errors
+ since we did x_catch_errors on DPY. */
+
+int
+x_had_errors_p (dpy)
+ Display *dpy;
+{
+ /* Make sure to catch any errors incurred so far. */
+ XSync (dpy, False);
+
+ return XSTRING (x_error_message_string)->data[0] != 0;
+}
+
+/* Forget about any errors we have had, since we did x_catch_errors on DPY. */
+
+int
+x_clear_errors (dpy)
+ Display *dpy;
+{
+ XSTRING (x_error_message_string)->data[0] = 0;
+}
+
+/* Stop catching X protocol errors and let them make Emacs die.
+ DPY should be the display that was passed to x_catch_errors.
+ COUNT should be the value that was returned by
+ the corresponding call to x_catch_errors. */
+
+void
+x_uncatch_errors (dpy, count)
+ Display *dpy;
+ int count;
+{
+ unbind_to (count, Qnil);
+}
+
+#if 0
+static unsigned int x_wire_count;
+x_trace_wire ()
+{
+ fprintf (stderr, "Lib call: %d\n", ++x_wire_count);
+}
+#endif /* ! 0 */
+
+\f
+/* Handle SIGPIPE, which can happen when the connection to a server
+ simply goes away. SIGPIPE is handled by x_connection_signal.
+ Don't need to do anything, because the write which caused the
+ SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
+ which will do the appropriate cleanup for us. */
+
+static SIGTYPE
+x_connection_signal (signalnum) /* If we don't have an argument, */
+ int signalnum; /* some compilers complain in signal calls. */
+{
+#ifdef USG
+ /* USG systems forget handlers when they are used;
+ must reestablish each time */
+ signal (signalnum, x_connection_signal);
+#endif /* USG */
+}
+\f
/* Handling X errors. */
/* Handle the loss of connection to display DISPLAY. */
/* Indicate that this display is dead. */
- #ifdef USE_X_TOOLKIT
+#ifdef USE_X_TOOLKIT
XtCloseDisplay (display);
- #endif
+#endif
dpyinfo->display = 0;
x_connection_closed (display, buf1);
}
-/* This is the handler for X IO errors, always.
- It kills all frames on the display that we lost touch with.
- If that was the only one, it prints an error message and kills Emacs. */
+/* This is the first-level handler for X protocol errors.
+ It calls x_error_quitter or x_error_catcher. */
static int
-x_io_error_quitter (display)
+x_error_handler (display, error)
Display *display;
+ XErrorEvent *error;
{
- char buf[256];
+ char buf[256], buf1[356];
- sprintf (buf, "Connection lost to X server `%s'", DisplayString (display));
- x_connection_closed (display, buf);
-}
-\f
-/* Handle SIGPIPE, which can happen when the connection to a server
- simply goes away. SIGPIPE is handled by x_connection_signal.
- Don't need to do anything, because the write which caused the
- SIGPIPE will fail, causing Xlib to invoke the X IO error handler,
- which will do the appropriate cleanup for us. */
-
-static SIGTYPE
-x_connection_signal (signalnum) /* If we don't have an argument, */
- int signalnum; /* some compilers complain in signal calls. */
-{
-#ifdef USG
- /* USG systems forget handlers when they are used;
- must reestablish each time */
- signal (signalnum, x_connection_signal);
-#endif /* USG */
+ if (! NILP (x_error_message_string))
+ x_error_catcher (display, error);
+ else
+ x_error_quitter (display, error);
}
-\f
-/* A buffer for storing X error messages. */
-static char *x_caught_error_message;
-#define X_CAUGHT_ERROR_MESSAGE_SIZE 200
-/* An X error handler which stores the error message in
- x_caught_error_message. This is what's installed when
- x_catch_errors is in effect. */
+/* This is the handler for X IO errors, always.
+ It kills all frames on the display that we lost touch with.
+ If that was the only one, it prints an error message and kills Emacs. */
static int
-x_error_catcher (display, error)
+x_io_error_quitter (display)
Display *display;
- XErrorEvent *error;
-{
- XGetErrorText (display, error->error_code,
- x_caught_error_message, X_CAUGHT_ERROR_MESSAGE_SIZE);
-}
-
-
-/* Begin trapping X errors for display DPY. Actually we trap X errors
- for all displays, but DPY should be the display you are actually
- operating on.
-
- After calling this function, X protocol errors no longer cause
- Emacs to exit; instead, they are recorded in x_cfc_error_message.
-
- Calling x_check_errors signals an Emacs error if an X error has
- occurred since the last call to x_catch_errors or x_check_errors.
-
- Calling x_uncatch_errors resumes the normal error handling. */
-
-void x_catch_errors (), x_check_errors (), x_uncatch_errors ();
-
-void
-x_catch_errors (dpy)
- Display *dpy;
-{
- /* Make sure any errors from previous requests have been dealt with. */
- XSync (dpy, False);
-
- /* Set up the error buffer. */
- x_caught_error_message
- = (char*) xmalloc (X_CAUGHT_ERROR_MESSAGE_SIZE);
- x_caught_error_message[0] = '\0';
-
- /* Install our little error handler. */
- XSetErrorHandler (x_error_catcher);
-}
-
-/* If any X protocol errors have arrived since the last call to
- x_catch_errors or x_check_errors, signal an Emacs error using
- sprintf (a buffer, FORMAT, the x error message text) as the text. */
-
-void
-x_check_errors (dpy, format)
- Display *dpy;
- char *format;
-{
- /* Make sure to catch any errors incurred so far. */
- XSync (dpy, False);
-
- if (x_caught_error_message[0])
- {
- char buf[X_CAUGHT_ERROR_MESSAGE_SIZE + 56];
-
- sprintf (buf, format, x_caught_error_message);
- x_uncatch_errors (dpy);
- error (buf);
- }
-}
-
-/* Nonzero if we had any X protocol errors since we did x_catch_errors. */
-
-int
-x_had_errors_p (dpy)
- Display *dpy;
{
- /* Make sure to catch any errors incurred so far. */
- XSync (dpy, False);
-
- return x_caught_error_message[0] != 0;
-}
-
-/* Stop catching X protocol errors and let them make Emacs die. */
-
-void
-x_uncatch_errors (dpy)
- Display *dpy;
-{
- xfree (x_caught_error_message);
- x_caught_error_message = 0;
- XSetErrorHandler (x_error_quitter);
-}
+ char buf[256];
-#if 0
-static unsigned int x_wire_count;
-x_trace_wire ()
-{
- fprintf (stderr, "Lib call: %d\n", ++x_wire_count);
+ sprintf (buf, "Connection lost to X server `%s'", DisplayString (display));
+ x_connection_closed (display, buf);
}
-#endif /* ! 0 */
-
\f
/* Changing the font of the frame. */
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)
if (fontset < 0)
return Qnil;
+ if (f->output_data.x->fontset == fontset)
+ /* This fontset is already set in frame F. There's nothing more
+ to do. */
+ return build_string (fontsetname);
+
fontsetp = FRAME_FONTSET_DATA (f)->fontset_table[fontset];
if (!fontsetp->fontname[CHARSET_ASCII])
/* Since x_new_font doesn't update any fontset information, do it now. */
f->output_data.x->fontset = fontset;
- fs_load_font (f, FRAME_X_FONT_TABLE (f),
+ FS_LOAD_FONT (f, FRAME_X_FONT_TABLE (f),
CHARSET_ASCII, XSTRING (result)->data, fontset);
return build_string (fontsetname);
int flags = f->output_data.x->size_hint_flags;
int this_window;
+ /* We have nothing to do if the current position
+ is already for the top-left corner. */
+ if (! ((flags & XNegative) || (flags & YNegative)))
+ return;
+
#ifdef USE_X_TOOLKIT
this_window = XtWindow (f->output_data.x->widget);
#else
#endif
/* Find the position of the outside upper-left corner of
- the inner window, with respect to the outer window. */
+ the inner window, with respect to the outer window.
+ But do this only if we will need the results. */
if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
{
+ int count;
+
BLOCK_INPUT;
- XTranslateCoordinates (FRAME_X_DISPLAY (f),
+ count = x_catch_errors (FRAME_X_DISPLAY (f));
+ while (1)
+ {
+ x_clear_errors (FRAME_X_DISPLAY (f));
+ XTranslateCoordinates (FRAME_X_DISPLAY (f),
+
+ /* From-window, to-window. */
+ this_window,
+ f->output_data.x->parent_desc,
+
+ /* From-position, to-position. */
+ 0, 0, &win_x, &win_y,
+
+ /* Child of win. */
+ &child);
+ if (x_had_errors_p (FRAME_X_DISPLAY (f)))
+ {
+ Window newroot, newparent = 0xdeadbeef;
+ Window *newchildren;
+ int nchildren;
- /* From-window, to-window. */
- this_window,
- f->output_data.x->parent_desc,
+ if (! XQueryTree (FRAME_X_DISPLAY (f), this_window, &newroot,
+ &newparent, &newchildren, &nchildren))
+ break;
- /* From-position, to-position. */
- 0, 0, &win_x, &win_y,
+ XFree (newchildren);
- /* Child of win. */
- &child);
+ f->output_data.x->parent_desc = newparent;
+ }
+ else
+ break;
+ }
+
+ x_uncatch_errors (FRAME_X_DISPLAY (f), count);
UNBLOCK_INPUT;
}
{
int mask;
Lisp_Object type;
+ int starting_flags = f->output_data.x->size_hint_flags;
+ int original_top, original_left;
BLOCK_INPUT;
{
Lisp_Object frame;
int count = input_signal_count;
+ /* This must be before UNBLOCK_INPUT
+ since events that arrive in response to the actions above
+ will set it when they are handled. */
+ int previously_visible = f->output_data.x->has_been_visible;
+
+ original_left = f->output_data.x->left_pos;
+ original_top = f->output_data.x->top_pos;
/* This must come after we set COUNT. */
UNBLOCK_INPUT;
+ /* Arriving X events are processed here. */
+
+ /* Now move the window back to where it was "supposed to be".
+ But don't do it if the gravity is negative.
+ When the gravity is negative, this uses a position
+ that is 3 pixels too low. Perhaps that's really the border width.
+
+ Don't do this if the window has never been visible before,
+ because the window manager may choose the position
+ and we don't want to override it. */
+
+ if (! FRAME_VISIBLE_P (f) && ! FRAME_ICONIFIED_P (f)
+ && f->output_data.x->win_gravity == NorthWestGravity
+ && previously_visible)
+ {
+ BLOCK_INPUT;
+
+#ifdef USE_X_TOOLKIT
+ XMoveWindow (FRAME_X_DISPLAY (f), XtWindow (f->output_data.x->widget),
+ original_left, original_top);
+#else /* not USE_X_TOOLKIT */
+ XMoveWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ original_left, original_top);
+#endif /* not USE_X_TOOLKIT */
+ UNBLOCK_INPUT;
+ }
+
XSETFRAME (frame, f);
while (1)
/* 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.
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;
int size;
int maxnames;
{
- Lisp_Object list, patterns = Qnil, 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;
- for (list = Valternative_fontname_alist; CONSP (list);
- list = XCONS (list)->cdr)
- {
- tem = XCONS (list)->car;
- if (CONSP (tem)
- && STRINGP (XCONS (tem)->car)
- && !NILP (Fstring_equal (XCONS (tem)->car, pattern)))
- {
- patterns = XCONS (tem)->cdr;
- break;
- }
- }
+ 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 (patterns = Fcons (pattern, patterns); CONSP (patterns);
- patterns = XCONS (patterns)->cdr, pattern = XCONS (patterns)->car)
+ for (; CONSP (patterns); patterns = XCONS (patterns)->cdr)
{
int num_fonts;
char **names;
- /* See if we cached the result for this particular query. */
+ pattern = XCONS (patterns)->car;
+ /* 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))))
if (NILP (Fassoc (tem, list)))
{
if (STRINGP (Vx_pixel_size_width_font_regexp)
- && (fast_string_match_ignore_case
- (Vx_pixel_size_width_font_regexp, names[i])
+ && ((fast_c_string_match_ignore_case
+ (Vx_pixel_size_width_font_regexp, names[i]))
>= 0))
/* We can set the value of PIXEL_SIZE to the
width of this font. */
/* 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))
struct font_info *fontp;
unsigned long value;
+ /* If we have found fonts by x_list_font, load one of them. If
+ not, we still try to load a font by the name given as FONTNAME
+ because XListFonts (called in x_list_font) of some X server has
+ a bug of not finding a font even if the font surely exists and
+ is loadable by XLoadQueryFont. */
if (!NILP (font_names))
- fontname = XSTRING (XCONS (font_names)->car)->data;
+ fontname = (char *) XSTRING (XCONS (font_names)->car)->data;
BLOCK_INPUT;
font = (XFontStruct *) XLoadQueryFont (FRAME_X_DISPLAY (f), fontname);
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))
+ {
+ /* We come here because of a bug of XListFonts mentioned at
+ the head of this block. Let's store this information in
+ the cache for x_list_fonts. */
+ Lisp_Object lispy_name = build_string (fontname);
+ Lisp_Object lispy_full_name = build_string (fontp->full_name);
+
+ XCONS (dpyinfo->name_list_element)->cdr
+ = Fcons (Fcons (Fcons (lispy_name, make_number (256)),
+ Fcons (Fcons (lispy_full_name,
+ make_number (fontp->size)),
+ Qnil)),
+ XCONS (dpyinfo->name_list_element)->cdr);
+ if (full_name)
+ XCONS (dpyinfo->name_list_element)->cdr
+ = Fcons (Fcons (Fcons (lispy_full_name, make_number (256)),
+ Fcons (Fcons (lispy_full_name,
+ make_number (fontp->size)),
+ Qnil)),
+ XCONS (dpyinfo->name_list_element)->cdr);
+ }
/* The slot `encoding' specifies how to map a character
code-points (0x20..0x7F or 0x2020..0x7F7F) of each charset to
- the font code-points (0x20..0x7F, 0xA0..0xFF, 0x2020..0x7F7F,
- 0xA0A0..0xFFFF, 0x20A0..0x7FFF, or 0xA020..0xFF7F). For the
- moment, we don't know which charset uses this font. So, we set
- informatoin in fontp->encoding[1] which is never used by any
- charset. If mapping can't be decided, set -1. */
+ the font code-points (0:0x20..0x7F, 1:0xA0..0xFF, 0:0x2020..0x7F7F,
+ the font code-points (0:0x20..0x7F, 1:0xA0..0xFF,
+ 0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF, or
+ 2:0xA020..0xFF7F). For the moment, we don't know which charset
+ uses this font. So, we set informatoin in fontp->encoding[1]
+ which is never used by any charset. If mapping can't be
+ decided, set FONT_ENCODING_NOT_DECIDED. */
fontp->encoding[1]
= (font->max_byte1 == 0
/* 1-byte font */
? (font->min_char_or_byte2 < 0x80
? (font->max_char_or_byte2 < 0x80
? 0 /* 0x20..0x7F */
- : -1) /* 0x20..0xFF (can't decide) */
+ : FONT_ENCODING_NOT_DECIDED) /* 0x20..0xFF */
: 1) /* 0xA0..0xFF */
/* 2-byte font */
: (font->min_byte1 < 0x80
? (font->min_char_or_byte2 < 0x80
? (font->max_char_or_byte2 < 0x80
? 0 /* 0x2020..0x7F7F */
- : -1) /* 0x2020..0x7FFF (can't decide) */
+ : FONT_ENCODING_NOT_DECIDED) /* 0x2020..0x7FFF */
: 3) /* 0x20A0..0x7FFF */
- : -1) /* 0x20??..0xA0?? (can't decide) */
+ : FONT_ENCODING_NOT_DECIDED) /* 0x20??..0xA0?? */
: (font->min_char_or_byte2 < 0x80
? (font->max_char_or_byte2 < 0x80
? 2 /* 0xA020..0xFF7F */
- : -1) /* 0xA020..0xFFFF (can't decide) */
+ : FONT_ENCODING_NOT_DECIDED) /* 0xA020..0xFFFF */
: 1))); /* 0xA0A0..0xFFFF */
fontp->baseline_offset
#endif /* ! 0 */
dpyinfo->x_id_name
- = (char *) xmalloc (XSTRING (Vinvocation_name)->size
- + XSTRING (Vsystem_name)->size
+ = (char *) xmalloc (XSTRING (Vinvocation_name)->size_byte
+ + XSTRING (Vsystem_name)->size_byte
+ 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. */
{
Display *dpy = dpyinfo->display;
XrmValue d, fr, to;
Font font;
+ int count;
d.addr = (XPointer)&dpy;
d.size = sizeof (Display *);
fr.size = sizeof (XtDefaultFont);
to.size = sizeof (Font *);
to.addr = (XPointer)&font;
- x_catch_errors (dpy);
+ count = x_catch_errors (dpy);
if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL))
abort ();
if (x_had_errors_p (dpy) || !XQueryFont (dpy, font))
XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
- x_uncatch_errors (dpy);
+ x_uncatch_errors (dpy, count);
}
#endif
+#endif
UNBLOCK_INPUT;
/* Note that there is no real way portable across R3/R4 to get the
original error handler. */
- XSetErrorHandler (x_error_quitter);
+ XSetErrorHandler (x_error_handler);
XSetIOErrorHandler (x_io_error_quitter);
/* Disable Window Change signals; they are handled by X events. */
void
syms_of_xterm ()
{
+ staticpro (&x_error_message_string);
+ x_error_message_string = Qnil;
+
staticpro (&x_display_name_list);
x_display_name_list = Qnil;