/* #include <sys/param.h> */
#include "charset.h"
+#include "coding.h"
#include "ccl.h"
#include "frame.h"
#include "dispextern.h"
}
else
{
- XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
- 0, 0, s->img->width, s->img->height, x, y);
+ unsigned long mask = GCClipXOrigin | GCClipYOrigin | GCFunction;
+ XGCValues xgcv;
+ XRectangle clip_rect, image_rect, r;
+
+ x_get_glyph_string_clip_rect (s, &clip_rect);
+ image_rect.x = x;
+ image_rect.y = y;
+ image_rect.width = s->img->width;
+ image_rect.height = s->img->height;
+ if (x_intersect_rectangles (&clip_rect, &image_rect, &r))
+ XCopyArea (s->display, s->img->pixmap, s->window, s->gc,
+ r.x - x, r.y - y, r.width, r.height, r.x, r.y);
/* When the image has a mask, we can expect that at
least part of a mouse highlight or a block cursor will
enough space for all, and try again. */
len = 10;
overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
- noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL);
+ noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
if (noverlays > len)
{
len = noverlays;
overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
- noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL);
+ noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
}
-
+
+ /* Sort overlays into increasing priority order. */
noverlays = sort_overlays (overlay_vec, noverlays, w);
/* Check mouse-face highlighting. */
/* Find the highest priority overlay that has a mouse-face prop. */
overlay = Qnil;
- for (i = 0; i < noverlays; i++)
+ for (i = noverlays - 1; i >= 0; --i)
{
mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
if (!NILP (mouse_face))
/* Look for a `help-echo' property. */
{
- Lisp_Object help, object, position;
+ Lisp_Object help, overlay;
/* Check overlays first. */
help = Qnil;
- for (i = 0; i < noverlays && NILP (help); ++i)
- help = Foverlay_get (overlay_vec[i], Qhelp_echo);
+ for (i = noverlays - 1; i >= 0 && NILP (help); --i)
+ {
+ overlay = overlay_vec[i];
+ help = Foverlay_get (overlay, Qhelp_echo);
+ }
if (!NILP (help))
{
help_echo = help;
help_echo_window = window;
- help_echo_object = w->buffer;
+ help_echo_object = overlay;
help_echo_pos = pos;
}
else
struct frame *f;
int event_found = 0;
struct x_display_info *dpyinfo;
+ struct coding_system coding;
if (interrupt_input_blocked)
{
++handling_signal;
+ /* The input should be decoded if it is from XIM. Currently the
+ locale of XIM is the same as that of the system. So, we can use
+ Vlocale_coding_system which is initialized properly at Emacs
+ startup time. */
+ setup_coding_system (Vlocale_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;
+
/* 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)
if (f != 0)
{
KeySym keysym, orig_keysym;
- /* al%imercury@uunet.uu.net says that making this 81 instead of
- 80 fixed a bug whereby meta chars made his Emacs hang. */
- unsigned char copy_buffer[81];
+ /* al%imercury@uunet.uu.net says that making this 81
+ instead of 80 fixed a bug whereby meta chars made
+ his Emacs hang.
+
+ It seems that some version of XmbLookupString has
+ a bug of not returning XBufferOverflow in
+ status_return even if the input is too long to
+ fit in 81 bytes. So, we must prepare sufficient
+ bytes for copy_buffer. 513 bytes (256 chars for
+ two-byte character set) seems to be a faily good
+ approximation. -- 2000.8.10 handa@etl.go.jp */
+ unsigned char copy_buffer[513];
+ unsigned char *copy_bufptr = copy_buffer;
+ int copy_bufsiz = sizeof (copy_buffer);
int modifiers;
event.xkey.state
#ifdef HAVE_X_I18N
if (FRAME_XIC (f))
{
- unsigned char *copy_bufptr = copy_buffer;
- int copy_bufsiz = sizeof (copy_buffer);
Status status_return;
nbytes = XmbLookupString (FRAME_XIC (f),
abort ();
}
else
- nbytes = XLookupString (&event.xkey, copy_buffer,
- 80, &keysym, &compose_status);
+ nbytes = XLookupString (&event.xkey, copy_bufptr,
+ copy_bufsiz, &keysym,
+ &compose_status);
#else
- nbytes = XLookupString (&event.xkey, copy_buffer,
- 80, &keysym, &compose_status);
+ nbytes = XLookupString (&event.xkey, copy_bufptr,
+ copy_bufsiz, &keysym,
+ &compose_status);
#endif
orig_keysym = keysym;
else if (numchars > nbytes)
{
register int i;
+ register int c;
+ unsigned char *p, *pend;
+ int nchars, len;
for (i = 0; i < nbytes; i++)
{
- if (temp_index == sizeof temp_buffer / sizeof (short))
+ if (temp_index == (sizeof temp_buffer
+ / sizeof (short)))
temp_index = 0;
- temp_buffer[temp_index++] = copy_buffer[i];
- bufp->kind = ascii_keystroke;
- bufp->code = copy_buffer[i];
+ temp_buffer[temp_index++] = copy_bufptr[i];
+ }
+
+ if (/* If the event is not from XIM, */
+ event.xkey.keycode != 0
+ /* or the current locale doesn't request
+ decoding of the intup data, ... */
+ || coding.type == coding_type_raw_text
+ || coding.type == coding_type_no_conversion)
+ {
+ /* ... we can use the input data as is. */
+ nchars = nbytes;
+ }
+ else
+ {
+ /* We have to 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;
+ decode_coding (&coding, copy_bufptr, p,
+ nbytes, require);
+ nbytes = coding.produced;
+ nchars = coding.produced_char;
+ copy_bufptr = p;
+ }
+
+ /* Convert the input data to a sequence of
+ character events. */
+ for (i = 0; i < nbytes; i += len)
+ {
+ c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
+ nbytes - i, len);
+ bufp->kind = (SINGLE_BYTE_CHAR_P (c)
+ ? ascii_keystroke
+ : multibyte_char_keystroke);
+ bufp->code = c;
XSETFRAME (bufp->frame_or_window, f);
bufp->arg = Qnil;
bufp->modifiers
bufp++;
}
- count += nbytes;
- numchars -= nbytes;
+ count += nchars;
+ numchars -= nchars;
if (keysym == NoSymbol)
break;
int n;
XSETFRAME (frame, f);
- n = gen_help_event (bufp, Qnil, frame, Qnil, Qnil, 0);
+ n = gen_help_event (bufp, numchars,
+ Qnil, frame, Qnil, Qnil, 0);
bufp += n, count += n, numchars -= n;
}
frame = Qnil;
any_help_event_p = 1;
- n = gen_help_event (bufp, help_echo, frame,
+ n = gen_help_event (bufp, numchars, help_echo, frame,
help_echo_window, help_echo_object,
help_echo_pos);
bufp += n, count += n, numchars -= n;
struct glyph_row *row;
int width;
{
- /* If cursor hpos is out of bounds, don't draw garbage. This can
- happen in mini-buffer windows when switching between echo area
- glyphs and mini-buffer. */
- if (w->phys_cursor.hpos < row->used[TEXT_AREA])
- {
- struct frame *f = XFRAME (w->frame);
- struct glyph *cursor_glyph;
- GC gc;
- int x;
- unsigned long mask;
- XGCValues xgcv;
- Display *dpy;
- Window window;
+ struct frame *f = XFRAME (w->frame);
+ struct glyph *cursor_glyph;
+ GC gc;
+ int x;
+ unsigned long mask;
+ XGCValues xgcv;
+ Display *dpy;
+ Window window;
- cursor_glyph = get_phys_cursor_glyph (w);
- if (cursor_glyph == NULL)
- return;
+ /* If cursor is out of bounds, don't draw garbage. This can happen
+ in mini-buffer windows when switching between echo area glyphs
+ and mini-buffer. */
+ cursor_glyph = get_phys_cursor_glyph (w);
+ if (cursor_glyph == NULL)
+ return;
+ /* If on an image, draw like a normal cursor. That's usually better
+ visible than drawing a bar, esp. if the image is large so that
+ the bar might not be in the window. */
+ if (cursor_glyph->type == IMAGE_GLYPH)
+ {
+ struct glyph_row *row;
+ row = MATRIX_ROW (w->current_matrix, w->phys_cursor.vpos);
+ x_draw_phys_cursor_glyph (w, row, DRAW_CURSOR);
+ }
+ else
+ {
xgcv.background = f->output_data.x->cursor_pixel;
xgcv.foreground = f->output_data.x->cursor_pixel;
xgcv.graphics_exposures = 0;
dpy = FRAME_X_DISPLAY (f);
window = FRAME_X_WINDOW (f);
gc = FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc;
-
+
if (gc)
XChangeGC (dpy, gc, mask, &xgcv);
else
gc = XCreateGC (dpy, window, mask, &xgcv);
FRAME_X_DISPLAY_INFO (f)->scratch_cursor_gc = gc;
}
-
+
if (width < 0)
width = f->output_data.x->cursor_width;
-
+
x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
x_clip_to_row (w, row, gc, 0);
XFillRectangle (dpy, window, gc,