/* #include <sys/param.h> */
#include "charset.h"
+#include "coding.h"
#include "ccl.h"
#include "frame.h"
#include "dispextern.h"
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. */
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,