summaryrefslogtreecommitdiff
path: root/src/xterm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c202
1 files changed, 100 insertions, 102 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 44396955ed0..6340700cb89 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -1750,7 +1750,7 @@ x_draw_glyph_string_background (struct glyph_string *s, bool force_p)
shouldn't be drawn in the first place. */
if (!s->background_filled_p)
{
- int box_line_width = max (s->face->box_line_width, 0);
+ int box_line_width = max (s->face->box_horizontal_line_width, 0);
if (s->stippled_p)
{
@@ -1795,7 +1795,7 @@ x_draw_glyph_string_foreground (struct glyph_string *s)
of S to the right of that box line. */
if (s->face->box != FACE_NO_BOX
&& s->first_glyph->left_box_line_p)
- x = s->x + eabs (s->face->box_line_width);
+ x = s->x + max (s->face->box_vertical_line_width, 0);
else
x = s->x;
@@ -1845,7 +1845,7 @@ x_draw_glyph_string_foreground (struct glyph_string *s)
if (!(s->for_overlaps
|| (s->background_filled_p && s->hl != DRAW_CURSOR)))
{
- int box_line_width = max (s->face->box_line_width, 0);
+ int box_line_width = max (s->face->box_horizontal_line_width, 0);
if (s->stippled_p)
{
@@ -1889,7 +1889,7 @@ x_draw_composite_glyph_string_foreground (struct glyph_string *s)
of S to the right of that box line. */
if (s->face && s->face->box != FACE_NO_BOX
&& s->first_glyph->left_box_line_p)
- x = s->x + eabs (s->face->box_line_width);
+ x = s->x + max (s->face->box_vertical_line_width, 0);
else
x = s->x;
@@ -2000,7 +2000,7 @@ x_draw_glyphless_glyph_string_foreground (struct glyph_string *s)
of S to the right of that box line. */
if (s->face && s->face->box != FACE_NO_BOX
&& s->first_glyph->left_box_line_p)
- x = s->x + eabs (s->face->box_line_width);
+ x = s->x + max (s->face->box_vertical_line_width, 0);
else
x = s->x;
@@ -2376,8 +2376,6 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
x_query_colors (f, bgcolor, 1);
}
-#define HEX_COLOR_NAME_LENGTH 32
-
/* On frame F, translate the color name to RGB values. Use cached
information, if possible.
@@ -2389,44 +2387,23 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
Status x_parse_color (struct frame *f, const char *color_name,
XColor *color)
{
+ /* Don't pass #RGB strings directly to XParseColor, because that
+ follows the X convention of zero-extending each channel
+ value: #f00 means #f00000. We want the convention of scaling
+ channel values, so #f00 means #ff0000, just as it does for
+ HTML, SVG, and CSS. */
+ unsigned short r, g, b;
+ if (parse_color_spec (color_name, &r, &g, &b))
+ {
+ color->red = r;
+ color->green = g;
+ color->blue = b;
+ return 1;
+ }
+
Display *dpy = FRAME_X_DISPLAY (f);
Colormap cmap = FRAME_X_COLORMAP (f);
struct color_name_cache_entry *cache_entry;
-
- if (color_name[0] == '#')
- {
- /* Don't pass #RGB strings directly to XParseColor, because that
- follows the X convention of zero-extending each channel
- value: #f00 means #f00000. We want the convention of scaling
- channel values, so #f00 means #ff0000, just as it does for
- HTML, SVG, and CSS.
-
- So we translate #f00 to rgb:f/0/0, which X handles
- differently. */
- char rgb_color_name[HEX_COLOR_NAME_LENGTH];
- int len = strlen (color_name);
- int digits_per_channel;
- if (len == 4)
- digits_per_channel = 1;
- else if (len == 7)
- digits_per_channel = 2;
- else if (len == 10)
- digits_per_channel = 3;
- else if (len == 13)
- digits_per_channel = 4;
- else
- return 0;
-
- snprintf (rgb_color_name, sizeof rgb_color_name, "rgb:%.*s/%.*s/%.*s",
- digits_per_channel, color_name + 1,
- digits_per_channel, color_name + digits_per_channel + 1,
- digits_per_channel, color_name + 2 * digits_per_channel + 1);
-
- /* The rgb form is parsed directly by XParseColor without
- talking to the X server. No need for caching. */
- return XParseColor (dpy, cmap, rgb_color_name, color);
- }
-
for (cache_entry = FRAME_DISPLAY_INFO (f)->color_names; cache_entry;
cache_entry = cache_entry->next)
{
@@ -2765,7 +2742,7 @@ x_setup_relief_colors (struct glyph_string *s)
static void
x_draw_relief_rect (struct frame *f,
int left_x, int top_y, int right_x, int bottom_y,
- int width, bool raised_p, bool top_p, bool bot_p,
+ int hwidth, int vwidth, bool raised_p, bool top_p, bool bot_p,
bool left_p, bool right_p,
XRectangle *clip_rect)
{
@@ -2790,7 +2767,7 @@ x_draw_relief_rect (struct frame *f,
if (left_p)
{
x_fill_rectangle (f, top_left_gc, left_x, top_y,
- width, bottom_y + 1 - top_y);
+ vwidth, bottom_y + 1 - top_y);
if (top_p)
corners |= 1 << CORNER_TOP_LEFT;
if (bot_p)
@@ -2798,8 +2775,8 @@ x_draw_relief_rect (struct frame *f,
}
if (right_p)
{
- x_fill_rectangle (f, bottom_right_gc, right_x + 1 - width, top_y,
- width, bottom_y + 1 - top_y);
+ x_fill_rectangle (f, bottom_right_gc, right_x + 1 - vwidth, top_y,
+ vwidth, bottom_y + 1 - top_y);
if (top_p)
corners |= 1 << CORNER_TOP_RIGHT;
if (bot_p)
@@ -2809,25 +2786,25 @@ x_draw_relief_rect (struct frame *f,
{
if (!right_p)
x_fill_rectangle (f, top_left_gc, left_x, top_y,
- right_x + 1 - left_x, width);
+ right_x + 1 - left_x, hwidth);
else
x_fill_trapezoid_for_relief (f, top_left_gc, left_x, top_y,
- right_x + 1 - left_x, width, 1);
+ right_x + 1 - left_x, hwidth, 1);
}
if (bot_p)
{
if (!left_p)
- x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - width,
- right_x + 1 - left_x, width);
+ x_fill_rectangle (f, bottom_right_gc, left_x, bottom_y + 1 - hwidth,
+ right_x + 1 - left_x, hwidth);
else
x_fill_trapezoid_for_relief (f, bottom_right_gc,
- left_x, bottom_y + 1 - width,
- right_x + 1 - left_x, width, 0);
+ left_x, bottom_y + 1 - hwidth,
+ right_x + 1 - left_x, hwidth, 0);
}
- if (left_p && width != 1)
+ if (left_p && vwidth > 1)
x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
1, bottom_y + 1 - top_y);
- if (top_p && width != 1)
+ if (top_p && hwidth > 1)
x_fill_rectangle (f, bottom_right_gc, left_x, top_y,
right_x + 1 - left_x, 1);
if (corners)
@@ -2861,12 +2838,12 @@ x_draw_relief_rect (struct frame *f,
/* Top. */
if (top_p)
{
- if (width == 1)
+ if (hwidth == 1)
XDrawLine (dpy, drawable, gc,
left_x + left_p, top_y,
right_x + !right_p, top_y);
- for (i = 1; i < width; ++i)
+ for (i = 1; i < hwidth; ++i)
XDrawLine (dpy, drawable, gc,
left_x + i * left_p, top_y + i,
right_x + 1 - i * right_p, top_y + i);
@@ -2875,13 +2852,10 @@ x_draw_relief_rect (struct frame *f,
/* Left. */
if (left_p)
{
- if (width == 1)
+ if (vwidth == 1)
XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
- x_clear_area(f, left_x, top_y, 1, 1);
- x_clear_area(f, left_x, bottom_y, 1, 1);
-
- for (i = (width > 1 ? 1 : 0); i < width; ++i)
+ for (i = 1; i < vwidth; ++i)
XDrawLine (dpy, drawable, gc,
left_x + i, top_y + (i + 1) * top_p,
left_x + i, bottom_y + 1 - (i + 1) * bot_p);
@@ -2894,26 +2868,25 @@ x_draw_relief_rect (struct frame *f,
gc = f->output_data.x->white_relief.gc;
XSetClipRectangles (dpy, gc, 0, 0, clip_rect, 1, Unsorted);
- if (width > 1)
- {
- /* Outermost top line. */
- if (top_p)
- XDrawLine (dpy, drawable, gc,
- left_x + left_p, top_y,
- right_x + !right_p, top_y);
+ /* Outermost top line. */
+ if (top_p && hwidth > 1)
+ XDrawLine (dpy, drawable, gc,
+ left_x + left_p, top_y,
+ right_x + !right_p, top_y);
- /* Outermost left line. */
- if (left_p)
- XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
- }
+ /* Outermost left line. */
+ if (left_p && vwidth > 1)
+ XDrawLine (dpy, drawable, gc, left_x, top_y + 1, left_x, bottom_y);
/* Bottom. */
if (bot_p)
{
- XDrawLine (dpy, drawable, gc,
- left_x + left_p, bottom_y,
- right_x + !right_p, bottom_y);
- for (i = 1; i < width; ++i)
+ if (hwidth >= 1)
+ XDrawLine (dpy, drawable, gc,
+ left_x + left_p, bottom_y,
+ right_x + !right_p, bottom_y);
+
+ for (i = 1; i < hwidth; ++i)
XDrawLine (dpy, drawable, gc,
left_x + i * left_p, bottom_y - i,
right_x + 1 - i * right_p, bottom_y - i);
@@ -2922,9 +2895,7 @@ x_draw_relief_rect (struct frame *f,
/* Right. */
if (right_p)
{
- x_clear_area(f, right_x, top_y, 1, 1);
- x_clear_area(f, right_x, bottom_y, 1, 1);
- for (i = 0; i < width; ++i)
+ for (i = 0; i < vwidth; ++i)
XDrawLine (dpy, drawable, gc,
right_x - i, top_y + (i + 1) * top_p,
right_x - i, bottom_y + 1 - (i + 1) * bot_p);
@@ -2945,8 +2916,8 @@ x_draw_relief_rect (struct frame *f,
static void
x_draw_box_rect (struct glyph_string *s,
- int left_x, int top_y, int right_x, int bottom_y, int width,
- bool left_p, bool right_p, XRectangle *clip_rect)
+ int left_x, int top_y, int right_x, int bottom_y, int hwidth,
+ int vwidth, bool left_p, bool right_p, XRectangle *clip_rect)
{
Display *display = FRAME_X_DISPLAY (s->f);
XGCValues xgcv;
@@ -2957,21 +2928,21 @@ x_draw_box_rect (struct glyph_string *s,
/* Top. */
x_fill_rectangle (s->f, s->gc,
- left_x, top_y, right_x - left_x + 1, width);
+ left_x, top_y, right_x - left_x + 1, hwidth);
/* Left. */
if (left_p)
x_fill_rectangle (s->f, s->gc,
- left_x, top_y, width, bottom_y - top_y + 1);
+ left_x, top_y, vwidth, bottom_y - top_y + 1);
/* Bottom. */
x_fill_rectangle (s->f, s->gc,
- left_x, bottom_y - width + 1, right_x - left_x + 1, width);
+ left_x, bottom_y - hwidth + 1, right_x - left_x + 1, hwidth);
/* Right. */
if (right_p)
x_fill_rectangle (s->f, s->gc,
- right_x - width + 1, top_y, width, bottom_y - top_y + 1);
+ right_x - vwidth + 1, top_y, vwidth, bottom_y - top_y + 1);
XSetForeground (display, s->gc, xgcv.foreground);
x_reset_clip_rectangles (s->f, s->gc);
@@ -2983,7 +2954,7 @@ x_draw_box_rect (struct glyph_string *s,
static void
x_draw_glyph_string_box (struct glyph_string *s)
{
- int width, left_x, right_x, top_y, bottom_y, last_x;
+ int hwidth, vwidth, left_x, right_x, top_y, bottom_y, last_x;
bool raised_p, left_p, right_p;
struct glyph *last_glyph;
XRectangle clip_rect;
@@ -2992,12 +2963,29 @@ x_draw_glyph_string_box (struct glyph_string *s)
? WINDOW_RIGHT_EDGE_X (s->w)
: window_box_right (s->w, s->area));
- /* The glyph that may have a right box line. */
- last_glyph = (s->cmp || s->img
- ? s->first_glyph
- : s->first_glyph + s->nchars - 1);
+ /* The glyph that may have a right box line. For static
+ compositions and images, the right-box flag is on the first glyph
+ of the glyph string; for other types it's on the last glyph. */
+ if (s->cmp || s->img)
+ last_glyph = s->first_glyph;
+ else if (s->first_glyph->type == COMPOSITE_GLYPH
+ && s->first_glyph->u.cmp.automatic)
+ {
+ /* For automatic compositions, we need to look up the last glyph
+ in the composition. */
+ struct glyph *end = s->row->glyphs[s->area] + s->row->used[s->area];
+ struct glyph *g = s->first_glyph;
+ for (last_glyph = g++;
+ g < end && g->u.cmp.automatic && g->u.cmp.id == s->cmp_id
+ && g->slice.cmp.to < s->cmp_to;
+ last_glyph = g++)
+ ;
+ }
+ else
+ last_glyph = s->first_glyph + s->nchars - 1;
- width = eabs (s->face->box_line_width);
+ vwidth = eabs (s->face->box_vertical_line_width);
+ hwidth = eabs (s->face->box_horizontal_line_width);
raised_p = s->face->box == FACE_RAISED_BOX;
left_x = s->x;
right_x = (s->row->full_width_p && s->extends_to_end_of_line_p
@@ -3018,13 +3006,13 @@ x_draw_glyph_string_box (struct glyph_string *s)
get_glyph_string_clip_rect (s, &clip_rect);
if (s->face->box == FACE_SIMPLE_BOX)
- x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, width,
- left_p, right_p, &clip_rect);
+ x_draw_box_rect (s, left_x, top_y, right_x, bottom_y, hwidth,
+ vwidth, left_p, right_p, &clip_rect);
else
{
x_setup_relief_colors (s);
- x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y,
- width, raised_p, true, true, left_p, right_p,
+ x_draw_relief_rect (s->f, left_x, top_y, right_x, bottom_y, hwidth,
+ vwidth, raised_p, true, true, left_p, right_p,
&clip_rect);
}
}
@@ -3082,7 +3070,7 @@ x_draw_image_foreground (struct glyph_string *s)
if (s->face->box != FACE_NO_BOX
&& s->first_glyph->left_box_line_p
&& s->slice.x == 0)
- x += eabs (s->face->box_line_width);
+ x += max (s->face->box_vertical_line_width, 0);
/* If there is a margin around the image, adjust x- and y-position
by that margin. */
@@ -3201,7 +3189,7 @@ x_draw_image_relief (struct glyph_string *s)
if (s->face->box != FACE_NO_BOX
&& s->first_glyph->left_box_line_p
&& s->slice.x == 0)
- x += eabs (s->face->box_line_width);
+ x += max (s->face->box_vertical_line_width, 0);
/* If there is a margin around the image, adjust x- and y-position
by that margin. */
@@ -3269,7 +3257,7 @@ x_draw_image_relief (struct glyph_string *s)
x_setup_relief_colors (s);
get_glyph_string_clip_rect (s, &r);
- x_draw_relief_rect (s->f, x, y, x1, y1, thick, raised_p,
+ x_draw_relief_rect (s->f, x, y, x1, y1, thick, thick, raised_p,
top_p, bot_p, left_p, right_p, &r);
}
@@ -3288,7 +3276,7 @@ x_draw_image_foreground_1 (struct glyph_string *s, Pixmap pixmap)
if (s->face->box != FACE_NO_BOX
&& s->first_glyph->left_box_line_p
&& s->slice.x == 0)
- x += eabs (s->face->box_line_width);
+ x += max (s->face->box_vertical_line_width, 0);
/* If there is a margin around the image, adjust x- and y-position
by that margin. */
@@ -3390,8 +3378,8 @@ x_draw_glyph_string_bg_rect (struct glyph_string *s, int x, int y, int w, int h)
static void
x_draw_image_glyph_string (struct glyph_string *s)
{
- int box_line_hwidth = eabs (s->face->box_line_width);
- int box_line_vwidth = max (s->face->box_line_width, 0);
+ int box_line_hwidth = max (s->face->box_vertical_line_width, 0);
+ int box_line_vwidth = max (s->face->box_horizontal_line_width, 0);
int height;
#ifndef USE_CAIRO
Display *display = FRAME_X_DISPLAY (s->f);
@@ -4786,6 +4774,16 @@ x_detect_focus_change (struct x_display_info *dpyinfo, struct frame *frame,
case FocusIn:
case FocusOut:
+ /* Ignore transient focus events from hotkeys, window manager
+ gadgets, and other odd sources. Some buggy window managers
+ (e.g., Muffin 4.2.4) send FocusIn events of this type without
+ corresponding FocusOut events even when some other window
+ really has focus, and these kinds of focus event don't
+ correspond to real user input changes. GTK+ uses the same
+ filtering. */
+ if (event->xfocus.mode == NotifyGrab ||
+ event->xfocus.mode == NotifyUngrab)
+ return;
x_focus_changed (event->type,
(event->xfocus.detail == NotifyPointer ?
FOCUS_IMPLICIT : FOCUS_EXPLICIT),
@@ -8701,7 +8699,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (nchars == nbytes)
ch = copy_bufptr[i], len = 1;
else
- ch = STRING_CHAR_AND_LENGTH (copy_bufptr + i, len);
+ ch = string_char_and_length (copy_bufptr + i, &len);
inev.ie.kind = (SINGLE_BYTE_CHAR_P (ch)
? ASCII_KEYSTROKE_EVENT
: MULTIBYTE_CHAR_KEYSTROKE_EVENT);