X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/5bc624834eeabb49b6c319d08bbd46f5777a9baa..8030369ccb5c871d3ce11b96c220f318bc741ed8:/src/xterm.c diff --git a/src/xterm.c b/src/xterm.c index 73e987531a..338fd65613 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -98,7 +98,7 @@ Boston, MA 02111-1307, USA. */ #endif #ifdef USE_LUCID -extern int xlwmenu_window_p (Widget w, Window window); +extern int xlwmenu_window_p P_ ((Widget w, Window window)); extern void xlwmenu_redisplay P_ ((Widget)); #endif @@ -255,9 +255,9 @@ static int any_help_event_p; /* Non-zero means autoselect window with the mouse cursor. */ -int autoselect_window_p; +int mouse_autoselect_window; -/* Last window where we saw the mouse. Used by autoselect-window. */ +/* Last window where we saw the mouse. Used by mouse-autoselect-window. */ static Lisp_Object last_window; /* Non-zero means draw block and hollow cursor as wide as the glyph @@ -394,6 +394,7 @@ Lisp_Object Vx_alt_keysym, Vx_hyper_keysym, Vx_meta_keysym, Vx_super_keysym; static Lisp_Object Qalt, Qhyper, Qmeta, Qsuper, Qmodifier_value; static Lisp_Object Qvendor_specific_keysyms; +static Lisp_Object Qlatin_1, Qutf_8; extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *)); extern Lisp_Object x_icon_type P_ ((struct frame *)); @@ -429,7 +430,8 @@ static int fast_find_string_pos P_ ((struct window *, int, Lisp_Object, static void set_output_cursor P_ ((struct cursor_pos *)); static struct glyph *x_y_to_hpos_vpos P_ ((struct window *, int, int, int *, int *, int *, int)); -static void note_mode_line_highlight P_ ((struct window *, int, int)); +static void note_mode_line_or_margin_highlight P_ ((struct window *, int, + int, int)); static void note_mouse_highlight P_ ((struct frame *, int, int)); static void note_tool_bar_highlight P_ ((struct frame *f, int, int)); static void x_handle_tool_bar_click P_ ((struct frame *, XButtonEvent *)); @@ -464,14 +466,27 @@ static void x_clear_cursor P_ ((struct window *)); static void frame_highlight P_ ((struct frame *)); static void frame_unhighlight P_ ((struct frame *)); static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *)); +static int x_focus_changed P_ ((int, + int, + struct x_display_info *, + struct frame *, + struct input_event *, + int)); +static int x_detect_focus_change P_ ((struct x_display_info *, + XEvent *, + struct input_event *, + int)); static void XTframe_rehighlight P_ ((struct frame *)); static void x_frame_rehighlight P_ ((struct x_display_info *)); static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *)); -static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int)); +static void x_draw_bar_cursor P_ ((struct window *, struct glyph_row *, int, + enum text_cursor_kinds)); static int x_intersect_rectangles P_ ((XRectangle *, XRectangle *, XRectangle *)); static void expose_frame P_ ((struct frame *, int, int, int, int)); static int expose_window_tree P_ ((struct window *, XRectangle *)); +static void expose_overlaps P_ ((struct window *, struct glyph_row *, + struct glyph_row *)); static int expose_window P_ ((struct window *, XRectangle *)); static void expose_area P_ ((struct window *, struct glyph_row *, XRectangle *, enum glyph_row_area)); @@ -851,7 +866,7 @@ x_draw_fringe_bitmap (w, row, which, left_p) Window window = FRAME_X_WINDOW (f); int x, y, wd, h, dy; int b1, b2; - unsigned char *bits; + unsigned char *bits = NULL; Pixmap pixmap; GC gc = f->output_data.x->normal_gc; struct face *face; @@ -4113,8 +4128,12 @@ x_draw_image_foreground (s) the image. I believe it's looking better if we do nothing here for mouse-face. */ if (s->hl == DRAW_CURSOR) - XDrawRectangle (s->display, s->window, s->gc, x, y, - s->img->width - 1, s->img->height - 1); + { + int r = s->img->relief; + if (r < 0) r = -r; + XDrawRectangle (s->display, s->window, s->gc, x - r, y - r, + s->img->width + r*2 - 1, s->img->height + r*2 - 1); + } } } else @@ -4229,8 +4248,12 @@ x_draw_image_foreground_1 (s, pixmap) the image. I believe it's looking better if we do nothing here for mouse-face. */ if (s->hl == DRAW_CURSOR) - XDrawRectangle (s->display, pixmap, s->gc, x, y, - s->img->width - 1, s->img->height - 1); + { + int r = s->img->relief; + if (r < 0) r = -r; + XDrawRectangle (s->display, s->window, s->gc, x - r, y - r, + s->img->width + r*2 - 1, s->img->height + r*2 - 1); + } } } else @@ -5320,6 +5343,14 @@ x_write_glyphs (start, len) hpos, hpos + len, DRAW_NORMAL_TEXT, 0); + /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */ + if (updated_area == TEXT_AREA + && updated_window->phys_cursor_on_p + && updated_window->phys_cursor.vpos == output_cursor.vpos + && updated_window->phys_cursor.hpos >= hpos + && updated_window->phys_cursor.hpos < hpos + len) + updated_window->phys_cursor_on_p = 0; + UNBLOCK_INPUT; /* Advance the output cursor. */ @@ -6041,6 +6072,39 @@ x_phys_cursor_in_rect_p (w, r) } +/* Redraw those parts of glyphs rows during expose event handling that + overlap other rows. Redrawing of an exposed line writes over parts + of lines overlapping that exposed line; this function fixes that. + + W is the window being exposed. FIRST_OVERLAPPING_ROW is the first + row in W's current matrix that is exposed and overlaps other rows. + LAST_OVERLAPPING_ROW is the last such row. */ + +static void +expose_overlaps (w, first_overlapping_row, last_overlapping_row) + struct window *w; + struct glyph_row *first_overlapping_row; + struct glyph_row *last_overlapping_row; +{ + struct glyph_row *row; + + for (row = first_overlapping_row; row <= last_overlapping_row; ++row) + if (row->overlapping_p) + { + xassert (row->enabled_p && !row->mode_line_p); + + if (row->used[LEFT_MARGIN_AREA]) + x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA); + + if (row->used[TEXT_AREA]) + x_fix_overlapping_area (w, row, TEXT_AREA); + + if (row->used[RIGHT_MARGIN_AREA]) + x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA); + } +} + + /* Redraw the part of window W intersection rectangle FR. Pixel coordinates in FR are frame-relative. Call this function with input blocked. Value is non-zero if the exposure overwrites @@ -6082,6 +6146,7 @@ expose_window (w, fr) int yb = window_text_bottom_y (w); struct glyph_row *row; int cursor_cleared_p; + struct glyph_row *first_overlapping_row, *last_overlapping_row; TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height)); @@ -6100,7 +6165,8 @@ expose_window (w, fr) else cursor_cleared_p = 0; - /* Find the first row intersecting the rectangle R. */ + /* Update lines intersecting rectangle R. */ + first_overlapping_row = last_overlapping_row = NULL; for (row = w->current_matrix->rows; row->enabled_p; ++row) @@ -6113,6 +6179,13 @@ expose_window (w, fr) || (r.y >= y0 && r.y < y1) || (r.y + r.height > y0 && r.y + r.height < y1)) { + if (row->overlapping_p) + { + if (first_overlapping_row == NULL) + first_overlapping_row = row; + last_overlapping_row = row; + } + if (expose_line (w, row, &r)) mouse_face_overwritten_p = 1; } @@ -6133,6 +6206,10 @@ expose_window (w, fr) if (!w->pseudo_window_p) { + /* Fix the display of overlapping rows. */ + if (first_overlapping_row) + expose_overlaps (w, first_overlapping_row, last_overlapping_row); + /* Draw border between windows. */ x_draw_vertical_border (w); @@ -6272,6 +6349,121 @@ x_new_focus_frame (dpyinfo, frame) x_frame_rehighlight (dpyinfo); } +/* Handle FocusIn and FocusOut state changes for FRAME. + If FRAME has focus and there exists more than one frame, puts + an FOCUS_IN_EVENT into BUFP. + Returns number of events inserted into BUFP. */ + +static int +x_focus_changed (type, state, dpyinfo, frame, bufp, numchars) + int type; + int state; + struct x_display_info *dpyinfo; + struct frame *frame; + struct input_event *bufp; + int numchars; +{ + int nr_events = 0; + + if (type == FocusIn) + { + if (dpyinfo->x_focus_event_frame != frame) + { + x_new_focus_frame (dpyinfo, frame); + dpyinfo->x_focus_event_frame = frame; + + /* Don't stop displaying the initial startup message + for a switch-frame event we don't need. */ + if (numchars > 0 + && GC_NILP (Vterminal_frame) + && GC_CONSP (Vframe_list) + && !GC_NILP (XCDR (Vframe_list))) + { + bufp->kind = FOCUS_IN_EVENT; + XSETFRAME (bufp->frame_or_window, frame); + bufp->arg = Qnil; + ++bufp; + numchars--; + ++nr_events; + } + } + + frame->output_data.x->focus_state |= state; + +#ifdef HAVE_X_I18N + if (FRAME_XIC (frame)) + XSetICFocus (FRAME_XIC (frame)); +#endif + } + else if (type == FocusOut) + { + frame->output_data.x->focus_state &= ~state; + + if (dpyinfo->x_focus_event_frame == frame) + { + dpyinfo->x_focus_event_frame = 0; + x_new_focus_frame (dpyinfo, 0); + } + +#ifdef HAVE_X_I18N + if (FRAME_XIC (frame)) + XUnsetICFocus (FRAME_XIC (frame)); +#endif + } + + return nr_events; +} + +/* The focus may have changed. Figure out if it is a real focus change, + by checking both FocusIn/Out and Enter/LeaveNotify events. + + Returns number of events inserted into BUFP. */ + +static int +x_detect_focus_change (dpyinfo, event, bufp, numchars) + struct x_display_info *dpyinfo; + XEvent *event; + struct input_event *bufp; + int numchars; +{ + struct frame *frame; + int nr_events = 0; + + frame = x_top_window_to_frame (dpyinfo, event->xany.window); + if (! frame) return nr_events; + + switch (event->type) + { + case EnterNotify: + case LeaveNotify: + if (event->xcrossing.detail != NotifyInferior + && event->xcrossing.focus + && ! (frame->output_data.x->focus_state & FOCUS_EXPLICIT)) + nr_events = x_focus_changed ((event->type == EnterNotify + ? FocusIn : FocusOut), + FOCUS_IMPLICIT, + dpyinfo, + frame, + bufp, + numchars); + break; + + case FocusIn: + case FocusOut: + nr_events = x_focus_changed (event->type, + (event->xfocus.detail == NotifyPointer + ? FOCUS_IMPLICIT : FOCUS_EXPLICIT), + dpyinfo, + frame, + bufp, + numchars); + break; + } + + return nr_events; +} + + /* Handle an event saying the mouse has moved out of an Emacs frame. */ void @@ -6617,9 +6809,9 @@ construct_mouse_click (result, event, f) XButtonEvent *event; struct frame *f; { - /* Make the event type no_event; we'll change that when we decide + /* Make the event type NO_EVENT; we'll change that when we decide otherwise. */ - result->kind = mouse_click; + result->kind = MOUSE_CLICK_EVENT; result->code = event->button - Button1; result->timestamp = event->time; result->modifiers = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), @@ -6791,80 +6983,54 @@ frame_to_window_pixel_xy (w, x, y) } -/* Take proper action when mouse has moved to the mode or header line of - window W, x-position X. MODE_LINE_P non-zero means mouse is on the - mode line. X is relative to the start of the text display area of - W, so the width of fringes and scroll bars must be subtracted - to get a position relative to the start of the mode line. */ - +/* Take proper action when mouse has moved to the mode or header line + or marginal area of window W, x-position X and y-position Y. Area + is 1, 3, 6 or 7 for the mode line, header line, left and right + marginal area respectively. X is relative to the start of the text + display area of W, so the width of bitmap areas and scroll bars + must be subtracted to get a position relative to the start of the + mode line. */ + static void -note_mode_line_highlight (w, x, mode_line_p) +note_mode_line_or_margin_highlight (w, x, y, portion) struct window *w; - int x, mode_line_p; + int x, y, portion; { struct frame *f = XFRAME (w->frame); struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); Cursor cursor = dpyinfo->vertical_scroll_bar_cursor; - struct glyph_row *row; + int charpos; + Lisp_Object string, help, map, pos; - if (mode_line_p) - row = MATRIX_MODE_LINE_ROW (w->current_matrix); - else - row = MATRIX_HEADER_LINE_ROW (w->current_matrix); + if (portion == 1 || portion == 3) + string = mode_line_string (w, x, y, portion == 1, &charpos); + else + string = marginal_area_string (w, x, y, portion, &charpos); - if (row->enabled_p) + if (STRINGP (string)) { - struct glyph *glyph, *end; - Lisp_Object help, map; - int x0; - - /* Find the glyph under X. */ - glyph = row->glyphs[TEXT_AREA]; - end = glyph + row->used[TEXT_AREA]; - x0 = - (FRAME_LEFT_SCROLL_BAR_WIDTH (f) * CANON_X_UNIT (f) - + FRAME_X_LEFT_FRINGE_WIDTH (f)); + pos = make_number (charpos); - while (glyph < end - && x >= x0 + glyph->pixel_width) + /* If we're on a string with `help-echo' text property, arrange + for the help to be displayed. This is done by setting the + global variable help_echo to the help string. */ + help = Fget_text_property (pos, Qhelp_echo, string); + if (!NILP (help)) { - x0 += glyph->pixel_width; - ++glyph; + help_echo = help; + XSETWINDOW (help_echo_window, w); + help_echo_object = string; + help_echo_pos = charpos; } - if (glyph < end - && STRINGP (glyph->object) - && XSTRING (glyph->object)->intervals - && glyph->charpos >= 0 - && glyph->charpos < XSTRING (glyph->object)->size) - { - /* If we're on a string with `help-echo' text property, - arrange for the help to be displayed. This is done by - setting the global variable help_echo to the help string. */ - help = Fget_text_property (make_number (glyph->charpos), - Qhelp_echo, glyph->object); - if (!NILP (help)) - { - help_echo = help; - XSETWINDOW (help_echo_window, w); - help_echo_object = glyph->object; - help_echo_pos = glyph->charpos; - } - - /* Change the mouse pointer according to what is under X/Y. */ - map = Fget_text_property (make_number (glyph->charpos), - Qlocal_map, glyph->object); - if (KEYMAPP (map)) - cursor = f->output_data.x->nontext_cursor; - else - { - map = Fget_text_property (make_number (glyph->charpos), - Qkeymap, glyph->object); - if (KEYMAPP (map)) - cursor = f->output_data.x->nontext_cursor; - } - } + /* Change the mouse pointer according to what is under X/Y. */ + map = Fget_text_property (pos, Qlocal_map, string); + if (!KEYMAPP (map)) + map = Fget_text_property (pos, Qkeymap, string); + if (KEYMAPP (map)) + cursor = f->output_data.x->nontext_cursor; } - + XDefineCursor (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), cursor); } @@ -6932,10 +7098,10 @@ note_mouse_highlight (f, x, y) return; } - /* Mouse is on the mode or header line? */ - if (portion == 1 || portion == 3) + /* Mouse is on the mode, header line or margin? */ + if (portion == 1 || portion == 3 || portion == 6 || portion == 7) { - note_mode_line_highlight (w, x, portion == 1); + note_mode_line_or_margin_highlight (w, x, y, portion); return; } @@ -7151,7 +7317,7 @@ note_mouse_highlight (f, x, y) if (NILP (b)) b = make_number (0); if (NILP (e)) - e = make_number (XSTRING (object)->size - 1); + e = make_number (SCHARS (object) - 1); fast_find_string_pos (w, XINT (b), object, &dpyinfo->mouse_face_beg_col, &dpyinfo->mouse_face_beg_row, @@ -7249,7 +7415,7 @@ note_mouse_highlight (f, x, y) /* Try text properties. */ if (STRINGP (object) && charpos >= 0 - && charpos < XSTRING (object)->size) + && charpos < SCHARS (object)) { help = Fget_text_property (make_number (charpos), Qhelp_echo, object); @@ -8332,7 +8498,7 @@ static Boolean xaw3d_pick_top; /* Action hook installed via XtAppAddActionHook when toolkit scroll bars are used.. The hook is responsible for detecting when the user ends an interaction with the scroll bar, and generates - a `end-scroll' scroll_bar_click' event if so. */ + a `end-scroll' SCROLL_BAR_CLICK_EVENT' event if so. */ static void xt_action_hook (widget, client_data, action_name, event, params, @@ -8462,7 +8628,7 @@ x_scroll_bar_to_input_event (event, ievent) XSETWINDOW (window, w); f = XFRAME (w->frame); - ievent->kind = scroll_bar_click; + ievent->kind = SCROLL_BAR_CLICK_EVENT; ievent->frame_or_window = window; ievent->arg = Qnil; ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f)); @@ -8485,7 +8651,7 @@ x_scroll_bar_to_input_event (event, ievent) /* Scroll bar callback for Motif scroll bars. WIDGET is the scroll bar widget. CLIENT_DATA is a pointer to the scroll_bar structure. - CALL_DATA is a pointer a a XmScrollBarCallbackStruct. */ + CALL_DATA is a pointer to a XmScrollBarCallbackStruct. */ static void xm_scroll_callback (widget, client_data, call_data) @@ -8819,7 +8985,7 @@ x_create_toolkit_scroll_bar (f, bar) #endif /* !USE_MOTIF */ - /* Install an action hook that let's us detect when the user + /* Install an action hook that lets us detect when the user finishes interacting with a scroll bar. */ if (action_hook_id == 0) action_hook_id = XtAppAddActionHook (Xt_app_con, xt_action_hook, 0); @@ -9520,7 +9686,7 @@ x_scroll_bar_expose (bar, event) } /* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind - is set to something other than no_event, it is enqueued. + is set to something other than NO_EVENT, it is enqueued. This may be called from a signal handler, so we have to ignore GC mark bits. */ @@ -9536,7 +9702,7 @@ x_scroll_bar_handle_click (bar, event, emacs_event) if (! GC_WINDOWP (bar->window)) abort (); - emacs_event->kind = scroll_bar_click; + emacs_event->kind = SCROLL_BAR_CLICK_EVENT; emacs_event->code = event->xbutton.button - Button1; emacs_event->modifiers = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO @@ -9903,7 +10069,7 @@ static struct x_display_info *next_noop_dpyinfo; bcopy (&event, f->output_data.x->saved_menu_event, size); \ if (numchars >= 1) \ { \ - bufp->kind = menu_bar_activate_event; \ + bufp->kind = MENU_BAR_ACTIVATE_EVENT; \ XSETFRAME (bufp->frame_or_window, f); \ bufp->arg = Qnil; \ bufp++; \ @@ -9959,18 +10125,6 @@ XTread_socket (sd, bufp, numchars, expected) ++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) @@ -10132,7 +10286,7 @@ XTread_socket (sd, bufp, numchars, expected) if (numchars == 0) abort (); - bufp->kind = delete_window_event; + bufp->kind = DELETE_WINDOW_EVENT; XSETFRAME (bufp->frame_or_window, f); bufp->arg = Qnil; bufp++; @@ -10222,7 +10376,7 @@ XTread_socket (sd, bufp, numchars, expected) if (numchars == 0) abort (); - bufp->kind = selection_clear_event; + bufp->kind = SELECTION_CLEAR_EVENT; SELECTION_EVENT_DISPLAY (bufp) = eventp->display; SELECTION_EVENT_SELECTION (bufp) = eventp->selection; SELECTION_EVENT_TIME (bufp) = eventp->time; @@ -10251,7 +10405,7 @@ XTread_socket (sd, bufp, numchars, expected) if (numchars == 0) abort (); - bufp->kind = selection_request_event; + bufp->kind = SELECTION_REQUEST_EVENT; SELECTION_EVENT_DISPLAY (bufp) = eventp->display; SELECTION_EVENT_REQUESTOR (bufp) = eventp->requestor; SELECTION_EVENT_SELECTION (bufp) = eventp->selection; @@ -10391,7 +10545,7 @@ XTread_socket (sd, bufp, numchars, expected) { f->async_iconified = 1; - bufp->kind = iconify_event; + bufp->kind = ICONIFY_EVENT; XSETFRAME (bufp->frame_or_window, f); bufp->arg = Qnil; bufp++; @@ -10423,7 +10577,7 @@ XTread_socket (sd, bufp, numchars, expected) if (f->iconified) { - bufp->kind = deiconify_event; + bufp->kind = DEICONIFY_EVENT; XSETFRAME (bufp->frame_or_window, f); bufp->arg = Qnil; bufp++; @@ -10440,6 +10594,11 @@ XTread_socket (sd, bufp, numchars, expected) goto OTHER; case KeyPress: + + /* Dispatch KeyPress events when in menu. */ + if (popup_activated_flag) + goto OTHER; + f = x_any_window_to_frame (dpyinfo, event.xkey.window); if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)) @@ -10481,6 +10640,7 @@ XTread_socket (sd, bufp, numchars, expected) unsigned char *copy_bufptr = copy_buffer; int copy_bufsiz = sizeof (copy_buffer); int modifiers; + Lisp_Object coding_system = Qlatin_1; event.xkey.state |= x_emacs_to_x_modifiers (FRAME_X_DISPLAY_INFO (f), @@ -10510,6 +10670,7 @@ XTread_socket (sd, bufp, numchars, expected) { Status status_return; + coding_system = Vlocale_coding_system; nbytes = XmbLookupString (FRAME_XIC (f), &event.xkey, copy_bufptr, copy_bufsiz, &keysym, @@ -10523,6 +10684,27 @@ XTread_socket (sd, bufp, numchars, expected) copy_bufsiz, &keysym, &status_return); } +/* Xutf8LookupString is a new but already deprecated interface. -stef */ +#if 0 && defined X_HAVE_UTF8_STRING + else if (status_return == XLookupKeySym) + { /* Try again but with utf-8. */ + coding_system = Qutf_8; + nbytes = Xutf8LookupString (FRAME_XIC (f), + &event.xkey, copy_bufptr, + copy_bufsiz, &keysym, + &status_return); + if (status_return == XBufferOverflow) + { + copy_bufsiz = nbytes + 1; + copy_bufptr = (char *) alloca (copy_bufsiz); + nbytes = Xutf8LookupString (FRAME_XIC (f), + &event.xkey, + copy_bufptr, + copy_bufsiz, &keysym, + &status_return); + } + } +#endif if (status_return == XLookupNone) break; @@ -10631,7 +10813,7 @@ XTread_socket (sd, bufp, numchars, expected) if (temp_index == sizeof temp_buffer / sizeof (short)) temp_index = 0; temp_buffer[temp_index++] = keysym; - bufp->kind = non_ascii_keystroke; + bufp->kind = NON_ASCII_KEYSTROKE_EVENT; bufp->code = keysym; XSETFRAME (bufp->frame_or_window, f); bufp->arg = Qnil; @@ -10649,6 +10831,17 @@ XTread_socket (sd, bufp, numchars, expected) register int c; int nchars, len; + /* The input should be decoded with `coding_system' + which depends on which X*LookupString function + we used just above and the locale. */ + setup_coding_system (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; + for (i = 0; i < nbytes; i++) { if (temp_index == (sizeof temp_buffer @@ -10657,31 +10850,25 @@ XTread_socket (sd, bufp, numchars, expected) 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; - } + { + /* 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; + /* We explicitely disable composition + handling because key data should + not contain any composition + sequence. */ + coding.composing = COMPOSITION_DISABLED; + 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. */ @@ -10694,8 +10881,8 @@ XTread_socket (sd, bufp, numchars, expected) nbytes - i, len); bufp->kind = (SINGLE_BYTE_CHAR_P (c) - ? ascii_keystroke - : multibyte_char_keystroke); + ? ASCII_KEYSTROKE_EVENT + : MULTIBYTE_CHAR_KEYSTROKE_EVENT); bufp->code = c; XSETFRAME (bufp->frame_or_window, f); bufp->arg = Qnil; @@ -10737,15 +10924,16 @@ XTread_socket (sd, bufp, numchars, expected) goto OTHER; #endif - /* Here's a possible interpretation of the whole - FocusIn-EnterNotify FocusOut-LeaveNotify mess. If - you get a FocusIn event, you have to get a FocusOut - event before you relinquish the focus. If you - haven't received a FocusIn event, then a mere - LeaveNotify is enough to free you. */ - case EnterNotify: { + int n; + + n = x_detect_focus_change (dpyinfo, &event, bufp, numchars); + if (n > 0) + { + bufp += n, count += n, numchars -= n; + } + f = x_any_window_to_frame (dpyinfo, event.xcrossing.window); #if 0 @@ -10772,34 +10960,29 @@ XTread_socket (sd, bufp, numchars, expected) } case FocusIn: - f = x_any_window_to_frame (dpyinfo, event.xfocus.window); - if (event.xfocus.detail != NotifyPointer) - dpyinfo->x_focus_event_frame = f; - if (f) - { - x_new_focus_frame (dpyinfo, f); + { + int n; - /* Don't stop displaying the initial startup message - for a switch-frame event we don't need. */ - if (GC_NILP (Vterminal_frame) - && GC_CONSP (Vframe_list) - && !GC_NILP (XCDR (Vframe_list))) - { - bufp->kind = FOCUS_IN_EVENT; - XSETFRAME (bufp->frame_or_window, f); - bufp->arg = Qnil; - ++bufp, ++count, --numchars; - } - } - -#ifdef HAVE_X_I18N - if (f && FRAME_XIC (f)) - XSetICFocus (FRAME_XIC (f)); -#endif + n = x_detect_focus_change (dpyinfo, &event, bufp, numchars); + if (n > 0) + { + bufp += n, count += n, numchars -= n; + } + } goto OTHER; case LeaveNotify: + { + int n; + + n = x_detect_focus_change (dpyinfo, &event, bufp, numchars); + if (n > 0) + { + bufp += n, count += n, numchars -= n; + } + } + f = x_top_window_to_frame (dpyinfo, event.xcrossing.window); if (f) { @@ -10827,32 +11010,19 @@ XTread_socket (sd, bufp, numchars, expected) bufp += n, count += n, numchars -= n; } -#if 0 - if (event.xcrossing.focus) - x_mouse_leave (dpyinfo); - else - { - if (f == dpyinfo->x_focus_event_frame) - dpyinfo->x_focus_event_frame = 0; - if (f == dpyinfo->x_focus_frame) - x_new_focus_frame (dpyinfo, 0); - } -#endif } goto OTHER; case FocusOut: - f = x_any_window_to_frame (dpyinfo, event.xfocus.window); - if (event.xfocus.detail != NotifyPointer - && f == dpyinfo->x_focus_event_frame) - dpyinfo->x_focus_event_frame = 0; - if (f && f == dpyinfo->x_focus_frame) - x_new_focus_frame (dpyinfo, 0); + { + int n; -#ifdef HAVE_X_I18N - if (f && FRAME_XIC (f)) - XUnsetICFocus (FRAME_XIC (f)); -#endif + n = x_detect_focus_change (dpyinfo, &event, bufp, numchars); + if (n > 0) + { + bufp += n, count += n, numchars -= n; + } + } goto OTHER; @@ -10878,19 +11048,20 @@ XTread_socket (sd, bufp, numchars, expected) { /* Generate SELECT_WINDOW_EVENTs when needed. */ - if (autoselect_window_p) + if (mouse_autoselect_window) { Lisp_Object window; int area; window = window_from_coordinates (f, - XINT (event.xmotion.x), XINT (event.xmotion.y), + event.xmotion.x, event.xmotion.y, &area, 0); /* Window will be selected only when it is not selected now and last mouse movement event was not in it. Minibuffer window will be selected iff it is active. */ - if (!EQ (window, last_window) + if (WINDOWP(window) + && !EQ (window, last_window) && !EQ (window, selected_window) && numchars > 0) { @@ -11022,7 +11193,7 @@ XTread_socket (sd, bufp, numchars, expected) struct input_event emacs_event; int tool_bar_p = 0; - emacs_event.kind = no_event; + emacs_event.kind = NO_EVENT; bzero (&compose_status, sizeof (compose_status)); if (dpyinfo->grabbed @@ -11088,7 +11259,7 @@ XTread_socket (sd, bufp, numchars, expected) dpyinfo->grabbed &= ~(1 << event.xbutton.button); } - if (numchars >= 1 && emacs_event.kind != no_event) + if (numchars >= 1 && emacs_event.kind != NO_EVENT) { bcopy (&emacs_event, bufp, sizeof (struct input_event)); bufp++; @@ -11233,13 +11404,36 @@ notice_overwritten_cursor (w, area, x0, x1, y0, y1) enum glyph_row_area area; int x0, y0, x1, y1; { - if (area == TEXT_AREA - && w->phys_cursor_on_p - && y0 <= w->phys_cursor.y - && y1 >= w->phys_cursor.y + w->phys_cursor_height - && x0 <= w->phys_cursor.x - && (x1 < 0 || x1 > w->phys_cursor.x)) - w->phys_cursor_on_p = 0; + if (area == TEXT_AREA && w->phys_cursor_on_p) + { + int cx0 = w->phys_cursor.x; + int cx1 = cx0 + w->phys_cursor_width; + int cy0 = w->phys_cursor.y; + int cy1 = cy0 + w->phys_cursor_height; + + if (x0 <= cx0 && (x1 < 0 || x1 >= cx1)) + { + /* The cursor image will be completely removed from the + screen if the output area intersects the cursor area in + y-direction. When we draw in [y0 y1[, and some part of + the cursor is at y < y0, that part must have been drawn + before. When scrolling, the cursor is erased before + actually scrolling, so we don't come here. When not + scrolling, the rows above the old cursor row must have + changed, and in this case these rows must have written + over the cursor image. + + Likewise if part of the cursor is below y1, with the + exception of the cursor being in the first blank row at + the buffer and window end because update_text_area + doesn't draw that row. (Except when it does, but + that's handled in update_text_area.) */ + + if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1)) + && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p) + w->phys_cursor_on_p = 0; + } + } } @@ -11319,6 +11513,7 @@ x_draw_hollow_cursor (w, row) if (cursor_glyph->type == STRETCH_GLYPH && !x_stretch_cursor_p) wd = min (CANON_X_UNIT (f), wd); + w->phys_cursor_width = wd; /* The foreground of cursor_gc is typically the same as the normal background color, which can cause the cursor box to be invisible. */ @@ -11345,10 +11540,11 @@ x_draw_hollow_cursor (w, row) --gerd. */ static void -x_draw_bar_cursor (w, row, width) +x_draw_bar_cursor (w, row, width, kind) struct window *w; struct glyph_row *row; int width; + enum text_cursor_kinds kind; { struct frame *f = XFRAME (w->frame); struct glyph *cursor_glyph; @@ -11401,11 +11597,22 @@ x_draw_bar_cursor (w, row, width) width = f->output_data.x->cursor_width; width = min (cursor_glyph->pixel_width, width); + w->phys_cursor_width = width; x_clip_to_row (w, row, gc, 0); - XFillRectangle (dpy, window, gc, - WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x), - WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), - width, row->height); + + if (kind == BAR_CURSOR) + XFillRectangle (dpy, window, gc, + WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x), + WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y), + width, row->height); + else + XFillRectangle (dpy, window, gc, + 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, + width); + XSetClipMask (dpy, gc, None); } } @@ -11439,16 +11646,20 @@ x_draw_phys_cursor_glyph (w, row, hl) if (w->phys_cursor.hpos < row->used[TEXT_AREA]) { int on_p = w->phys_cursor_on_p; + int x1; - x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, - w->phys_cursor.hpos, w->phys_cursor.hpos + 1, - hl, 0); + x1 = x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA, + w->phys_cursor.hpos, w->phys_cursor.hpos + 1, + hl, 0); w->phys_cursor_on_p = on_p; + if (hl == DRAW_CURSOR) + w->phys_cursor_width = x1 - w->phys_cursor.x; + /* When we erase the cursor, and ROW is overlapped by other rows, make sure that these overlapping parts of other rows are redrawn. */ - if (hl == DRAW_NORMAL_TEXT && row->overlapped_p) + else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p) { if (row > w->current_matrix->rows && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1)) @@ -11599,10 +11810,10 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y) struct frame *f = XFRAME (w->frame); int new_cursor_type; int new_cursor_width; + int cursor_off_state = 0; struct glyph_matrix *current_glyphs; struct glyph_row *glyph_row; struct glyph *glyph; - int cursor_non_selected; /* This is pointless on invisible frames, and dangerous on garbaged windows and frames; in the latter case, the frame or window may @@ -11638,54 +11849,65 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y) the cursor type given by the frame parameter. If explicitly marked off, draw no cursor. In all other cases, we want a hollow box cursor. */ - cursor_non_selected - = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows, - w->buffer)); new_cursor_width = -1; + new_cursor_type = -2; + + /* Echo area */ if (cursor_in_echo_area && FRAME_HAS_MINIBUF_P (f) && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window)) { if (w == XWINDOW (echo_area_window)) new_cursor_type = FRAME_DESIRED_CURSOR (f); - else if (cursor_non_selected) - new_cursor_type = HOLLOW_BOX_CURSOR; + else if (NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows, + w->buffer))) + new_cursor_type = NO_CURSOR; else + cursor_off_state = 1; + } + + /* Nonselected window or nonselected frame. */ + else if (f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame + || w != XWINDOW (f->selected_window)) + { + if ((MINI_WINDOW_P (w) && minibuf_level == 0) + || NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows, + w->buffer)) + || NILP (XBUFFER (w->buffer)->cursor_type)) new_cursor_type = NO_CURSOR; + else + cursor_off_state = 1; } - else + + /* If new_cursor_type isn't decided yet, decide it now. */ + if (new_cursor_type == -2) { - if (f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame - || w != XWINDOW (f->selected_window)) + struct buffer *b = XBUFFER (w->buffer); + + if (EQ (b->cursor_type, Qt)) { - if ((MINI_WINDOW_P (w) && minibuf_level == 0) - || !cursor_non_selected - || NILP (XBUFFER (w->buffer)->cursor_type)) - new_cursor_type = NO_CURSOR; - else - new_cursor_type = HOLLOW_BOX_CURSOR; + new_cursor_type = FRAME_DESIRED_CURSOR (f); + new_cursor_width = FRAME_CURSOR_WIDTH (f); } else - { - struct buffer *b = XBUFFER (w->buffer); + new_cursor_type = x_specified_cursor_type (b->cursor_type, + &new_cursor_width); + } - if (EQ (b->cursor_type, Qt)) - new_cursor_type = FRAME_DESIRED_CURSOR (f); - else - new_cursor_type = x_specified_cursor_type (b->cursor_type, - &new_cursor_width); - if (w->cursor_off_p) - { - if (new_cursor_type == FILLED_BOX_CURSOR) - new_cursor_type = HOLLOW_BOX_CURSOR; - else if (new_cursor_type == BAR_CURSOR && new_cursor_width > 1) - new_cursor_width = 1; - else - new_cursor_type = NO_CURSOR; - } - } + /* Dim out or hollow out the cursor, + if it has blinked off or for nonselected windows. */ + if (w->cursor_off_p || cursor_off_state) + { + if (new_cursor_type == FILLED_BOX_CURSOR) + new_cursor_type = HOLLOW_BOX_CURSOR; + else if (new_cursor_type == BAR_CURSOR && new_cursor_width > 1) + new_cursor_width = 1; + else + new_cursor_type = NO_CURSOR; } + /* Now new_cursor_type is correct. */ + /* If cursor is currently being shown and we don't want it to be or it is in the wrong place, or the cursor type is not what we want, erase it. */ @@ -11698,9 +11920,12 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y) && new_cursor_width != w->phys_cursor_width))) x_erase_phys_cursor (w); - /* If the cursor is now invisible and we want it to be visible, - display it. */ - if (on && !w->phys_cursor_on_p) + /* Don't check phys_cursor_on_p here because that flag is only set + to zero in some cases where we know that the cursor has been + completely erased, to avoid the extra work of erasing the cursor + twice. In other words, phys_cursor_on_p can be 1 and the cursor + still not be visible, or it has only been partly erased. */ + if (on) { w->phys_cursor_ascent = glyph_row->ascent; w->phys_cursor_height = glyph_row->height; @@ -11712,7 +11937,6 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y) w->phys_cursor.hpos = hpos; w->phys_cursor.vpos = vpos; w->phys_cursor_type = new_cursor_type; - w->phys_cursor_width = new_cursor_width; w->phys_cursor_on_p = 1; switch (new_cursor_type) @@ -11726,10 +11950,15 @@ x_display_and_set_cursor (w, on, hpos, vpos, x, y) break; case BAR_CURSOR: - x_draw_bar_cursor (w, glyph_row, new_cursor_width); + x_draw_bar_cursor (w, glyph_row, new_cursor_width, BAR_CURSOR); + break; + + case HBAR_CURSOR: + x_draw_bar_cursor (w, glyph_row, new_cursor_width, HBAR_CURSOR); break; case NO_CURSOR: + w->phys_cursor_width = 0; break; default: @@ -11921,7 +12150,7 @@ x_error_catcher (display, error) XErrorEvent *error; { XGetErrorText (display, error->error_code, - XSTRING (x_error_message_string)->data, + SDATA (x_error_message_string), X_ERROR_MESSAGE_SIZE); } @@ -11945,7 +12174,7 @@ int x_catch_errors (dpy) Display *dpy; { - int count = specpdl_ptr - specpdl; + int count = SPECPDL_INDEX (); /* Make sure any errors from previous requests have been dealt with. */ XSync (dpy, False); @@ -11953,7 +12182,7 @@ x_catch_errors (dpy) record_unwind_protect (x_catch_errors_unwind, x_error_message_string); x_error_message_string = make_uninit_string (X_ERROR_MESSAGE_SIZE); - XSTRING (x_error_message_string)->data[0] = 0; + SSET (x_error_message_string, 0, 0); return count; } @@ -11980,8 +12209,8 @@ x_check_errors (dpy, format) /* Make sure to catch any errors incurred so far. */ XSync (dpy, False); - if (XSTRING (x_error_message_string)->data[0]) - error (format, XSTRING (x_error_message_string)->data); + if (SREF (x_error_message_string, 0)) + error (format, SDATA (x_error_message_string)); } /* Nonzero if we had any X protocol errors @@ -11994,7 +12223,7 @@ x_had_errors_p (dpy) /* Make sure to catch any errors incurred so far. */ XSync (dpy, False); - return XSTRING (x_error_message_string)->data[0] != 0; + return SREF (x_error_message_string, 0) != 0; } /* Forget about any errors we have had, since we did x_catch_errors on DPY. */ @@ -12003,7 +12232,7 @@ void x_clear_errors (dpy) Display *dpy; { - XSTRING (x_error_message_string)->data[0] = 0; + SSET (x_error_message_string, 0, 0); } /* Stop catching X protocol errors and let them make Emacs die. @@ -12303,7 +12532,7 @@ x_new_fontset (f, fontsetname) to do. */ return fontset_name (fontset); - result = x_new_font (f, (XSTRING (fontset_ascii (fontset))->data)); + result = x_new_font (f, (SDATA (fontset_ascii (fontset)))); if (!STRINGP (result)) /* Can't load ASCII font. */ @@ -12315,7 +12544,7 @@ x_new_fontset (f, fontsetname) #ifdef HAVE_X_I18N if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea))) - xic_set_xfontset (f, XSTRING (fontset_ascii (fontset))->data); + xic_set_xfontset (f, SDATA (fontset_ascii (fontset))); #endif return build_string (fontsetname); @@ -13915,7 +14144,7 @@ x_list_fonts (f, pattern, size, maxnames) XFontStruct *font; unsigned long value; - font = XLoadQueryFont (dpy, XSTRING (pattern)->data); + font = XLoadQueryFont (dpy, SDATA (pattern)); if (x_had_errors_p (dpy)) { /* This error is perhaps due to insufficient memory on X @@ -13958,7 +14187,7 @@ x_list_fonts (f, pattern, size, maxnames) { /* We try at least 10 fonts because XListFonts will return auto-scaled fonts at the head. */ - names = XListFonts (dpy, XSTRING (pattern)->data, max (maxnames, 10), + names = XListFonts (dpy, SDATA (pattern), max (maxnames, 10), &num_fonts); if (x_had_errors_p (dpy)) { @@ -14059,7 +14288,7 @@ x_list_fonts (f, pattern, size, maxnames) BLOCK_INPUT; count = x_catch_errors (dpy); thisinfo = XLoadQueryFont (dpy, - XSTRING (XCAR (tem))->data); + SDATA (XCAR (tem))); if (x_had_errors_p (dpy)) { /* This error is perhaps due to insufficient memory on X @@ -14239,9 +14468,9 @@ x_load_font (f, fontname, size) for (tail = font_names; CONSP (tail); tail = XCDR (tail)) if (dpyinfo->font_table[i].name && (!strcmp (dpyinfo->font_table[i].name, - XSTRING (XCAR (tail))->data) + SDATA (XCAR (tail))) || !strcmp (dpyinfo->font_table[i].full_name, - XSTRING (XCAR (tail))->data))) + SDATA (XCAR (tail))))) return (dpyinfo->font_table + i); } @@ -14259,7 +14488,7 @@ x_load_font (f, fontname, size) a bug of not finding a font even if the font surely exists and is loadable by XLoadQueryFont. */ if (size > 0 && !NILP (font_names)) - fontname = (char *) XSTRING (XCAR (font_names))->data; + fontname = (char *) SDATA (XCAR (font_names)); BLOCK_INPUT; count = x_catch_errors (FRAME_X_DISPLAY (f)); @@ -14508,10 +14737,10 @@ static int x_initialized; the screen number from the server number. */ static int same_x_server (name1, name2) - char *name1, *name2; + const char *name1, *name2; { int seen_colon = 0; - unsigned char *system_name = XSTRING (Vsystem_name)->data; + const unsigned char *system_name = SDATA (Vsystem_name); int system_name_length = strlen (system_name); int length_until_period = 0; @@ -14592,10 +14821,12 @@ x_term_init (display_name, xrm_option, resource_name) argv[argc++] = "-xrm"; argv[argc++] = xrm_option; } - dpy = XtOpenDisplay (Xt_app_con, XSTRING (display_name)->data, + stop_polling (); + dpy = XtOpenDisplay (Xt_app_con, SDATA (display_name), resource_name, EMACS_CLASS, emacs_options, XtNumber (emacs_options), &argc, argv); + start_polling (); #ifdef HAVE_X11XTR6 /* I think this is to compensate for XtSetLanguageProc. */ @@ -14607,7 +14838,7 @@ x_term_init (display_name, xrm_option, resource_name) #ifdef HAVE_X11R5 XSetLocaleModifiers (""); #endif - dpy = XOpenDisplay (XSTRING (display_name)->data); + dpy = XOpenDisplay (SDATA (display_name)); #endif /* not USE_X_TOOLKIT */ /* Detect failure. */ @@ -14629,8 +14860,8 @@ x_term_init (display_name, xrm_option, resource_name) for (share = x_display_list, tail = x_display_name_list; share; share = share->next, tail = XCDR (tail)) - if (same_x_server (XSTRING (XCAR (XCAR (tail)))->data, - XSTRING (display_name)->data)) + if (same_x_server (SDATA (XCAR (XCAR (tail))), + SDATA (display_name))) break; if (share) dpyinfo->kboard = share->kboard; @@ -14676,11 +14907,11 @@ x_term_init (display_name, xrm_option, resource_name) #endif /* ! 0 */ dpyinfo->x_id_name - = (char *) xmalloc (STRING_BYTES (XSTRING (Vinvocation_name)) - + STRING_BYTES (XSTRING (Vsystem_name)) + = (char *) xmalloc (SBYTES (Vinvocation_name) + + SBYTES (Vsystem_name) + 2); sprintf (dpyinfo->x_id_name, "%s@%s", - XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data); + SDATA (Vinvocation_name), SDATA (Vsystem_name)); /* Figure out which modifier bits mean what. */ x_find_modifier_meanings (dpyinfo); @@ -14743,8 +14974,8 @@ x_term_init (display_name, xrm_option, resource_name) build_string ("PrivateColormap"), Qnil, Qnil); if (STRINGP (value) - && (!strcmp (XSTRING (value)->data, "true") - || !strcmp (XSTRING (value)->data, "on"))) + && (!strcmp (SDATA (value), "true") + || !strcmp (SDATA (value), "on"))) dpyinfo->cmap = XCopyColormapAndFree (dpyinfo->display, dpyinfo->cmap); } } @@ -14904,8 +15135,8 @@ x_term_init (display_name, xrm_option, resource_name) build_string ("Synchronous"), Qnil, Qnil); if (STRINGP (value) - && (!strcmp (XSTRING (value)->data, "true") - || !strcmp (XSTRING (value)->data, "on"))) + && (!strcmp (SDATA (value), "true") + || !strcmp (SDATA (value), "on"))) XSynchronize (dpyinfo->display, True); } @@ -15078,7 +15309,7 @@ x_initialize () /* Disable Window Change signals; they are handled by X events. */ #ifdef SIGWINCH signal (SIGWINCH, SIG_DFL); -#endif /* ! defined (SIGWINCH) */ +#endif /* SIGWINCH */ signal (SIGPIPE, x_connection_signal); @@ -15103,6 +15334,11 @@ syms_of_xterm () staticpro (&Qvendor_specific_keysyms); Qvendor_specific_keysyms = intern ("vendor-specific-keysyms"); + staticpro (&Qutf_8); + Qutf_8 = intern ("utf-8"); + staticpro (&Qlatin_1); + Qlatin_1 = intern ("latin-1"); + staticpro (&last_mouse_press_frame); last_mouse_press_frame = Qnil; @@ -15116,9 +15352,9 @@ syms_of_xterm () staticpro (&previous_help_echo); help_echo_pos = -1; - DEFVAR_BOOL ("autoselect-window", &autoselect_window_p, + DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window, doc: /* *Non-nil means autoselect window with mouse pointer. */); - autoselect_window_p = 0; + mouse_autoselect_window = 0; DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p, doc: /* *Non-nil means draw block cursor as wide as the glyph under it.