#include "atimer.h"
#include "keymap.h"
#include "font.h"
+#include "fontset.h"
#ifdef USE_X_TOOLKIT
#include <X11/Shell.h>
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
Display *dpy = FRAME_X_DISPLAY (f);
Window win = FRAME_OUTER_WINDOW (f);
+ double alpha = 1.0;
+ double alpha_min = 1.0;
+ unsigned long opac;
+
if (FRAME_X_DISPLAY_INFO (f)->root_window != FRAME_X_OUTPUT (f)->parent_desc)
/* Since the WM decoration lies under the FRAME_OUTER_WINDOW,
we must treat the former instead of the latter. */
win = FRAME_X_OUTPUT(f)->parent_desc;
- double alpha = 1.0, alpha_min = 1.0;
-
if (dpyinfo->x_highlight_frame == f)
alpha = f->alpha[0];
else
else if (INTEGERP (Vframe_alpha_lower_limit))
alpha_min = (XINT (Vframe_alpha_lower_limit)) / 100.0;
- if (alpha < 0.0 || 1.0 < alpha)
+ if (alpha < 0.0)
+ return;
+ else if (alpha > 1.0)
alpha = 1.0;
else if (0.0 <= alpha && alpha < alpha_min && alpha_min <= 1.0)
alpha = alpha_min;
- unsigned int opac = (unsigned int)(alpha * OPAQUE);
+ opac = alpha * OPAQUE;
/* return unless necessary */
{
unsigned char *data;
Atom actual;
- int format;
+ int rc, format;
unsigned long n, left;
- XGetWindowProperty(dpy, win, XInternAtom(dpy, OPACITY, False),
- 0L, 1L, False, XA_CARDINAL, &actual, &format, &n, &left,
- (unsigned char **) &data);
- if (data != None)
- if (*(unsigned int *)data == opac)
+ x_catch_errors (dpy);
+ rc = XGetWindowProperty(dpy, win, XInternAtom(dpy, OPACITY, False),
+ 0L, 1L, False, XA_CARDINAL,
+ &actual, &format, &n, &left,
+ &data);
+
+ if (rc == Success && actual != None)
+ if (*(unsigned long *)data == opac)
{
XFree ((void *) data);
+ x_uncatch_errors ();
return;
}
else
- {
- XFree ((void *) data);
- }
+ XFree ((void *) data);
+ x_uncatch_errors ();
}
+ x_catch_errors (dpy);
XChangeProperty (dpy, win, XInternAtom (dpy, OPACITY, False),
XA_CARDINAL, 32, PropModeReplace,
(unsigned char *) &opac, 1L);
- XSync (dpy, False);
+ x_uncatch_errors ();
+}
+
+int
+x_display_pixel_height (dpyinfo)
+ struct x_display_info *dpyinfo;
+{
+ return HeightOfScreen (dpyinfo->screen);
+}
+
+int
+x_display_pixel_width (dpyinfo)
+ struct x_display_info *dpyinfo;
+{
+ return WidthOfScreen (dpyinfo->screen);
}
\f
struct glyph_string *s;
{
int i, j, x;
+ struct font *font = s->font;
/* If first glyph of S has a left box line, start drawing the text
of S to the right of that box line. */
else
x = s->x;
- /* S is a glyph string for a composition. S->gidx is the index of
- the first character drawn for glyphs of this composition.
- S->gidx == 0 means we are drawing the very first character of
+ /* S is a glyph string for a composition. S->cmp_from is the index
+ of the first character drawn for glyphs of this composition.
+ S->cmp_from == 0 means we are drawing the very first character of
this composition. */
/* Draw a rectangle for the composition if the font for the very
first character of the composition could not be loaded. */
if (s->font_not_found_p)
{
- if (s->gidx == 0)
+ if (s->cmp_from == 0)
XDrawRectangle (s->display, s->window, s->gc, x, s->y,
s->width - 1, s->height - 1);
}
+ else if (! s->first_glyph->u.cmp.automatic)
+ {
+ int y = s->ybase;
+
+ for (i = 0, j = s->cmp_from; 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);
+ }
+ }
else
{
- struct font *font = s->font;
+ Lisp_Object gstring = composition_gstring_from_id (s->cmp_id);
+ Lisp_Object glyph;
int y = s->ybase;
int width = 0;
- if (s->cmp->method == COMPOSITION_WITH_GLYPH_STRING)
+ for (i = j = s->cmp_from; i < s->cmp_to; i++)
{
- 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++)
+ glyph = LGSTRING_GLYPH (gstring, i);
+ if (NILP (LGLYPH_ADJUSTMENT (glyph)))
+ width += LGLYPH_WIDTH (glyph);
+ else
{
- Lisp_Object g = LGSTRING_GLYPH (gstring, i);
- Lisp_Object adjustment = LGLYPH_ADJUSTMENT (g);
int xoff, yoff, wadjust;
- if (! VECTORP (adjustment))
+ if (j < i)
{
- width += LGLYPH_WIDTH (g);
- continue;
- }
- if (from < i)
- {
- font->driver->draw (s, from, i, x, y, 0);
+ font->driver->draw (s, j, i, x, y, 0);
x += width;
}
- xoff = XINT (AREF (adjustment, 0));
- yoff = XINT (AREF (adjustment, 1));
- wadjust = XINT (AREF (adjustment, 2));
-
+ xoff = LGLYPH_XOFF (glyph);
+ yoff = LGLYPH_YOFF (glyph);
+ wadjust = LGLYPH_WADJUST (glyph);
font->driver->draw (s, i, i + 1, x + xoff, y + yoff, 0);
x += wadjust;
- from = i + 1;
+ j = 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);
- }
}
+ if (j < i)
+ font->driver->draw (s, j, i, x, y, 0);
}
}
int width;
struct glyph_string *next;
- for (width = 0, next = s->next; next;
+ for (width = 0, next = s->next;
+ next && width < s->right_overhang;
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);
+ if (next->first_glyph->type == STRETCH_GLYPH)
+ x_draw_stretch_glyph_string (next);
+ else
+ x_draw_glyph_string_background (next, 1);
next->num_clips = 0;
}
}
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))
+ else if (!s->clip_head /* draw_glyphs didn't specify a clip mask. */
+ && !s->clip_tail
+ && ((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. */
break;
case COMPOSITE_GLYPH:
- if (s->for_overlaps || s->gidx > 0)
+ if (s->for_overlaps || (s->cmp_from > 0
+ && ! s->first_glyph->u.cmp.automatic))
s->background_filled_p = 1;
else
x_draw_glyph_string_background (s, 1);
else
thickness = 1;
if (x_underline_at_descent_line)
- position = (s->height - thickness) - s->ybase;
+ position = (s->height - thickness) - (s->ybase - s->y);
else
{
/* Get the underline position. This is the recommended
else if (s->font)
position = (s->font->descent + 1) / 2;
}
- s->underline_thickness = thickness;
- s->underline_position = position;
+ position = max (position, underline_minimum_offset);
}
+ /* Check the sanity of thickness and position. We should
+ avoid drawing underline out of the current line area. */
+ if (s->y + s->height <= s->ybase + position)
+ position = (s->height - 1) - (s->ybase - s->y);
+ if (s->y + s->height < s->ybase + position + thickness)
+ thickness = (s->y + s->height) - (s->ybase + position);
+ s->underline_thickness = thickness;
+ s->underline_position = position;
y = s->ybase + position;
if (s->face->underline_defaulted_p)
XFillRectangle (s->display, s->window, s->gc,
if (f)
{
- /* Generate SELECT_WINDOW_EVENTs when needed. */
- if (!NILP (Vmouse_autoselect_window))
+ /* Generate SELECT_WINDOW_EVENTs when needed.
+ Don't let popup menus influence things (bug#1261). */
+ if (!NILP (Vmouse_autoselect_window) && !popup_activated ())
{
Lisp_Object window;
WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y +
row->height - width),
- cursor_glyph->pixel_width,
+ min (FRAME_COLUMN_WIDTH (f), cursor_glyph->pixel_width),
width);
XSetClipMask (dpy, gc, None);
XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
NULL, EMACS_CLASS,
xim_instantiate_callback, NULL);
-#endif /* not HAVE_X11R6_XIM */
+#else /* not HAVE_X11R6_XIM */
+ /* If we have X11R6 xim, this causes a double-free. */
if (dpyinfo->display)
XCloseIM (dpyinfo->xim);
+#endif /* HAVE_X11R6_XIM */
dpyinfo->xim = NULL;
XFree (dpyinfo->xim_styles);
}
/* Treat negative positions as relative to the leftmost bottommost
position that fits on the screen. */
if (flags & XNegative)
- f->left_pos = (FRAME_X_DISPLAY_INFO (f)->width
- - FRAME_PIXEL_WIDTH (f) + f->left_pos);
+ f->left_pos = x_display_pixel_width (FRAME_X_DISPLAY_INFO (f))
+ - FRAME_PIXEL_WIDTH (f) + f->left_pos;
{
int height = FRAME_PIXEL_HEIGHT (f);
XtVaGetValues (f->output_data.x->column_widget, XtNheight, &height, NULL);
#endif
- if (flags & YNegative)
- f->top_pos = (FRAME_X_DISPLAY_INFO (f)->height - height + f->top_pos);
+ if (flags & YNegative)
+ f->top_pos = x_display_pixel_height (FRAME_X_DISPLAY_INFO (f))
+ - height + f->top_pos;
}
/* The left_pos and top_pos
XFlush (FRAME_X_DISPLAY (f));
}
- if (f->output_data.x->saved_menu_event)
- xfree (f->output_data.x->saved_menu_event);
-
+ xfree (f->output_data.x->saved_menu_event);
xfree (f->output_data.x);
f->output_data.x = NULL;
size_hints.width_inc = FRAME_COLUMN_WIDTH (f);
size_hints.height_inc = FRAME_LINE_HEIGHT (f);
- size_hints.max_width
- = FRAME_X_DISPLAY_INFO (f)->width - FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
- size_hints.max_height
- = FRAME_X_DISPLAY_INFO (f)->height - FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
+ size_hints.max_width = x_display_pixel_width (FRAME_X_DISPLAY_INFO (f))
+ - FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, 0);
+ size_hints.max_height = x_display_pixel_height (FRAME_X_DISPLAY_INFO (f))
+ - FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, 0);
/* Calculate the base and minimum sizes.
static int x_session_initialized;
#endif
-#ifdef MULTI_KBOARD
/* Test whether two display-name strings agree up to the dot that separates
the screen number from the server number. */
static int
&& (*name1 == '.' || *name1 == '\0')
&& (*name2 == '.' || *name2 == '\0'));
}
-#endif
/* Count number of set bits in mask and number of bits to shift to
get to the first bit. With MASK 0x7e0, *BITS is set to 6, and *OFFSET
terminal = x_create_terminal (dpyinfo);
-#ifdef MULTI_KBOARD
{
struct x_display_info *share;
Lisp_Object tail;
if (!EQ (XSYMBOL (Qvendor_specific_keysyms)->function, Qunbound))
{
char *vendor = ServerVendor (dpy);
+ /* Temporarily hide the partially initialized terminal */
+ terminal_list = terminal->next_terminal;
UNBLOCK_INPUT;
terminal->kboard->Vsystem_key_alist
= call1 (Qvendor_specific_keysyms,
vendor ? build_string (vendor) : empty_unibyte_string);
BLOCK_INPUT;
+ terminal->next_terminal = terminal_list;
+ terminal_list = terminal;
}
terminal->kboard->next_kboard = all_kboards;
}
terminal->kboard->reference_count++;
}
-#endif
/* Put this display on the chain. */
dpyinfo->next = x_display_list;
DefaultScreen (dpyinfo->display));
select_visual (dpyinfo);
dpyinfo->cmap = DefaultColormapOfScreen (dpyinfo->screen);
- dpyinfo->height = HeightOfScreen (dpyinfo->screen);
- dpyinfo->width = WidthOfScreen (dpyinfo->screen);
dpyinfo->root_window = RootWindowOfScreen (dpyinfo->screen);
dpyinfo->client_leader_window = 0;
dpyinfo->grabbed = 0;
tail->next = tail->next->next;
}
-#ifndef USE_X_TOOLKIT /* I'm told Xt does this itself. */
+ /* Xt and GTK do this themselves. */
+#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK)
#ifndef AIX /* On AIX, XCloseDisplay calls this. */
XrmDestroyDatabase (dpyinfo->xrdb);
#endif
xim_close_dpy (dpyinfo);
#endif
- if (dpyinfo->x_id_name)
- xfree (dpyinfo->x_id_name);
- if (dpyinfo->color_cells)
- xfree (dpyinfo->color_cells);
+ xfree (dpyinfo->x_id_name);
+ xfree (dpyinfo->color_cells);
xfree (dpyinfo);
}
doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
A value of nil means ignore them. If you encounter fonts with bogus
UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
-to 4.1, set this to nil. */);
+to 4.1, set this to nil. You can also use `underline-minimum-offset'
+to override the font's UNDERLINE_POSITION for small font display
+sizes. */);
x_use_underline_position_properties = 1;
DEFVAR_BOOL ("x-underline-at-descent-line",