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 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
#include <sys/ioctl.h>
#endif /* ! defined (BSD_SYSTEM) */
-#include "systty.h"
#include "systime.h"
#ifndef INCLUDED_FCNTL
/* #include <sys/param.h> */
#include "charset.h"
+#include "character.h"
#include "coding.h"
#include "ccl.h"
#include "frame.h"
#include "gtkutil.h"
#endif
+#ifdef USE_FONT_BACKEND
+#include "font.h"
+#endif /* USE_FONT_BACKEND */
+
#ifdef USE_LUCID
extern int xlwmenu_window_p P_ ((Widget w, Window window));
extern void xlwmenu_redisplay P_ ((Widget));
#endif
#endif
-#define abs(x) ((x) < 0 ? -(x) : (x))
-
/* Default to using XIM if available. */
#ifdef USE_XIM
int use_xim = 1;
static Lisp_Object Qvendor_specific_keysyms;
static Lisp_Object Qlatin_1;
+/* Used in x_flush. */
+
+extern Lisp_Object Vinhibit_redisplay;
+
extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *));
extern int x_bitmap_mask P_ ((FRAME_PTR, int));
static void x_update_window_end P_ ((struct window *, int, int));
static int x_io_error_quitter P_ ((Display *));
+static struct terminal *x_create_terminal P_ ((struct x_display_info *));
+void x_delete_terminal P_ ((struct terminal *));
static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
static int x_compute_min_glyph_bounds P_ ((struct frame *));
static void x_update_end P_ ((struct frame *));
static void XTframe_up_to_date P_ ((struct frame *));
-static void XTset_terminal_modes P_ ((void));
-static void XTreset_terminal_modes P_ ((void));
-static void x_clear_frame P_ ((void));
+static void XTset_terminal_modes P_ ((struct terminal *));
+static void XTreset_terminal_modes P_ ((struct terminal *));
+static void x_clear_frame P_ ((struct frame *));
static void frame_highlight P_ ((struct frame *));
static void frame_unhighlight P_ ((struct frame *));
static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
x_flush (f)
struct frame *f;
{
+ /* Don't call XFlush when it is not safe to redisplay; the X
+ connection may be broken. */
+ if (!NILP (Vinhibit_redisplay))
+ return;
+
BLOCK_INPUT;
if (f == NULL)
{
Lisp_Object rest, frame;
FOR_EACH_FRAME (rest, frame)
- x_flush (XFRAME (frame));
+ if (FRAME_X_P (XFRAME (frame)))
+ x_flush (XFRAME (frame));
}
else if (FRAME_X_P (f))
XFlush (FRAME_X_DISPLAY (f));
else
x_clip_to_row (w, row, -1, gc);
- if (p->bx >= 0 && !p->overlay_p)
+ if (!p->overlay_p)
{
+ int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
+
/* In case the same realized face is used for fringes and
for something displayed in the text (e.g. face `region' on
mono-displays, the fill style may have been changed to
else
XSetForeground (display, face->gc, face->background);
- XFillRectangle (display, window, face->gc,
- p->bx, p->by, p->nx, p->ny);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ /* If the fringe is adjacent to the left (right) scroll bar of a
+ leftmost (rightmost, respectively) window, then extend its
+ background to the gap between the fringe and the bar. */
+ if ((WINDOW_LEFTMOST_P (w)
+ && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+ || (WINDOW_RIGHTMOST_P (w)
+ && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
+ {
+ int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
+
+ if (sb_width > 0)
+ {
+ int left = WINDOW_SCROLL_BAR_AREA_X (w);
+ int width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
+ * FRAME_COLUMN_WIDTH (f));
+
+ if (bx < 0)
+ {
+ /* Bitmap fills the fringe. */
+ if (left + width == p->x)
+ bx = left + sb_width;
+ else if (p->x + p->wd == left)
+ bx = left;
+ if (bx >= 0)
+ {
+ int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+
+ nx = width - sb_width;
+ by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
+ row->y));
+ ny = row->visible_height;
+ }
+ }
+ else
+ {
+ if (left + width == bx)
+ {
+ bx = left + sb_width;
+ nx += width - sb_width;
+ }
+ else if (bx + nx == left)
+ nx += width - sb_width;
+ }
+ }
+ }
+#endif
+ if (bx >= 0 && nx > 0)
+ XFillRectangle (display, window, face->gc, bx, by, nx, ny);
if (!face->stipple)
XSetForeground (display, face->gc, face->foreground);
rarely happens). */
static void
-XTset_terminal_modes ()
+XTset_terminal_modes (struct terminal *terminal)
{
}
the X-windows go away, and suspending requires no action. */
static void
-XTreset_terminal_modes ()
+XTreset_terminal_modes (struct terminal *terminal)
{
}
/* Function prototypes of this page. */
-static int x_encode_char P_ ((int, XChar2b *, struct font_info *, int *));
+static int x_encode_char P_ ((int, XChar2b *, struct font_info *,
+ struct charset *, int *));
/* Get metrics of character CHAR2B in FONT. Value is null if CHAR2B
the two-byte form of C. Encoding is returned in *CHAR2B. */
static int
-x_encode_char (c, char2b, font_info, two_byte_p)
+x_encode_char (c, char2b, font_info, charset, two_byte_p)
int c;
XChar2b *char2b;
struct font_info *font_info;
+ struct charset *charset;
int *two_byte_p;
{
- int charset = CHAR_CHARSET (c);
XFontStruct *font = font_info->font;
/* FONT_INFO may define a scheme by which to encode byte1 and byte2.
check_ccl_update (ccl);
if (CHARSET_DIMENSION (charset) == 1)
{
- ccl->reg[0] = charset;
+ ccl->reg[0] = CHARSET_ID (charset);
ccl->reg[1] = char2b->byte2;
ccl->reg[2] = -1;
}
else
{
- ccl->reg[0] = charset;
+ ccl->reg[0] = CHARSET_ID (charset);
ccl->reg[1] = char2b->byte1;
ccl->reg[2] = char2b->byte2;
}
- ccl_driver (ccl, NULL, NULL, 0, 0, NULL);
+ ccl_driver (ccl, NULL, NULL, 0, 0, Qnil);
/* We assume that MSBs are appropriately set/reset by CCL
program. */
if (font->max_byte1 == 0) /* 1-byte font */
- char2b->byte1 = 0, char2b->byte2 = ccl->reg[1];
+ STORE_XCHAR2B (char2b, 0, ccl->reg[1]);
else
- char2b->byte1 = ccl->reg[1], char2b->byte2 = ccl->reg[2];
+ STORE_XCHAR2B (char2b, ccl->reg[1], ccl->reg[2]);
}
- else if (font_info->encoding[charset])
+ else if (font_info->encoding_type)
{
/* Fixed encoding scheme. See fontset.h for the meaning of the
encoding numbers. */
- int enc = font_info->encoding[charset];
+ unsigned char enc = font_info->encoding_type;
if ((enc == 1 || enc == 2)
&& CHARSET_DIMENSION (charset) == 2)
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);
+ face_id = FACE_FOR_CHAR (s->f, face, s->first_glyph->u.ch, -1, Qnil);
else
- face_id = FACE_FOR_CHAR (s->f, face, 0);
+ face_id = FACE_FOR_CHAR (s->f, face, 0, -1, Qnil);
s->face = FACE_FROM_ID (s->f, face_id);
PREPARE_FACE_FOR_DISPLAY (s->f, s->face);
/* If font in this face is same as S->font, use it. */
if (s->font == s->face->font)
s->gc = s->face->gc;
+#ifdef USE_FONT_BACKEND
+ else if (enable_font_backend)
+ /* No need of setting a font for s->gc. */
+ s->gc = s->face->gc;
+#endif /* USE_FONT_BACKEND */
else
{
/* Otherwise construct scratch_cursor_gc with values from FACE
static INLINE void
x_set_glyph_string_clipping (s)
struct glyph_string *s;
+{
+#ifdef USE_FONT_BACKEND
+ XRectangle *r = s->clip;
+#else
+ XRectangle r[2];
+#endif
+ int n = get_glyph_string_clip_rects (s, r, 2);
+
+ if (n > 0)
+ XSetClipRectangles (s->display, s->gc, 0, 0, r, n, Unsorted);
+#ifdef USE_FONT_BACKEND
+ s->num_clips = n;
+#endif
+}
+
+
+/* Set SRC's clipping for output of glyph string DST. This is called
+ when we are drawing DST's left_overhang or right_overhang only in
+ the area of SRC. */
+
+static void
+x_set_glyph_string_clipping_exactly (src, dst)
+ struct glyph_string *src, *dst;
{
XRectangle r;
- get_glyph_string_clip_rect (s, &r);
- XSetClipRectangles (s->display, s->gc, 0, 0, &r, 1, Unsorted);
+
+#ifdef USE_FONT_BACKEND
+ if (enable_font_backend)
+ {
+ r.x = src->x;
+ r.width = src->width;
+ r.y = src->y;
+ r.height = src->height;
+ dst->clip[0] = r;
+ dst->num_clips = 1;
+ }
+ else
+ {
+#endif /* USE_FONT_BACKEND */
+ struct glyph_string *clip_head = src->clip_head;
+ struct glyph_string *clip_tail = src->clip_tail;
+
+ /* This foces clipping just this glyph string. */
+ src->clip_head = src->clip_tail = src;
+ get_glyph_string_clip_rect (src, &r);
+ src->clip_head = clip_head, src->clip_tail = clip_tail;
+#ifdef USE_FONT_BACKEND
+ }
+#endif /* USE_FONT_BACKEND */
+ XSetClipRectangles (dst->display, dst->gc, 0, 0, &r, 1, Unsorted);
}
/* RIF:
- Compute left and right overhang of glyph string S. If S is a glyph
- string for a composition, assume overhangs don't exist. */
+ Compute left and right overhang of glyph string S. */
static void
x_compute_glyph_string_overhangs (s)
{
XCharStruct cs;
int direction, font_ascent, font_descent;
+
+#ifdef USE_FONT_BACKEND
+ if (enable_font_backend)
+ {
+ unsigned *code = alloca (sizeof (unsigned) * s->nchars);
+ struct font *font = (struct font *) s->font_info;
+ struct font_metrics metrics;
+ int i;
+
+ for (i = 0; i < s->nchars; i++)
+ code[i] = (s->char2b[i].byte1 << 8) | s->char2b[i].byte2;
+ font->driver->text_extents (font, code, s->nchars, &metrics);
+ cs.rbearing = metrics.rbearing;
+ cs.lbearing = metrics.lbearing;
+ cs.width = metrics.width;
+ }
+ else
+#endif /* USE_FONT_BACKEND */
XTextExtents16 (s->font, s->char2b, s->nchars, &direction,
&font_ascent, &font_descent, &cs);
s->right_overhang = cs.rbearing > cs.width ? cs.rbearing - cs.width : 0;
s->left_overhang = cs.lbearing < 0 ? -cs.lbearing : 0;
}
+ else if (s->cmp)
+ {
+ s->right_overhang = s->cmp->rbearing - s->cmp->pixel_width;
+ s->left_overhang = - s->cmp->lbearing;
+ }
}
x += g->pixel_width;
}
}
+#ifdef USE_FONT_BACKEND
+ else if (enable_font_backend)
+ {
+ int boff = s->font_info->baseline_offset;
+ struct font *font = (struct font *) s->font_info;
+ int y;
+
+ if (s->font_info->vertical_centering)
+ boff = VCENTER_BASELINE_OFFSET (s->font, s->f) - boff;
+
+ y = s->ybase - boff;
+ if (s->for_overlaps
+ || (s->background_filled_p && s->hl != DRAW_CURSOR))
+ font->driver->draw (s, 0, s->nchars, x, y, 0);
+ else
+ font->driver->draw (s, 0, s->nchars, x, y, 1);
+ if (s->face->overstrike)
+ font->driver->draw (s, 0, s->nchars, x + 1, y, 0);
+ }
+#endif /* USE_FONT_BACKEND */
else
{
char *char1b = (char *) s->char2b;
x_draw_composite_glyph_string_foreground (s)
struct glyph_string *s;
{
- int i, x;
+ int i, j, x;
/* If first glyph of S has a left box line, start drawing the text
of S to the right of that box line. */
- if (s->face->box != FACE_NO_BOX
+ if (s->face && s->face->box != FACE_NO_BOX
&& s->first_glyph->left_box_line_p)
x = s->x + abs (s->face->box_line_width);
else
XDrawRectangle (s->display, s->window, s->gc, x, s->y,
s->width - 1, s->height - 1);
}
- else
+#ifdef USE_FONT_BACKEND
+ else if (enable_font_backend)
{
- for (i = 0; i < s->nchars; i++, ++s->gidx)
+ struct font *font = (struct font *) s->font_info;
+ int y = s->ybase;
+ int width = 0;
+
+ if (s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
{
- XDrawString16 (s->display, s->window, s->gc,
- x + s->cmp->offsets[s->gidx * 2],
- s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
- s->char2b + i, 1);
- if (s->face->overstrike)
- XDrawString16 (s->display, s->window, s->gc,
- x + s->cmp->offsets[s->gidx * 2] + 1,
- s->ybase - s->cmp->offsets[s->gidx * 2 + 1],
- s->char2b + i, 1);
+ Lisp_Object gstring = AREF (XHASH_TABLE (composition_hash_table)
+ ->key_and_value,
+ s->cmp->hash_index * 2);
+ int from;
+
+ for (i = from = 0; i < s->nchars; i++)
+ {
+ Lisp_Object g = LGSTRING_GLYPH (gstring, i);
+ Lisp_Object adjustment = LGLYPH_ADJUSTMENT (g);
+ int xoff, yoff, wadjust;
+
+ if (! VECTORP (adjustment))
+ {
+ width += XINT (LGLYPH_WIDTH (g));
+ continue;
+ }
+ if (from < i)
+ {
+ font->driver->draw (s, from, i, x, y, 0);
+ x += width;
+ }
+ xoff = XINT (AREF (adjustment, 0));
+ yoff = XINT (AREF (adjustment, 1));
+ wadjust = XINT (AREF (adjustment, 2));
+
+ font->driver->draw (s, i, i + 1, x + xoff, y + yoff, 0);
+ x += XINT (LGLYPH_WIDTH (g)) + wadjust;
+ from = i + 1;
+ width = 0;
+ }
+ if (from < i)
+ font->driver->draw (s, from, i, x, y, 0);
+ }
+ else
+ {
+ for (i = 0, j = s->gidx; i < s->nchars; i++, j++)
+ if (COMPOSITION_GLYPH (s->cmp, j) != '\t')
+ {
+ int xx = x + s->cmp->offsets[j * 2];
+ int yy = y - s->cmp->offsets[j * 2 + 1];
+
+ font->driver->draw (s, j, j + 1, xx, yy, 0);
+ if (s->face->overstrike)
+ font->driver->draw (s, j, j + 1, xx + 1, yy, 0);
+ }
}
}
+#endif /* USE_FONT_BACKEND */
+ else
+ {
+ for (i = 0, j = s->gidx; i < s->nchars; i++, j++)
+ if (s->face)
+ {
+ XDrawString16 (s->display, s->window, s->gc,
+ x + s->cmp->offsets[j * 2],
+ s->ybase - s->cmp->offsets[j * 2 + 1],
+ s->char2b + j, 1);
+ if (s->face->overstrike)
+ XDrawString16 (s->display, s->window, s->gc,
+ x + s->cmp->offsets[j * 2] + 1,
+ s->ybase - s->cmp->offsets[j * 2 + 1],
+ s->char2b + j, 1);
+ }
+ }
}
/* Look for a frame with that top-level widget. Allocate the color
on that frame to get the right gamma correction value. */
- for (tail = Vframe_list; GC_CONSP (tail); tail = XCDR (tail))
- if (GC_FRAMEP (XCAR (tail))
+ for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
+ if (FRAMEP (XCAR (tail))
&& (f = XFRAME (XCAR (tail)),
- (f->output_data.nothing != 1
+ (FRAME_X_P (f)
+ && f->output_data.nothing != 1
&& FRAME_X_DISPLAY_INFO (f) == dpyinfo))
&& f->output_data.x->widget == widget)
return f;
{
/* Fill background with a stipple pattern. */
XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
+ XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
XFillRectangle (s->display, pixmap, s->gc,
0, 0, s->background_width, s->height);
XSetFillStyle (s->display, s->gc, FillSolid);
+ XSetTSOrigin (s->display, s->gc, 0, 0);
}
else
{
{
int relief_drawn_p = 0;
- /* If S draws into the background of its successor, draw the
- background of the successor first so that S can draw into it.
+ /* If S draws into the background of its successors, draw the
+ background of the successors first so that S can draw into it.
This makes S->next use XDrawString instead of XDrawImageString. */
if (s->next && s->right_overhang && !s->for_overlaps)
{
- xassert (s->next->img == NULL);
- x_set_glyph_string_gc (s->next);
- x_set_glyph_string_clipping (s->next);
- x_draw_glyph_string_background (s->next, 1);
+ int width;
+ struct glyph_string *next;
+
+ for (width = 0, next = s->next; next;
+ width += next->width, next = next->next)
+ if (next->first_glyph->type != IMAGE_GLYPH)
+ {
+ x_set_glyph_string_gc (next);
+ x_set_glyph_string_clipping (next);
+ x_draw_glyph_string_background (next, 1);
+#ifdef USE_FONT_BACKEND
+ next->num_clips = 0;
+#endif /* USE_FONT_BACKEND */
+ }
}
/* Set up S->gc, set clipping and draw S. */
x_set_glyph_string_clipping (s);
relief_drawn_p = 1;
}
+ else if ((s->prev && s->prev->hl != s->hl && s->left_overhang)
+ || (s->next && s->next->hl != s->hl && s->right_overhang))
+ /* We must clip just this glyph. left_overhang part has already
+ drawn when s->prev was drawn, and right_overhang part will be
+ drawn later when s->next is drawn. */
+ x_set_glyph_string_clipping_exactly (s, s);
else
x_set_glyph_string_clipping (s);
int y;
/* Get the underline thickness. Default is 1 pixel. */
+#ifdef USE_FONT_BACKEND
+ if (enable_font_backend)
+ /* In the future, we must use information of font. */
+ h = 1;
+ else
+#endif /* USE_FONT_BACKEND */
if (!XGetFontProperty (s->font, XA_UNDERLINE_THICKNESS, &h))
h = 1;
- y = s->y + s->height - h;
- if (!x_underline_at_descent_line)
- {
- /* Get the underline position. This is the recommended
- vertical offset in pixels from the baseline to the top of
- the underline. This is a signed value according to the
- specs, and its default is
-
- ROUND ((maximum descent) / 2), with
- ROUND(x) = floor (x + 0.5) */
-
- if (x_use_underline_position_properties
- && XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem))
- y = s->ybase + (long) tem;
- else if (s->face->font)
- y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
- }
+#ifdef USE_FONT_BACKEND
+ if (enable_font_backend)
+ {
+ if (s->face->font)
+ /* In the future, we must use information of font. */
+ y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
+ else
+ y = s->y + s->height - h;
+ }
+ else
+#endif
+ {
+ y = s->y + s->height - h;
+ if (!x_underline_at_descent_line)
+ {
+ /* Get the underline position. This is the recommended
+ vertical offset in pixels from the baseline to the top of
+ the underline. This is a signed value according to the
+ specs, and its default is
+
+ ROUND ((maximum descent) / 2), with
+ ROUND(x) = floor (x + 0.5) */
+
+ if (x_use_underline_position_properties
+ && XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem))
+ y = s->ybase + (long) tem;
+ else if (s->face->font)
+ y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
+ }
+ }
if (s->face->underline_defaulted_p)
XFillRectangle (s->display, s->window, s->gc,
/* Draw relief if not yet drawn. */
if (!relief_drawn_p && s->face->box != FACE_NO_BOX)
x_draw_glyph_string_box (s);
+
+ if (s->prev)
+ {
+ struct glyph_string *prev;
+
+ for (prev = s->prev; prev; prev = prev->prev)
+ if (prev->hl != s->hl
+ && prev->x + prev->width + prev->right_overhang > s->x)
+ {
+ /* As prev was drawn while clipped to its own area, we
+ must draw the right_overhang part using s->hl now. */
+ enum draw_glyphs_face save = prev->hl;
+
+ prev->hl = s->hl;
+ x_set_glyph_string_gc (prev);
+ x_set_glyph_string_clipping_exactly (s, prev);
+ if (prev->first_glyph->type == CHAR_GLYPH)
+ x_draw_glyph_string_foreground (prev);
+ else
+ x_draw_composite_glyph_string_foreground (prev);
+ XSetClipMask (prev->display, prev->gc, None);
+ prev->hl = save;
+#ifdef USE_FONT_BACKEND
+ prev->num_clips = 0;
+#endif /* USE_FONT_BACKEND */
+ }
+ }
+
+ if (s->next)
+ {
+ struct glyph_string *next;
+
+ for (next = s->next; next; next = next->next)
+ if (next->hl != s->hl
+ && next->x - next->left_overhang < s->x + s->width)
+ {
+ /* As next will be drawn while clipped to its own area,
+ we must draw the left_overhang part using s->hl now. */
+ enum draw_glyphs_face save = next->hl;
+
+ next->hl = s->hl;
+ x_set_glyph_string_gc (next);
+ x_set_glyph_string_clipping_exactly (s, next);
+ if (next->first_glyph->type == CHAR_GLYPH)
+ x_draw_glyph_string_foreground (next);
+ else
+ x_draw_composite_glyph_string_foreground (next);
+ XSetClipMask (next->display, next->gc, None);
+ next->hl = save;
+#ifdef USE_FONT_BACKEND
+ next->num_clips = 0;
+#endif /* USE_FONT_BACKEND */
+ }
+ }
}
/* Reset clipping. */
XSetClipMask (s->display, s->gc, None);
+#ifdef USE_FONT_BACKEND
+ s->num_clips = 0;
+#endif /* USE_FONT_BACKEND */
}
/* Shift display to make room for inserted glyphs. */
for X frames. */
static void
-x_delete_glyphs (n)
+x_delete_glyphs (f, n)
+ struct frame *f;
register int n;
{
abort ();
}
-/* Clear entire frame. If updating_frame is non-null, clear that
- frame. Otherwise clear the selected frame. */
+/* Clear an entire frame. */
static void
-x_clear_frame ()
+x_clear_frame (struct frame *f)
{
- struct frame *f;
-
- if (updating_frame)
- f = updating_frame;
- else
- f = SELECTED_FRAME ();
-
/* Clearing the frame will erase any cursor, so mark them all as no
longer visible. */
mark_window_cursors_off (XWINDOW (FRAME_ROOT_WINDOW (f)));
XGCValues values;
values.function = GXxor;
- values.foreground = (f->output_data.x->foreground_pixel
- ^ f->output_data.x->background_pixel);
+ values.foreground = (FRAME_FOREGROUND_PIXEL (f)
+ ^ FRAME_BACKGROUND_PIXEL (f));
gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
GCFunction | GCForeground, &values);
lines or deleting -N lines at vertical position VPOS. */
static void
-x_ins_del_lines (vpos, n)
+x_ins_del_lines (f, vpos, n)
+ struct frame *f;
int vpos, n;
{
abort ();
/* Don't stop displaying the initial startup message
for a switch-frame event we don't need. */
- if (GC_NILP (Vterminal_frame)
- && GC_CONSP (Vframe_list)
- && !GC_NILP (XCDR (Vframe_list)))
+ if (NILP (Vterminal_frame)
+ && CONSP (Vframe_list)
+ && !NILP (XCDR (Vframe_list)))
{
bufp->kind = FOCUS_IN_EVENT;
XSETFRAME (bufp->frame_or_window, frame);
if (dpyinfo->x_focus_frame)
{
dpyinfo->x_highlight_frame
- = ((GC_FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
+ = ((FRAMEP (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame)))
? XFRAME (FRAME_FOCUS_FRAME (dpyinfo->x_focus_frame))
: dpyinfo->x_focus_frame);
if (! FRAME_LIVE_P (dpyinfo->x_highlight_frame))
/* Clear the mouse-moved flag for every frame on this display. */
FOR_EACH_FRAME (tail, frame)
- if (FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
+ if (FRAME_X_P (XFRAME (frame))
+ && FRAME_X_DISPLAY (XFRAME (frame)) == FRAME_X_DISPLAY (*fp))
XFRAME (frame)->mouse_moved = 0;
last_mouse_scroll_bar = Qnil;
window_id = (Window) xg_get_scroll_id_for_window (display, window_id);
#endif /* USE_GTK && USE_TOOLKIT_SCROLL_BARS */
- for (tail = Vframe_list;
- XGCTYPE (tail) == Lisp_Cons;
- tail = XCDR (tail))
+ for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
{
Lisp_Object frame, bar, condemned;
frame = XCAR (tail);
/* All elements of Vframe_list should be frames. */
- if (! GC_FRAMEP (frame))
+ if (! FRAMEP (frame))
abort ();
+ if (! FRAME_X_P (XFRAME (frame)))
+ continue;
+
/* Scan this frame's scroll bar list for a scroll bar with the
right window ID. */
condemned = FRAME_CONDEMNED_SCROLL_BARS (XFRAME (frame));
for (bar = FRAME_SCROLL_BARS (XFRAME (frame));
/* This trick allows us to search both the ordinary and
condemned scroll bar lists with one loop. */
- ! GC_NILP (bar) || (bar = condemned,
+ ! NILP (bar) || (bar = condemned,
condemned = Qnil,
- ! GC_NILP (bar));
+ ! NILP (bar));
bar = XSCROLL_BAR (bar)->next)
if (SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)) == window_id &&
FRAME_X_DISPLAY (XFRAME (frame)) == display)
{
Lisp_Object tail;
- for (tail = Vframe_list;
- XGCTYPE (tail) == Lisp_Cons;
- tail = XCDR (tail))
+ for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
{
- Lisp_Object frame = XCAR (tail);
- Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
+ if (FRAME_X_P (XFRAME (XCAR (tail))))
+ {
+ Lisp_Object frame = XCAR (tail);
+ Widget menu_bar = XFRAME (frame)->output_data.x->menubar_widget;
- if (menu_bar && xlwmenu_window_p (menu_bar, window))
- return menu_bar;
+ if (menu_bar && xlwmenu_window_p (menu_bar, window))
+ return menu_bar;
+ }
}
return NULL;
a.background_pixel = f->output_data.x->scroll_bar_background_pixel;
if (a.background_pixel == -1)
- a.background_pixel = f->output_data.x->background_pixel;
+ a.background_pixel = FRAME_BACKGROUND_PIXEL (f);
a.event_mask = (ButtonPressMask | ButtonReleaseMask
| ButtonMotionMask | PointerMotionHintMask
XSETINT (bar->start, 0);
XSETINT (bar->end, 0);
bar->dragging = Qnil;
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ bar->fringe_extended_p = Qnil;
+#endif
/* Add bar to its frame's list of scroll bars. */
bar->next = FRAME_SCROLL_BARS (f);
/* Restore the foreground color of the GC if we changed it above. */
if (f->output_data.x->scroll_bar_foreground_pixel != -1)
XSetForeground (FRAME_X_DISPLAY (f), gc,
- f->output_data.x->foreground_pixel);
+ FRAME_FOREGROUND_PIXEL (f));
/* Draw the empty space below the handle. Note that we can't
clear zero-height areas; that means "clear to end of window." */
struct scroll_bar *bar;
int top, height, left, sb_left, width, sb_width;
int window_y, window_height;
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ int fringe_extended_p;
+#endif
/* Get window dimensions. */
window_box (w, -1, 0, &window_y, 0, &window_height);
/* Compute the left edge of the scroll bar. */
#ifdef USE_TOOLKIT_SCROLL_BARS
if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
- sb_left = (left +
- (WINDOW_RIGHTMOST_P (w)
- ? width - sb_width - (width - sb_width) / 2
- : 0));
+ sb_left = left + (WINDOW_RIGHTMOST_P (w) ? width - sb_width : 0);
else
- sb_left = (left +
- (WINDOW_LEFTMOST_P (w)
- ? (width - sb_width) / 2
- : width - sb_width));
+ sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
#else
if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
sb_left = left + width - sb_width;
sb_left = left;
#endif
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+ fringe_extended_p = (WINDOW_LEFTMOST_P (w)
+ && WINDOW_LEFT_FRINGE_WIDTH (w)
+ && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ || WINDOW_LEFT_MARGIN_COLS (w) == 0));
+ else
+ fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
+ && WINDOW_RIGHT_FRINGE_WIDTH (w)
+ && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
+#endif
+
/* Does the scroll bar exist yet? */
if (NILP (w->vertical_scroll_bar))
{
if (width > 0 && height > 0)
{
BLOCK_INPUT;
- x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- left, top, width, height, False);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ if (fringe_extended_p)
+ x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ sb_left, top, sb_width, height, False);
+ else
+#endif
+ x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ left, top, width, height, False);
UNBLOCK_INPUT;
}
#ifdef USE_TOOLKIT_SCROLL_BARS
/* Move/size the scroll bar widget. */
- if (mask)
+ if (mask || !NILP (bar->fringe_extended_p) != fringe_extended_p)
{
/* Since toolkit scroll bars are smaller than the space reserved
for them on the frame, we have to clear "under" them. */
if (width > 0 && height > 0)
- x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- left, top, width, height, False);
+ {
+ if (fringe_extended_p)
+ x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ sb_left, top, sb_width, height, False);
+ else
+ x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ left, top, width, height, False);
+ }
#ifdef USE_GTK
xg_update_scrollbar_pos (f,
SCROLL_BAR_X_WINDOW (bar),
}
#ifdef USE_TOOLKIT_SCROLL_BARS
+ bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
+
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
/* Restore the foreground color of the GC if we changed it above. */
if (f->output_data.x->scroll_bar_foreground_pixel != -1)
XSetForeground (FRAME_X_DISPLAY (f), gc,
- f->output_data.x->foreground_pixel);
+ FRAME_FOREGROUND_PIXEL (f));
UNBLOCK_INPUT;
XEvent *event;
struct input_event *emacs_event;
{
- if (! GC_WINDOWP (bar->window))
+ if (! WINDOWP (bar->window))
abort ();
emacs_event->kind = SCROLL_BAR_CLICK_EVENT;
XSETVECTOR (last_mouse_scroll_bar, bar);
/* If we're dragging the bar, display it. */
- if (! GC_NILP (bar->dragging))
+ if (! NILP (bar->dragging))
{
/* Where should the handle be now? */
int new_start = event->xmotion.y - XINT (bar->dragging);
int count = 0;
int do_help = 0;
int nbytes = 0;
- struct frame *f;
+ struct frame *f = NULL;
struct coding_system coding;
XEvent event = *eventp;
bzero (&compose_status, sizeof (compose_status));
orig_keysym = keysym;
- /* Common for all keysym input events. */
- XSETFRAME (inev.ie.frame_or_window, f);
- inev.ie.modifiers
- = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
- inev.ie.timestamp = event.xkey.time;
-
- /* First deal with keysyms which have defined
- translations to characters. */
- if (keysym >= 32 && keysym < 128)
- /* Avoid explicitly decoding each ASCII character. */
- {
- inev.ie.kind = ASCII_KEYSTROKE_EVENT;
- inev.ie.code = keysym;
+ /* Common for all keysym input events. */
+ XSETFRAME (inev.ie.frame_or_window, f);
+ inev.ie.modifiers
+ = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
+ inev.ie.timestamp = event.xkey.time;
+
+ /* First deal with keysyms which have defined
+ translations to characters. */
+ if (keysym >= 32 && keysym < 128)
+ /* Avoid explicitly decoding each ASCII character. */
+ {
+ inev.ie.kind = ASCII_KEYSTROKE_EVENT;
+ inev.ie.code = keysym;
goto done_keysym;
}
- /* Keysyms directly mapped to supported Unicode characters. */
- if ((keysym >= 0x01000000 && keysym <= 0x010033ff)
- || (keysym >= 0x0100e000 && keysym <= 0x0100ffff))
+ /* Keysyms directly mapped to Unicode characters. */
+ if (keysym >= 0x01000000 && keysym <= 0x0110FFFF)
{
- int code = keysym & 0xFFFF, charset_id, c1, c2;
-
- if (code < 0x80)
- {
- inev.ie.kind = ASCII_KEYSTROKE_EVENT;
- inev.ie.code = code;
- }
- else if (code < 0x100)
- {
- if (code < 0xA0)
- charset_id = CHARSET_8_BIT_CONTROL;
- else
- charset_id = charset_latin_iso8859_1;
- inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
- inev.ie.code = MAKE_CHAR (charset_id, code, 0);
- }
+ if (keysym < 0x01000080)
+ inev.ie.kind = ASCII_KEYSTROKE_EVENT;
else
- {
- if (code < 0x2500)
- charset_id = charset_mule_unicode_0100_24ff,
- code -= 0x100;
- else if (code < 0xE000)
- charset_id = charset_mule_unicode_2500_33ff,
- code -= 0x2500;
- else
- charset_id = charset_mule_unicode_e000_ffff,
- code -= 0xE000;
- c1 = (code / 96) + 32, c2 = (code % 96) + 32;
- inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
- inev.ie.code = MAKE_CHAR (charset_id, c1, c2);
- }
+ inev.ie.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+ inev.ie.code = keysym & 0xFFFFFF;
goto done_keysym;
}
/* Now non-ASCII. */
if (HASH_TABLE_P (Vx_keysym_table)
&& (NATNUMP (c = Fgethash (make_number (keysym),
- Vx_keysym_table,
- Qnil))))
- {
- inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
- ? ASCII_KEYSTROKE_EVENT
- : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
- inev.ie.code = XFASTINT (c);
- goto done_keysym;
- }
-
- /* Random non-modifier sorts of keysyms. */
- if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
+ Vx_keysym_table,
+ Qnil))))
+ {
+ inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ inev.ie.code = XFASTINT (c);
+ goto done_keysym;
+ }
+
+ /* Random non-modifier sorts of keysyms. */
+ if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
|| keysym == XK_Delete
#ifdef XK_ISO_Left_Tab
|| (keysym >= XK_ISO_Left_Tab
register int c;
int nchars, len;
- /* The input should be decoded with `coding_system'
- which depends on which X*LookupString function
- we used just above and the locale. */
- setup_coding_system (coding_system, &coding);
- coding.src_multibyte = 0;
- coding.dst_multibyte = 1;
- /* The input is converted to events, thus we can't
- handle composition. Anyway, there's no XIM that
- gives us composition information. */
- coding.composing = COMPOSITION_DISABLED;
-
- for (i = 0; i < nbytes; i++)
+ for (i = 0, nchars = 0; i < nbytes; i++)
{
+ if (ASCII_BYTE_P (copy_bufptr[i]))
+ nchars++;
STORE_KEYSYM_FOR_DEBUG (copy_bufptr[i]);
}
- {
- /* Decode the input data. */
- int require;
- unsigned char *p;
-
- require = decoding_buffer_size (&coding, nbytes);
- p = (unsigned char *) alloca (require);
- coding.mode |= CODING_MODE_LAST_BLOCK;
- /* We explicitly disable composition handling because
- key data should not contain any composition sequence. */
- coding.composing = COMPOSITION_DISABLED;
- decode_coding (&coding, copy_bufptr, p, nbytes, require);
- nbytes = coding.produced;
- nchars = coding.produced_char;
- copy_bufptr = p;
- }
+ if (nchars < nbytes)
+ {
+ /* Decode the input data. */
+ int require;
+ unsigned char *p;
+
+ /* The input should be decoded with `coding_system'
+ which depends on which X*LookupString function
+ we used just above and the locale. */
+ setup_coding_system (coding_system, &coding);
+ coding.src_multibyte = 0;
+ coding.dst_multibyte = 1;
+ /* The input is converted to events, thus we can't
+ handle composition. Anyway, there's no XIM that
+ gives us composition information. */
+ coding.common_flags &= ~CODING_ANNOTATION_MASK;
+
+ require = MAX_MULTIBYTE_LENGTH * nbytes;
+ coding.destination = alloca (require);
+ coding.dst_bytes = require;
+ coding.mode |= CODING_MODE_LAST_BLOCK;
+ decode_coding_c_string (&coding, copy_bufptr, nbytes, Qnil);
+ nbytes = coding.produced;
+ nchars = coding.produced_char;
+ copy_bufptr = coding.destination;
+ }
/* Convert the input data to a sequence of
character events. */
c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
nbytes - i, len);
inev.ie.kind = (SINGLE_BYTE_CHAR_P (c)
- ? ASCII_KEYSTROKE_EVENT
- : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
inev.ie.code = c;
kbd_buffer_store_event_hold (&inev.ie, hold_quit);
}
/* We may get an EnterNotify on the buttons in the toolbar. In that
case we moved out of any highlighted area and need to note this. */
if (!f && last_mouse_glyph_frame)
- note_mouse_movement (last_mouse_glyph_frame, &event);
+ note_mouse_movement (last_mouse_glyph_frame, &event.xmotion);
#endif
goto OTHER;
#ifdef USE_GTK
/* See comment in EnterNotify above */
else if (last_mouse_glyph_frame)
- note_mouse_movement (last_mouse_glyph_frame, &event);
+ note_mouse_movement (last_mouse_glyph_frame, &event.xmotion);
#endif
goto OTHER;
/* Window will be selected only when it is not selected now and
last mouse movement event was not in it. Minibuffer window
- will be selected iff it is active. */
+ will be selected only when it is active. */
if (WINDOWP (window)
&& !EQ (window, last_window)
- && !EQ (window, selected_window))
+ && !EQ (window, selected_window)
+ /* For click-to-focus window managers
+ create event iff we don't leave the
+ selected frame. */
+ && (focus_follows_mouse
+ || (EQ (XWINDOW (window)->frame,
+ XWINDOW (selected_window)->frame))))
{
inev.ie.kind = SELECT_WINDOW_EVENT;
inev.ie.frame_or_window = window;
}
if (!tool_bar_p)
- if (!dpyinfo->x_focus_frame
- || f == dpyinfo->x_focus_frame)
- {
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
- if (! popup_activated ())
+ if (! popup_activated ())
#endif
- {
- if (ignore_next_mouse_click_timeout)
- {
- if (event.type == ButtonPress
- && (int)(event.xbutton.time - ignore_next_mouse_click_timeout) > 0)
- {
- ignore_next_mouse_click_timeout = 0;
- construct_mouse_click (&inev.ie, &event.xbutton, f);
- }
- if (event.type == ButtonRelease)
- ignore_next_mouse_click_timeout = 0;
- }
- else
- construct_mouse_click (&inev.ie, &event.xbutton, f);
- }
+ {
+ if (ignore_next_mouse_click_timeout)
+ {
+ if (event.type == ButtonPress
+ && (int)(event.xbutton.time - ignore_next_mouse_click_timeout) > 0)
+ {
+ ignore_next_mouse_click_timeout = 0;
+ construct_mouse_click (&inev.ie, &event.xbutton, f);
+ }
+ if (event.type == ButtonRelease)
+ ignore_next_mouse_click_timeout = 0;
+ }
+ else
+ construct_mouse_click (&inev.ie, &event.xbutton, f);
}
}
else
EXPECTED is nonzero if the caller knows input is available. */
static int
-XTread_socket (sd, expected, hold_quit)
- register int sd;
+XTread_socket (terminal, expected, hold_quit)
+ struct terminal *terminal;
int expected;
struct input_event *hold_quit;
{
++handling_signal;
+#ifdef HAVE_X_SM
+ /* Only check session manager input for the primary display. */
+ if (terminal->id == 1 && x_session_have_connection ())
+ {
+ struct input_event inev;
+ BLOCK_INPUT;
+ /* We don't need to EVENT_INIT (inev) here, as
+ x_session_check_input copies an entire input_event. */
+ if (x_session_check_input (&inev))
+ {
+ kbd_buffer_store_event_hold (&inev, hold_quit);
+ count++;
+ }
+ UNBLOCK_INPUT;
+ }
+#endif
+
+ /* For debugging, this gives a way to fake an I/O error. */
+ if (terminal->display_info.x == XTread_socket_fake_io_error)
+ {
+ XTread_socket_fake_io_error = 0;
+ x_io_error_quitter (dpyinfo->display);
+ }
+
+#if 0 /* This loop is a noop now. */
/* Find the display we are supposed to read input for.
It's the one communicating on descriptor SD. */
for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
#endif /* HAVE_SELECT */
#endif /* SIGIO */
#endif
-
- /* For debugging, this gives a way to fake an I/O error. */
- if (dpyinfo == XTread_socket_fake_io_error)
- {
- XTread_socket_fake_io_error = 0;
- x_io_error_quitter (dpyinfo->display);
- }
-
-#ifdef HAVE_X_SM
- {
- struct input_event inev;
- BLOCK_INPUT;
- /* We don't need to EVENT_INIT (inev) here, as
- x_session_check_input copies an entire input_event. */
- if (x_session_check_input (&inev))
- {
- kbd_buffer_store_event_hold (&inev, hold_quit);
- count++;
- }
- UNBLOCK_INPUT;
- }
+ }
#endif
#ifndef USE_GTK
- while (XPending (dpyinfo->display))
- {
- int finish;
+ while (XPending (terminal->display_info.x->display))
+ {
+ int finish;
- XNextEvent (dpyinfo->display, &event);
+ XNextEvent (terminal->display_info.x->display, &event);
#ifdef HAVE_X_I18N
- /* Filter events for the current X input method. */
- if (x_filter_event (dpyinfo, &event))
- break;
+ /* Filter events for the current X input method. */
+ if (x_filter_event (terminal->display_info.x, &event))
+ break;
#endif
- event_found = 1;
+ event_found = 1;
- count += handle_one_xevent (dpyinfo, &event, &finish, hold_quit);
+ count += handle_one_xevent (terminal->display_info.x,
+ &event, &finish, hold_quit);
- if (finish == X_EVENT_GOTO_OUT)
- goto out;
- }
-#endif /* not USE_GTK */
+ if (finish == X_EVENT_GOTO_OUT)
+ goto out;
}
-#ifdef USE_GTK
+#else /* USE_GTK */
/* For GTK we must use the GTK event loop. But XEvents gets passed
to our filter function above, and then to the big event switch.
}
#ifndef XFlush
- if (updating_frame != f)
- XFlush (FRAME_X_DISPLAY (f));
+ XFlush (FRAME_X_DISPLAY (f));
#endif
}
x_error_message->string[0] = 0;
}
+#if 0 /* See comment in unwind_to_catch why calling this is a bad
+ * idea. --lorentey */
/* Close off all unclosed x_catch_errors calls. */
void
while (x_error_message)
x_uncatch_errors ();
}
+#endif
/* Nonzero if x_catch_errors has been done and not yet canceled. */
{
struct x_display_info *dpyinfo = x_display_info_for_display (dpy);
Lisp_Object frame, tail;
+ int index = SPECPDL_INDEX ();
error_msg = (char *) alloca (strlen (error_message) + 1);
strcpy (error_msg, error_message);
the original message here. */
x_catch_errors (dpy);
+ /* Inhibit redisplay while frames are being deleted. */
+ specbind (Qinhibit_redisplay, Qt);
+
+ if (dpyinfo)
+ {
+ /* Protect display from being closed when we delete the last
+ frame on it. */
+ dpyinfo->reference_count++;
+ dpyinfo->terminal->reference_count++;
+ }
+
+ /* First delete frames whose mini-buffers are on frames
+ that are on the dead display. */
+ FOR_EACH_FRAME (tail, frame)
+ {
+ Lisp_Object minibuf_frame;
+ minibuf_frame
+ = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame))));
+ if (FRAME_X_P (XFRAME (frame))
+ && FRAME_X_P (XFRAME (minibuf_frame))
+ && ! EQ (frame, minibuf_frame)
+ && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo)
+ Fdelete_frame (frame, Qt);
+ }
+
+ /* Now delete all remaining frames on the dead display.
+ We are now sure none of these is used as the mini-buffer
+ for another frame that we need to delete. */
+ FOR_EACH_FRAME (tail, frame)
+ if (FRAME_X_P (XFRAME (frame))
+ && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
+ {
+ /* Set this to t so that Fdelete_frame won't get confused
+ trying to find a replacement. */
+ FRAME_KBOARD (XFRAME (frame))->Vdefault_minibuffer_frame = Qt;
+ Fdelete_frame (frame, Qt);
+ }
+
/* 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
xg_display_close (dpyinfo->display);
#endif
- /* Indicate that this display is dead. */
if (dpyinfo)
- dpyinfo->display = 0;
-
- /* First delete frames whose mini-buffers are on frames
- that are on the dead display. */
- FOR_EACH_FRAME (tail, frame)
{
- Lisp_Object minibuf_frame;
- minibuf_frame
- = WINDOW_FRAME (XWINDOW (FRAME_MINIBUF_WINDOW (XFRAME (frame))));
- if (FRAME_X_P (XFRAME (frame))
- && FRAME_X_P (XFRAME (minibuf_frame))
- && ! EQ (frame, minibuf_frame)
- && FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo)
- Fdelete_frame (frame, Qt);
- }
+ /* Indicate that this display is dead. */
+ dpyinfo->display = 0;
- /* Now delete all remaining frames on the dead display.
- We are now sure none of these is used as the mini-buffer
- for another frame that we need to delete. */
- FOR_EACH_FRAME (tail, frame)
- if (FRAME_X_P (XFRAME (frame))
- && FRAME_X_DISPLAY_INFO (XFRAME (frame)) == dpyinfo)
- {
- /* Set this to t so that Fdelete_frame won't get confused
- trying to find a replacement. */
- FRAME_KBOARD (XFRAME (frame))->Vdefault_minibuffer_frame = Qt;
- Fdelete_frame (frame, Qt);
- }
+ dpyinfo->reference_count--;
+ dpyinfo->terminal->reference_count--;
+ if (dpyinfo->reference_count != 0)
+ /* We have just closed all frames on this display. */
+ abort ();
- if (dpyinfo)
- x_delete_display (dpyinfo);
+ x_delete_display (dpyinfo);
+ }
x_uncatch_errors ();
- if (x_display_list == 0)
+ if (terminal_list == 0)
{
fprintf (stderr, "%s\n", error_msg);
shut_down_emacs (0, 0, Qnil);
sigunblock (sigmask (SIGALRM));
TOTALLY_UNBLOCK_INPUT;
+ unbind_to (index, Qnil);
clear_waiting_for_input ();
error ("%s", error_msg);
}
register char *fontname;
{
struct font_info *fontp
- = FS_LOAD_FONT (f, 0, fontname, -1);
+ = FS_LOAD_FONT (f, fontname);
if (!fontp)
return Qnil;
+ if (FRAME_FONT (f) == (XFontStruct *) (fontp->font))
+ /* This font is already set in frame F. There's nothing more to
+ do. */
+ return build_string (fontp->full_name);
+
FRAME_FONT (f) = (XFontStruct *) (fontp->font);
FRAME_BASELINE_OFFSET (f) = fontp->baseline_offset;
FRAME_FONTSET (f) = -1;
return build_string (fontp->full_name);
}
-/* Give frame F the fontset named FONTSETNAME as its default font, and
- return the full name of that fontset. FONTSETNAME may be a wildcard
- pattern; in that case, we choose some fontset that fits the pattern.
- The return value shows which fontset we chose. */
+/* Give frame F the fontset named FONTSETNAME as its default fontset,
+ and return the full name of that fontset. FONTSETNAME may be a
+ wildcard pattern; in that case, we choose some fontset that fits
+ the pattern. FONTSETNAME may be a font name for ASCII characters;
+ in that case, we create a fontset from that font name.
+
+ The return value shows which fontset we chose.
+ If FONTSETNAME specifies the default fontset, return Qt.
+ If an ASCII font in the specified fontset can't be loaded, return
+ Qnil. */
Lisp_Object
x_new_fontset (f, fontsetname)
struct frame *f;
- char *fontsetname;
+ Lisp_Object fontsetname;
{
- int fontset = fs_query_fontset (build_string (fontsetname), 0);
+ int fontset = fs_query_fontset (fontsetname, 0);
Lisp_Object result;
- if (fontset < 0)
- return Qnil;
-
- if (FRAME_FONTSET (f) == fontset)
+ if (fontset > 0 && f->output_data.x->fontset == fontset)
/* This fontset is already set in frame F. There's nothing more
to do. */
return fontset_name (fontset);
+ else if (fontset == 0)
+ /* The default fontset can't be the default font. */
+ return Qt;
- result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
+ if (fontset > 0)
+ result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
+ else
+ result = x_new_font (f, SDATA (fontsetname));
if (!STRINGP (result))
/* Can't load ASCII font. */
return Qnil;
+ if (fontset < 0)
+ fontset = new_fontset_from_font_name (result);
+
/* Since x_new_font doesn't update any fontset information, do it now. */
FRAME_FONTSET (f) = fontset;
xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
#endif
- return build_string (fontsetname);
+ return fontset_name (fontset);
+}
+
+#ifdef USE_FONT_BACKEND
+Lisp_Object
+x_new_fontset2 (f, fontset, font_object)
+ struct frame *f;
+ int fontset;
+ Lisp_Object font_object;
+{
+ struct font *font = XSAVE_VALUE (font_object)->pointer;
+
+ if (FRAME_FONT_OBJECT (f) == font)
+ /* This font is already set in frame F. There's nothing more to
+ do. */
+ return fontset_name (fontset);
+
+ BLOCK_INPUT;
+
+ FRAME_FONT_OBJECT (f) = font;
+ FRAME_FONT (f) = font->font.font;
+ FRAME_BASELINE_OFFSET (f) = font->font.baseline_offset;
+ FRAME_FONTSET (f) = fontset;
+
+ FRAME_COLUMN_WIDTH (f) = font->font.average_width;
+ FRAME_SPACE_WIDTH (f) = font->font.space_width;
+ FRAME_LINE_HEIGHT (f) = font->font.height;
+
+ compute_fringe_widths (f, 1);
+
+ /* Compute the scroll bar width in character columns. */
+ if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
+ {
+ int wid = FRAME_COLUMN_WIDTH (f);
+ FRAME_CONFIG_SCROLL_BAR_COLS (f)
+ = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + wid - 1) / wid;
+ }
+ else
+ {
+ int wid = FRAME_COLUMN_WIDTH (f);
+ FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + wid - 1) / wid;
+ }
+
+ /* Now make the frame display the given font. */
+ if (FRAME_X_WINDOW (f) != 0)
+ {
+ /* 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, FRAME_COLS (f), FRAME_LINES (f));
+ }
+
+#ifdef HAVE_X_I18N
+ if (FRAME_XIC (f)
+ && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
+ xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
+#endif
+
+ UNBLOCK_INPUT;
+
+ return fontset_name (fontset);
}
+#endif /* USE_FONT_BACKEND */
\f
/***********************************************************************
FOR_EACH_FRAME (tail, frame)
{
struct frame *f = XFRAME (frame);
- if (FRAME_X_DISPLAY_INFO (f) == dpyinfo)
+ if (FRAME_X_P (f) && FRAME_X_DISPLAY_INFO (f) == dpyinfo)
{
FRAME_XIC (f) = NULL;
xic_free_xfontset (f);
{
struct frame *f = XFRAME (frame);
- if (FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo)
+ if (FRAME_X_P (f)
+ && FRAME_X_DISPLAY_INFO (f) == xim_inst->dpyinfo)
if (FRAME_XIC (f) == NULL)
{
create_frame_xic (f);
commands to the X server. */
if (dpyinfo->display)
{
+#ifdef USE_FONT_BACKEND
+ /* We must free faces before destroying windows because some
+ font-driver (e.g. xft) access a window while finishing a
+ face. */
+ if (enable_font_backend
+ && FRAME_FACE_CACHE (f))
+ free_frame_faces (f);
+#endif /* USE_FONT_BACKEND */
+
if (f->output_data.x->icon_desc)
XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc);
XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
#endif /* !USE_X_TOOLKIT */
- unload_color (f, f->output_data.x->foreground_pixel);
- unload_color (f, f->output_data.x->background_pixel);
+ unload_color (f, FRAME_FOREGROUND_PIXEL (f));
+ unload_color (f, FRAME_BACKGROUND_PIXEL (f));
unload_color (f, f->output_data.x->cursor_pixel);
unload_color (f, f->output_data.x->cursor_foreground_pixel);
unload_color (f, f->output_data.x->border_pixel);
If SIZE is > 0, it is the size (maximum bounds width) of fonts
to be listed.
- SIZE < 0 means include scalable fonts.
+ SIZE < 0 means include auto scaled 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
bzero (fontp, sizeof (*fontp));
fontp->font = font;
fontp->font_idx = i;
+ fontp->charset = -1; /* fs_load_font sets it. */
fontp->name = (char *) xmalloc (strlen (fontname) + 1);
bcopy (fontname, fontp->name, strlen (fontname) + 1);
the font code-points (0:0x20..0x7F, 1:0xA0..0xFF), or
(0:0x2020..0x7F7F, 1:0xA0A0..0xFFFF, 3:0x20A0..0x7FFF,
2:0xA020..0xFF7F). For the moment, we don't know which charset
- uses this font. So, we set information in fontp->encoding[1]
+ uses this font. So, we set information in fontp->encoding_type
which is never used by any charset. If mapping can't be
decided, set FONT_ENCODING_NOT_DECIDED. */
- fontp->encoding[1]
+ fontp->encoding_type
= (font->max_byte1 == 0
/* 1-byte font */
? (font->min_char_or_byte2 < 0x80
}
+/* Return a char-table whose elements are t if the font FONT_INFO
+ contains a glyph for the corresponding character, and nil if
+ not. */
+
+Lisp_Object
+x_get_font_repertory (f, font_info)
+ FRAME_PTR f;
+ struct font_info *font_info;
+{
+ XFontStruct *font = (XFontStruct *) font_info->font;
+ Lisp_Object table;
+ int min_byte1, max_byte1, min_byte2, max_byte2;
+ int c;
+ struct charset *charset = CHARSET_FROM_ID (font_info->charset);
+ int offset = CHARSET_OFFSET (charset);
+
+ table = Fmake_char_table (Qnil, Qnil);
+
+ min_byte1 = font->min_byte1;
+ max_byte1 = font->max_byte1;
+ min_byte2 = font->min_char_or_byte2;
+ max_byte2 = font->max_char_or_byte2;
+ if (min_byte1 == 0 && max_byte1 == 0)
+ {
+ if (! font->per_char || font->all_chars_exist == True)
+ {
+ if (offset >= 0)
+ char_table_set_range (table, offset + min_byte2,
+ offset + max_byte2, Qt);
+ else
+ for (; min_byte2 <= max_byte2; min_byte2++)
+ {
+ c = DECODE_CHAR (charset, min_byte2);
+ CHAR_TABLE_SET (table, c, Qt);
+ }
+ }
+ else
+ {
+ XCharStruct *pcm = font->per_char;
+ int from = -1;
+ int i;
+
+ for (i = min_byte2; i <= max_byte2; i++, pcm++)
+ {
+ if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
+ {
+ if (from >= 0)
+ {
+ if (offset >= 0)
+ char_table_set_range (table, offset + from,
+ offset + i - 1, Qt);
+ else
+ for (; from < i; from++)
+ {
+ c = DECODE_CHAR (charset, from);
+ CHAR_TABLE_SET (table, c, Qt);
+ }
+ from = -1;
+ }
+ }
+ else if (from < 0)
+ from = i;
+ }
+ if (from >= 0)
+ {
+ if (offset >= 0)
+ char_table_set_range (table, offset + from, offset + i - 1,
+ Qt);
+ else
+ for (; from < i; from++)
+ {
+ c = DECODE_CHAR (charset, from);
+ CHAR_TABLE_SET (table, c, Qt);
+ }
+ }
+ }
+ }
+ else
+ {
+ if (! font->per_char || font->all_chars_exist == True)
+ {
+ int i, j;
+
+ if (offset >= 0)
+ for (i = min_byte1; i <= max_byte1; i++)
+ char_table_set_range
+ (table, offset + ((i << 8) | min_byte2),
+ offset + ((i << 8) | max_byte2), Qt);
+ else
+ for (i = min_byte1; i <= max_byte1; i++)
+ for (j = min_byte2; j <= max_byte2; j++)
+ {
+ unsigned code = (i << 8) | j;
+ c = DECODE_CHAR (charset, code);
+ CHAR_TABLE_SET (table, c, Qt);
+ }
+ }
+ else
+ {
+ XCharStruct *pcm = font->per_char;
+ int i;
+
+ for (i = min_byte1; i <= max_byte1; i++)
+ {
+ int from = -1;
+ int j;
+
+ for (j = min_byte2; j <= max_byte2; j++, pcm++)
+ {
+ if (pcm->width == 0 && pcm->rbearing == pcm->lbearing)
+ {
+ if (from >= 0)
+ {
+ if (offset >= 0)
+ char_table_set_range
+ (table, offset + ((i << 8) | from),
+ offset + ((i << 8) | (j - 1)), Qt);
+ else
+ {
+ for (; from < j; from++)
+ {
+ unsigned code = (i << 8) | from;
+ c = ENCODE_CHAR (charset, code);
+ CHAR_TABLE_SET (table, c, Qt);
+ }
+ }
+ from = -1;
+ }
+ }
+ else if (from < 0)
+ from = j;
+ }
+ if (from >= 0)
+ {
+ if (offset >= 0)
+ char_table_set_range
+ (table, offset + ((i << 8) | from),
+ offset + ((i << 8) | (j - 1)), Qt);
+ else
+ {
+ for (; from < j; from++)
+ {
+ unsigned code = (i << 8) | from;
+ c = DECODE_CHAR (charset, code);
+ CHAR_TABLE_SET (table, c, Qt);
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return table;
+}
\f
/***********************************************************************
Initialization
*bits = nr;
}
+/* Return 1 if display DISPLAY is available for use, 0 otherwise.
+ But don't permanently open it, just test its availability. */
+
int
x_display_ok (display)
- const char * display;
+ const char *display;
{
int dpy_ok = 1;
Display *dpy;
return dpy_ok;
}
+/* Open a connection to X display DISPLAY_NAME, and return
+ the structure that describes the open display.
+ If we cannot contact the display, return null. */
+
struct x_display_info *
x_term_init (display_name, xrm_option, resource_name)
Lisp_Object display_name;
{
int connection;
Display *dpy;
+ struct terminal *terminal;
struct x_display_info *dpyinfo;
XrmDatabase xrdb;
++x_initialized;
}
+ if (! x_display_ok (SDATA (display_name)))
+ error ("Display %s can't be opened", SDATA (display_name));
+
#ifdef USE_GTK
{
#define NUM_ARGV 10
char **argv2 = argv;
GdkAtom atom;
+#ifndef HAVE_GTK_MULTIDISPLAY
+ if (!EQ (Vinitial_window_system, intern ("x")))
+ error ("Sorry, you cannot connect to X servers with the GTK toolkit");
+#endif
+
if (x_initialized++ > 1)
{
+#ifdef HAVE_GTK_MULTIDISPLAY
/* Opening another display. If xg_display_open returns less
than zero, we are probably on GTK 2.0, which can only handle
one display. GTK 2.2 or later can handle more than one. */
if (xg_display_open (SDATA (display_name), &dpy) < 0)
+#endif
error ("Sorry, this version of GTK can only handle one display");
- }
+ }
else
{
for (argc = 0; argc < NUM_ARGV; ++argc)
dpyinfo = (struct x_display_info *) xmalloc (sizeof (struct x_display_info));
bzero (dpyinfo, sizeof *dpyinfo);
+ terminal = x_create_terminal (dpyinfo);
+
#ifdef MULTI_KBOARD
{
struct x_display_info *share;
SDATA (display_name)))
break;
if (share)
- dpyinfo->kboard = share->kboard;
+ terminal->kboard = share->terminal->kboard;
else
{
- dpyinfo->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
- init_kboard (dpyinfo->kboard);
+ terminal->kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
+ init_kboard (terminal->kboard);
if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound))
{
char *vendor = ServerVendor (dpy);
UNBLOCK_INPUT;
- dpyinfo->kboard->Vsystem_key_alist
+ terminal->kboard->Vsystem_key_alist
= call1 (Qvendor_specific_keysyms,
vendor ? build_string (vendor) : empty_unibyte_string);
BLOCK_INPUT;
}
- dpyinfo->kboard->next_kboard = all_kboards;
- all_kboards = dpyinfo->kboard;
+ terminal->kboard->next_kboard = all_kboards;
+ all_kboards = terminal->kboard;
/* Don't let the initial kboard remain current longer than necessary.
That would cause problems if a file loaded on startup tries to
prompt in the mini-buffer. */
if (current_kboard == initial_kboard)
- current_kboard = dpyinfo->kboard;
+ current_kboard = terminal->kboard;
}
- dpyinfo->kboard->reference_count++;
+ terminal->kboard->reference_count++;
}
#endif
dpyinfo->display = dpy;
+ /* Set the name of the terminal. */
+ terminal->name = (char *) xmalloc (SBYTES (display_name) + 1);
+ strncpy (terminal->name, SDATA (display_name), SBYTES (display_name));
+ terminal->name[SBYTES (display_name)] = 0;
+
#if 0
XSetAfterFunction (x_current_display, x_trace_wire);
#endif /* ! 0 */
}
#ifdef HAVE_X_SM
- /* Only do this for the first display. */
- if (!x_session_initialized++)
+ /* Only do this for the very first display in the Emacs session.
+ Ignore X session management when Emacs was first started on a
+ tty. */
+ if (terminal->id == 1)
x_session_initialize (dpyinfo);
#endif
return dpyinfo;
}
\f
-/* Get rid of display DPYINFO, assuming all frames are already gone,
+/* Get rid of display DPYINFO, deleting all frames on it,
and without sending any more commands to the X server. */
void
struct x_display_info *dpyinfo;
{
int i;
+ struct terminal *t;
+
+ /* Close all frames and delete the generic struct terminal for this
+ X display. */
+ for (t = terminal_list; t; t = t->next_terminal)
+ if (t->type == output_x_window && t->display_info.x == dpyinfo)
+ {
+#ifdef HAVE_X_SM
+ /* Close X session management when we close its display. */
+ if (t->id == 1 && x_session_have_connection ())
+ x_session_close();
+#endif
+ delete_terminal (t);
+ break;
+ }
delete_keyboard_wait_descriptor (dpyinfo->connection);
XrmDestroyDatabase (dpyinfo->xrdb);
#endif
#endif
-#ifdef MULTI_KBOARD
- if (--dpyinfo->kboard->reference_count == 0)
- delete_kboard (dpyinfo->kboard);
-#endif
#ifdef HAVE_X_I18N
if (dpyinfo->xim)
xim_close_dpy (dpyinfo);
extern frame_parm_handler x_frame_parm_handlers[];
static struct redisplay_interface x_redisplay_interface =
-{
- x_frame_parm_handlers,
- x_produce_glyphs,
- x_write_glyphs,
- x_insert_glyphs,
- x_clear_end_of_line,
- x_scroll_run,
- x_after_update_window_line,
- x_update_window_begin,
- x_update_window_end,
- x_cursor_to,
- x_flush,
+ {
+ x_frame_parm_handlers,
+ x_produce_glyphs,
+ x_write_glyphs,
+ x_insert_glyphs,
+ x_clear_end_of_line,
+ x_scroll_run,
+ x_after_update_window_line,
+ x_update_window_begin,
+ x_update_window_end,
+ x_cursor_to,
+ x_flush,
#ifdef XFlush
- x_flush,
+ x_flush,
#else
- 0, /* flush_display_optional */
-#endif
- x_clear_window_mouse_face,
- x_get_glyph_overhangs,
- x_fix_overlapping_area,
- x_draw_fringe_bitmap,
- 0, /* define_fringe_bitmap */
- 0, /* destroy_fringe_bitmap */
- x_per_char_metric,
- x_encode_char,
- x_compute_glyph_string_overhangs,
- x_draw_glyph_string,
- x_define_frame_cursor,
- x_clear_frame_area,
- x_draw_window_cursor,
- x_draw_vertical_window_border,
- x_shift_glyphs_for_insert
-};
+ 0, /* flush_display_optional */
+#endif
+ x_clear_window_mouse_face,
+ x_get_glyph_overhangs,
+ x_fix_overlapping_area,
+ x_draw_fringe_bitmap,
+ 0, /* define_fringe_bitmap */
+ 0, /* destroy_fringe_bitmap */
+ x_per_char_metric,
+ x_encode_char,
+ x_compute_glyph_string_overhangs,
+ x_draw_glyph_string,
+ x_define_frame_cursor,
+ x_clear_frame_area,
+ x_draw_window_cursor,
+ x_draw_vertical_window_border,
+ x_shift_glyphs_for_insert
+ };
+
+
+/* This function is called when the last frame on a display is deleted. */
+void
+x_delete_terminal (struct terminal *terminal)
+{
+ struct x_display_info *dpyinfo = terminal->display_info.x;
+ int i;
+
+ /* Protect against recursive calls. Fdelete_frame in
+ delete_terminal calls us back when it deletes our last frame. */
+ if (!terminal->name)
+ return;
+
+ BLOCK_INPUT;
+ /* Free the fonts in the font table. */
+ for (i = 0; i < dpyinfo->n_fonts; i++)
+ if (dpyinfo->font_table[i].name)
+ {
+ XFreeFont (dpyinfo->display, dpyinfo->font_table[i].font);
+ }
+
+ x_destroy_all_bitmaps (dpyinfo);
+ XSetCloseDownMode (dpyinfo->display, DestroyAll);
+
+#ifdef USE_GTK
+ xg_display_close (dpyinfo->display);
+#else
+#ifdef USE_X_TOOLKIT
+ XtCloseDisplay (dpyinfo->display);
+#else
+ XCloseDisplay (dpyinfo->display);
+#endif
+#endif /* ! USE_GTK */
+
+ x_delete_display (dpyinfo);
+ UNBLOCK_INPUT;
+}
+
+/* Create a struct terminal, initialize it with the X11 specific
+ functions and make DISPLAY->TERMINAL point to it. */
+
+static struct terminal *
+x_create_terminal (struct x_display_info *dpyinfo)
+{
+ struct terminal *terminal;
+
+ terminal = create_terminal ();
+
+ terminal->type = output_x_window;
+ terminal->display_info.x = dpyinfo;
+ dpyinfo->terminal = terminal;
+
+ /* kboard is initialized in x_term_init. */
+
+ terminal->clear_frame_hook = x_clear_frame;
+ terminal->ins_del_lines_hook = x_ins_del_lines;
+ terminal->delete_glyphs_hook = x_delete_glyphs;
+ terminal->ring_bell_hook = XTring_bell;
+ terminal->reset_terminal_modes_hook = XTreset_terminal_modes;
+ terminal->set_terminal_modes_hook = XTset_terminal_modes;
+ terminal->update_begin_hook = x_update_begin;
+ terminal->update_end_hook = x_update_end;
+ terminal->set_terminal_window_hook = XTset_terminal_window;
+ terminal->read_socket_hook = XTread_socket;
+ terminal->frame_up_to_date_hook = XTframe_up_to_date;
+ terminal->mouse_position_hook = XTmouse_position;
+ terminal->frame_rehighlight_hook = XTframe_rehighlight;
+ terminal->frame_raise_lower_hook = XTframe_raise_lower;
+ terminal->fullscreen_hook = XTfullscreen_hook;
+ terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
+ terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
+ terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
+ terminal->judge_scroll_bars_hook = XTjudge_scroll_bars;
+
+ terminal->delete_frame_hook = x_destroy_window;
+ terminal->delete_terminal_hook = x_delete_terminal;
+
+ terminal->rif = &x_redisplay_interface;
+ terminal->scroll_region_ok = 1; /* We'll scroll partial frames. */
+ terminal->char_ins_del_ok = 1;
+ terminal->line_ins_del_ok = 1; /* We'll just blt 'em. */
+ terminal->fast_clear_end_of_line = 1; /* X does this well. */
+ terminal->memory_below_frame = 0; /* We don't remember what scrolls
+ off the bottom. */
+
+ return terminal;
+}
void
x_initialize ()
{
- rif = &x_redisplay_interface;
-
- clear_frame_hook = x_clear_frame;
- ins_del_lines_hook = x_ins_del_lines;
- delete_glyphs_hook = x_delete_glyphs;
- ring_bell_hook = XTring_bell;
- reset_terminal_modes_hook = XTreset_terminal_modes;
- set_terminal_modes_hook = XTset_terminal_modes;
- update_begin_hook = x_update_begin;
- update_end_hook = x_update_end;
- set_terminal_window_hook = XTset_terminal_window;
- read_socket_hook = XTread_socket;
- frame_up_to_date_hook = XTframe_up_to_date;
- mouse_position_hook = XTmouse_position;
- frame_rehighlight_hook = XTframe_rehighlight;
- frame_raise_lower_hook = XTframe_raise_lower;
- set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
- condemn_scroll_bars_hook = XTcondemn_scroll_bars;
- redeem_scroll_bar_hook = XTredeem_scroll_bar;
- judge_scroll_bars_hook = XTjudge_scroll_bars;
- fullscreen_hook = XTfullscreen_hook;
-
- scroll_region_ok = 1; /* we'll scroll partial frames */
- 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
- off the bottom */
baud_rate = 19200;
x_noop_count = 0;
#endif
/* Try to use interrupt input; if we can't, then start polling. */
- Fset_input_mode (Qt, Qnil, Qt, Qnil);
+ Fset_input_interrupt_mode (Qt);
#ifdef USE_X_TOOLKIT
XtToolkitInitialize ();
XSetIOErrorHandler (x_io_error_quitter);
/* Disable Window Change signals; they are handled by X events. */
+#if 0 /* Don't. We may want to open tty frames later. */
#ifdef SIGWINCH
signal (SIGWINCH, SIG_DFL);
#endif /* SIGWINCH */
+#endif
signal (SIGPIPE, x_connection_signal);
}
staticpro (&Qvendor_specific_keysyms);
Qvendor_specific_keysyms = intern ("vendor-specific-keysyms");
- staticpro (&Qutf_8);
- Qutf_8 = intern ("utf-8");
staticpro (&Qlatin_1);
Qlatin_1 = intern ("latin-1");