/* X Communication module for terminals which understand the X protocol.
Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008
+ 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
Free Software Foundation, Inc.
This file is part of GNU Emacs.
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;
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
/***********************************************************************
Starting and ending an update
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))
- {
- width += LGLYPH_WIDTH (g);
- continue;
- }
- if (from < i)
+ if (j < 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;
}
}
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);
position = s->font->underline_position;
else if (s->font)
position = (s->font->descent + 1) / 2;
+ else
+ position = underline_minimum_offset;
}
position = max (position, underline_minimum_offset);
}
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));
inev.ie.code = XFASTINT (c);
goto done_keysym;
}
-
+
/* Random non-modifier sorts of keysyms. */
if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
|| keysym == XK_Delete
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;
XTread_socket_fake_io_error = 0;
x_io_error_quitter (terminal->display_info.x->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. */
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);
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)
&& FRAME_X_P (XFRAME (minibuf_frame))
&& ! EQ (frame, minibuf_frame)
&& FRAME_X_DISPLAY_INFO (XFRAME (minibuf_frame)) == dpyinfo)
- Fdelete_frame (frame, Qnoelisp);
+ delete_frame (frame, Qnoelisp);
}
/* Now delete all remaining frames on the dead display.
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
+ /* Set this to t so that delete_frame won't get confused
trying to find a replacement. */
FRAME_KBOARD (XFRAME (frame))->Vdefault_minibuffer_frame = Qt;
- Fdelete_frame (frame, Qnoelisp);
+ delete_frame (frame, Qnoelisp);
}
/* We have to close the display to inform Xt that it doesn't
#ifdef HAVE_XIM
if (use_xim)
{
+ if (dpyinfo->xim)
+ XCloseIM (dpyinfo->xim);
xim = XOpenIM (dpyinfo->display, dpyinfo->xrdb, resource_name,
EMACS_CLASS);
dpyinfo->xim = xim;
#ifdef HAVE_X11R6_XIM
-struct xim_inst_t
-{
- struct x_display_info *dpyinfo;
- char *resource_name;
-};
-
/* XIM instantiate callback function, which is called whenever an XIM
server is available. DISPLAY is the display of the XIM.
CLIENT_DATA contains a pointer to an xim_inst_t structure created
struct x_display_info *dpyinfo;
char *resource_name;
{
+ dpyinfo->xim = NULL;
#ifdef HAVE_XIM
if (use_xim)
{
struct xim_inst_t *xim_inst;
int len;
- dpyinfo->xim = NULL;
xim_inst = (struct xim_inst_t *) xmalloc (sizeof (struct xim_inst_t));
+ dpyinfo->xim_callback_data = xim_inst;
xim_inst->dpyinfo = dpyinfo;
len = strlen (resource_name);
xim_inst->resource_name = (char *) xmalloc (len + 1);
least, hence the configure test. */
(XRegisterIMInstantiateCallback_arg6) xim_inst);
#else /* not HAVE_X11R6_XIM */
- dpyinfo->xim = NULL;
xim_open_dpy (dpyinfo, resource_name);
#endif /* not HAVE_X11R6_XIM */
-
}
- else
#endif /* HAVE_XIM */
- dpyinfo->xim = NULL;
}
XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
NULL, EMACS_CLASS,
xim_instantiate_callback, NULL);
-#endif /* not HAVE_X11R6_XIM */
+ xfree (dpyinfo->xim_callback_data->resource_name);
+ xfree (dpyinfo->xim_callback_data);
+#endif /* HAVE_X11R6_XIM */
if (dpyinfo->display)
XCloseIM (dpyinfo->xim);
dpyinfo->xim = NULL;
/* 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
if (f->output_data.x->black_relief.allocated_p)
unload_color (f, f->output_data.x->black_relief.pixel);
- if (FRAME_FACE_CACHE (f))
- free_frame_faces (f);
-
x_free_gcs (f);
XFlush (FRAME_X_DISPLAY (f));
}
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.
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->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 */
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;
dpyinfo->x_focus_frame = 0;
dpyinfo->x_focus_event_frame = 0;
dpyinfo->x_highlight_frame = 0;
- dpyinfo->terminal->image_cache = make_image_cache ();
dpyinfo->wm_type = X_WMTYPE_UNKNOWN;
/* See if we can construct pixel values from RGB values. */
connection = ConnectionNumber (dpyinfo->display);
dpyinfo->connection = connection;
- {
- char null_bits[1];
-
- null_bits[0] = 0x00;
-
- dpyinfo->null_pixel
- = XCreatePixmapFromBitmapData (dpyinfo->display, dpyinfo->root_window,
- null_bits, 1, 1, (long) 0, (long) 0,
- 1);
- }
-
{
extern int gray_bitmap_width, gray_bitmap_height;
extern char *gray_bitmap_bits;
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
-#endif
-#ifdef HAVE_X_I18N
- if (dpyinfo->xim)
- xim_close_dpy (dpyinfo);
#endif
xfree (dpyinfo->x_id_name);
+ xfree (dpyinfo->x_dnd_atoms);
xfree (dpyinfo->color_cells);
xfree (dpyinfo);
}
struct x_display_info *dpyinfo = terminal->display_info.x;
int i;
- /* Protect against recursive calls. Fdelete_frame in
+ /* Protect against recursive calls. delete_frame in
delete_terminal calls us back when it deletes our last frame. */
if (!terminal->name)
return;
BLOCK_INPUT;
+#ifdef HAVE_X_I18N
+ /* We must close our connection to the XIM server before closing the
+ X display. */
+ if (dpyinfo->xim)
+ xim_close_dpy (dpyinfo);
+#endif
+
/* If called from x_connection_closed, the display may already be closed
and dpyinfo->display was set to 0 to indicate that. */
if (dpyinfo->display)
x_create_terminal (struct x_display_info *dpyinfo)
{
struct terminal *terminal;
-
+
terminal = create_terminal ();
terminal->type = output_x_window;
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->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;