X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/9af3143a29edc6d09019dcdebc2129abe118598d..f000f5c5ac061ad8075841b9c8fb2019ae5fc531:/src/xterm.c diff --git a/src/xterm.c b/src/xterm.c index 906709fe99..977e1b8020 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -1,5 +1,5 @@ /* X Communication module for terminals which understand the X protocol. - Copyright (C) 1989, 1993, 1994, 1995 Free Software Foundation, Inc. + Copyright (C) 1989, 93, 94, 95, 1996 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -15,7 +15,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNU Emacs; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ /* Xt features made by Fred Pierresteguy. */ @@ -83,6 +84,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "keyboard.h" #include "intervals.h" +#ifdef USE_X_TOOLKIT +#include +#endif + #ifdef USE_X_TOOLKIT extern void free_frame_menubar (); extern FRAME_PTR x_menubar_window_to_frame (); @@ -104,13 +109,24 @@ extern void _XEditResCheckMessages (); #endif #endif -#ifdef HAVE_X11XTR6 +#ifdef HAVE_SETLOCALE /* So we can do setlocale. */ #include #endif +#ifdef SOLARIS2 +/* memmove will be defined as a macro in Xfuncs.h unless + is included beforehand. The declaration for memmove in + will cause a syntax error when Xfuncs.h later includes it. */ +#include +#endif + +#ifndef min #define min(a,b) ((a)<(b) ? (a) : (b)) +#endif +#ifndef max #define max(a,b) ((a)>(b) ? (a) : (b)) +#endif /* This is a chain of structures for all the X displays currently in use. */ struct x_display_info *x_display_list; @@ -128,6 +144,8 @@ Lisp_Object x_display_name_list; is the frame to apply to. */ extern struct frame *updating_frame; +extern waiting_for_input; + /* This is a frame waiting to be autoraised, within XTread_socket. */ struct frame *pending_autoraise_frame; @@ -157,6 +175,13 @@ static int curs_y; /* Mouse movement. + Formerly, we used PointerMotionHintMask (in STANDARD_EVENT_MASK) + so that we would have to call XQueryPointer after each MotionNotify + event to ask for another such event. However, this made mouse tracking + slow, and there was a bug that made it eventually stop. + + Simply asking for MotionNotify all the time seems to work better. + In order to avoid asking for motion events and then throwing most of them away or busy-polling the server for mouse positions, we ask the server for pointer motion hints. This means that we get only @@ -166,13 +191,7 @@ static int curs_y; get another MotionNotify event the next time the mouse moves. This is at least as efficient as getting motion events when mouse tracking is on, and I suspect only negligibly worse when tracking - is off. - - The silly O'Reilly & Associates Nutshell guides barely document - pointer motion hints at all (I think you have to infer how they - work from an example), and the description of XQueryPointer doesn't - mention that calling it causes you to get another motion hint from - the server, which is very important. */ + is off. */ /* Where the mouse was last time we reported a mouse event. */ static FRAME_PTR last_mouse_frame; @@ -216,9 +235,6 @@ extern Lisp_Object Vcommand_line_args, Vsystem_name; extern Lisp_Object Vx_no_window_manager; -/* Nonzero enables some debugging for the X interface code. */ -extern int _Xdebug; - extern Lisp_Object Qface, Qmouse_face; extern int errno; @@ -394,6 +410,7 @@ static XTframe_up_to_date (f) FRAME_PTR f; { + BLOCK_INPUT; if (FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc || f == FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_frame) { @@ -402,6 +419,7 @@ XTframe_up_to_date (f) FRAME_X_DISPLAY_INFO (f)->mouse_face_mouse_y); FRAME_X_DISPLAY_INFO (f)->mouse_face_deferred_gc = 0; } + UNBLOCK_INPUT; } /* External interface to control of standout mode. @@ -1562,8 +1580,8 @@ x_find_modifier_meanings (dpyinfo) #ifdef HAVE_X11R4 XDisplayKeycodes (dpyinfo->display, &min_code, &max_code); #else - min_code = display->min_keycode; - max_code = display->max_keycode; + min_code = dpyinfo->display->min_keycode; + max_code = dpyinfo->display->max_keycode; #endif syms = XGetKeyboardMapping (dpyinfo->display, @@ -1829,17 +1847,6 @@ note_mouse_movement (frame, event) last_mouse_scroll_bar = Qnil; note_mouse_highlight (frame, -1, -1); - - /* Ask for another mouse motion event. */ - { - int dummy; - Window dummy_window; - - XQueryPointer (event->display, FRAME_X_WINDOW (frame), - &dummy_window, &dummy_window, - &dummy, &dummy, &dummy, &dummy, - (unsigned int *) &dummy); - } } /* Has the mouse moved off the glyph it was on at the last sighting? */ @@ -1852,30 +1859,6 @@ note_mouse_movement (frame, event) last_mouse_scroll_bar = Qnil; note_mouse_highlight (frame, event->x, event->y); - - /* Ask for another mouse motion event. */ - { - int dummy; - Window dummy_window; - - XQueryPointer (event->display, FRAME_X_WINDOW (frame), - &dummy_window, &dummy_window, - &dummy, &dummy, &dummy, &dummy, - (unsigned int *) &dummy); - } - } - else - { - /* It's on the same glyph. Call XQueryPointer so we'll get an - event the next time the mouse moves and we can see if it's - *still* on the same glyph. */ - int dummy; - Window dummy_window; - - XQueryPointer (event->display, FRAME_X_WINDOW (frame), - &dummy_window, &dummy_window, - &dummy, &dummy, &dummy, &dummy, - (unsigned int *) &dummy); } } @@ -2250,9 +2233,7 @@ static void x_scroll_bar_report_motion (); Don't store anything if we don't have a valid set of values to report. This clears the mouse_moved flag, so we can wait for the next mouse - movement. This also calls XQueryPointer, which will cause the - server to give us another MotionNotify when the mouse moves - again. */ + movement. */ static void XTmouse_position (fp, insist, bar_window, part, x, y, time) @@ -2993,18 +2974,6 @@ x_scroll_bar_note_movement (bar, event) x_scroll_bar_set_handle (bar, new_start, new_end, 0); } } - - /* Call XQueryPointer so we'll get an event the next time the mouse - moves and we can see *still* on the same position. */ - { - int dummy; - Window dummy_window; - - XQueryPointer (event->xmotion.display, event->xmotion.window, - &dummy_window, &dummy_window, - &dummy, &dummy, &dummy, &dummy, - (unsigned int *) &dummy); - } } /* Return information to the user about the current position of the mouse @@ -3093,10 +3062,14 @@ x_scroll_bar_clear (f) { Lisp_Object bar; - for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar); - bar = XSCROLL_BAR (bar)->next) - XClearArea (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)), - 0, 0, 0, 0, True); + /* We can have scroll bars even if this is 0, + if we just turned off scroll bar mode. + But in that case we should not clear them. */ + if (FRAME_HAS_VERTICAL_SCROLL_BARS (f)) + for (bar = FRAME_SCROLL_BARS (f); VECTORP (bar); + bar = XSCROLL_BAR (bar)->next) + XClearArea (FRAME_X_DISPLAY (f), SCROLL_BAR_X_WINDOW (XSCROLL_BAR (bar)), + 0, 0, 0, 0, True); } /* This processes Expose events from the menubar specific X event @@ -3295,7 +3268,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) #ifdef FIOSNBIO /* If available, Xlib uses FIOSNBIO to make the socket non-blocking, and then looks for EWOULDBLOCK. If O_NDELAY is set, - FIOSNBIO is ignored, and instead of signalling EWOULDBLOCK, + FIOSNBIO is ignored, and instead of signaling EWOULDBLOCK, a read returns 0, which Xlib interprets as equivalent to EPIPE. */ fcntl (dpyinfo->connection, F_SETFL, 0); #endif /* ! defined (FIOSNBIO) */ @@ -3327,7 +3300,12 @@ XTread_socket (sd, bufp, numchars, waitp, expected) while (XPending (dpyinfo->display) != 0) { +#ifdef USE_X_TOOLKIT + /* needed to raise Motif submenus */ + XtAppNextEvent (Xt_app_con, &event); +#else XNextEvent (dpyinfo->display, &event); +#endif event_found = 1; switch (event.type) @@ -3376,7 +3354,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) XSetCommand (FRAME_X_DISPLAY (f), event.xclient.window, initial_argv, initial_argc); - else + else if (f) XSetCommand (FRAME_X_DISPLAY (f), event.xclient.window, 0, 0); @@ -3459,6 +3437,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) SELECTION_EVENT_DISPLAY (bufp) = eventp->display; SELECTION_EVENT_SELECTION (bufp) = eventp->selection; SELECTION_EVENT_TIME (bufp) = eventp->time; + bufp->frame_or_window = Qnil; bufp++; count += 1; @@ -3488,6 +3467,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) SELECTION_EVENT_TARGET (bufp) = eventp->target; SELECTION_EVENT_PROPERTY (bufp) = eventp->property; SELECTION_EVENT_TIME (bufp) = eventp->time; + bufp->frame_or_window = Qnil; bufp++; count += 1; @@ -3579,7 +3559,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) /* We can't distinguish, from the event, whether the window has become iconified or invisible. So assume, if it was previously visible, than now it is iconified. - We depend on x_make_frame_invisible to mark it iconified. */ + We depend on x_make_frame_invisible to mark it invisible. */ if (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)) f->async_iconified = 1; @@ -3589,10 +3569,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) count++; numchars--; } -#ifdef USE_X_TOOLKIT goto OTHER; -#endif /* USE_X_TOOLKIT */ - break; case MapNotify: /* We use x_top_window_to_frame because map events can come @@ -3615,16 +3592,14 @@ XTread_socket (sd, bufp, numchars, waitp, expected) count++; numchars--; } - else + else if (! NILP(Vframe_list) + && ! NILP (XCONS (Vframe_list)->cdr)) /* Force a redisplay sooner or later to update the frame titles in case this is the second frame. */ record_asynch_buffer_change (); } -#ifdef USE_X_TOOLKIT goto OTHER; -#endif /* USE_X_TOOLKIT */ - break; /* Turn off processing if we become fully obscured. */ case VisibilityNotify: @@ -3788,7 +3763,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) else abort (); } - break; + goto OTHER; /* Here's a possible interpretation of the whole FocusIn-EnterNotify FocusOut-LeaveNotify mess. If you get a @@ -3816,10 +3791,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) so update things that depend on mouse position. */ if (f) note_mouse_movement (f, &event.xmotion); -#ifdef USE_X_TOOLKIT goto OTHER; -#endif /* USE_X_TOOLKIT */ - break; case FocusIn: f = x_any_window_to_frame (dpyinfo, event.xfocus.window); @@ -3833,11 +3805,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) XSetICFocus (FRAME_XIC (f)); #endif -#ifdef USE_X_TOOLKIT goto OTHER; -#endif /* USE_X_TOOLKIT */ - break; - case LeaveNotify: f = x_top_window_to_frame (dpyinfo, event.xcrossing.window); @@ -3858,10 +3826,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) x_new_focus_frame (dpyinfo, 0); } } -#ifdef USE_X_TOOLKIT goto OTHER; -#endif /* USE_X_TOOLKIT */ - break; case FocusOut: f = x_any_window_to_frame (dpyinfo, event.xfocus.window); @@ -3876,10 +3841,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) XUnsetICFocus (FRAME_XIC (f)); #endif -#ifdef USE_X_TOOLKIT goto OTHER; -#endif /* USE_X_TOOLKIT */ - break; case MotionNotify: { @@ -3903,10 +3865,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) clear_mouse_face (dpyinfo); } } -#ifdef USE_X_TOOLKIT goto OTHER; -#endif /* USE_X_TOOLKIT */ - break; case ConfigureNotify: f = x_any_window_to_frame (dpyinfo, event.xconfigure.window); @@ -3995,11 +3954,7 @@ XTread_socket (sd, bufp, numchars, waitp, expected) /* #endif */ } } -#ifdef USE_X_TOOLKIT goto OTHER; -#else - break; -#endif case ButtonPress: case ButtonRelease: @@ -4101,14 +4056,11 @@ XTread_socket (sd, bufp, numchars, waitp, expected) case MappingKeyboard: XRefreshKeyboardMapping (&event.xmapping); } -#ifdef USE_X_TOOLKIT goto OTHER; -#endif /* USE_X_TOOLKIT */ - break; default: -#ifdef USE_X_TOOLKIT OTHER: +#ifdef USE_X_TOOLKIT BLOCK_INPUT; XtDispatchEvent (&event); UNBLOCK_INPUT; @@ -4409,6 +4361,11 @@ x_update_cursor (f, on) struct frame *f; int on; { + /* If we don't have any previous cursor position to use, + leave the cursor off. */ + if (f->phys_cursor_x < 0) + return; + BLOCK_INPUT; if (FRAME_DESIRED_CURSOR (f) == filled_box_cursor) @@ -4526,13 +4483,9 @@ x_connection_closed (display, error_message) struct x_display_info *dpyinfo = x_display_info_for_display (display); Lisp_Object frame, tail; - /* Whatever we were in the middle of, we are going to throw out of it, - so reassure various things that have error checks about being - called with input blocked. */ - TOTALLY_UNBLOCK_INPUT; + /* Indicate that this display is dead. */ - if (_Xdebug) - abort (); + dpyinfo->display = 0; /* First delete frames whose minibuffers are on frames that are on the dead display. */ @@ -4561,11 +4514,12 @@ x_connection_closed (display, error_message) Fdelete_frame (frame, Qt); } - x_delete_display (dpyinfo); + if (dpyinfo) + x_delete_display (dpyinfo); if (x_display_list == 0) { - fprintf (stderr, "%s", error_message); + fprintf (stderr, "%s\n", error_message); shut_down_emacs (0, 0, Qnil); exit (70); } @@ -4577,6 +4531,12 @@ x_connection_closed (display, error_message) sigunblock (sigmask (SIGALRM)); TOTALLY_UNBLOCK_INPUT; + if (waiting_for_input) + { + message ("%s", error_message); + quit_throw_to_read_char (); + } + error ("%s", error_message); } @@ -4595,7 +4555,7 @@ x_error_quitter (display, error) original error handler. */ XGetErrorText (display, error->error_code, buf, sizeof (buf)); - sprintf (buf1, "X protocol error: %s on protocol request %d", + sprintf (buf1, "X protocol error: %s on protocol request %d\n", buf, error->request_code); x_connection_closed (display, buf1); } @@ -4616,52 +4576,19 @@ x_io_error_quitter (display) /* Handle SIGPIPE, which can happen when the connection to a server simply goes away. SIGPIPE is handled by x_connection_signal. - It works by sending a no-op command to each X server connection. - When we try a connection that has closed, we get SIGPIPE again. - But this time, it is handled by x_connection_signal_1. - That function knows which connection we were testing, - so it closes that one. - - x_connection_closed never returns, - so if more than one connection was lost at once, - we only find one. But XTread_socket keeps trying them all, - so it will notice the other closed one sooner or later. */ + Don't need to do anything, because the write which caused the + SIGPIPE will fail, causing Xlib to invoke the X IO error handler, + which will do the appropriate cleanup for us. */ - -static struct x_display_info *x_connection_signal_dpyinfo; - -static SIGTYPE x_connection_signal (); - -static SIGTYPE -x_connection_signal_1 (signalnum) /* If we don't have an argument, */ - int signalnum; /* some compilers complain in signal calls. */ -{ - signal (SIGPIPE, x_connection_signal); - x_connection_closed (x_connection_signal_dpyinfo, - "connection was lost"); -} - static SIGTYPE x_connection_signal (signalnum) /* If we don't have an argument, */ int signalnum; /* some compilers complain in signal calls. */ { - x_connection_signal_dpyinfo = x_display_list; - - sigunblock (SIGPIPE); - - while (x_connection_signal_dpyinfo) - { - signal (SIGPIPE, x_connection_signal_1); - - XNoOp (x_connection_signal_dpyinfo->display); - XSync (x_connection_signal_dpyinfo->display, False); - - /* Each time we get here, cycle through the displays now open. */ - x_connection_signal_dpyinfo = x_connection_signal_dpyinfo->next; - } - - /* We should have found some closed connection. */ - abort (); +#ifdef USG + /* USG systems forget handlers when they are used; + must reestablish each time */ + signal (signalnum, x_connection_signal); +#endif /* USG */ } /* A buffer for storing X error messages. */ @@ -4825,6 +4752,7 @@ x_new_font (f, fontname) char *full_name; XFontStruct *font; int n_fonts; + Atom FONT_atom; /* Try to find a character-cell font in the list. */ #if 0 @@ -4870,11 +4798,10 @@ x_new_font (f, fontname) /* Try to get the full name of FONT. Put it in full_name. */ full_name = 0; + FONT_atom = XInternAtom (FRAME_X_DISPLAY (f), "FONT", False); for (i = 0; i < font->n_properties; i++) { - char *atom - = XGetAtomName (FRAME_X_DISPLAY (f), font->properties[i].name); - if (!strcmp (atom, "FONT")) + if (FONT_atom == font->properties[i].name) { char *name = XGetAtomName (FRAME_X_DISPLAY (f), (Atom) (font->properties[i].card32)); @@ -4898,8 +4825,6 @@ x_new_font (f, fontname) break; } - - XFree (atom); } n_fonts = FRAME_X_DISPLAY_INFO (f)->n_fonts; @@ -4956,6 +4881,9 @@ x_new_font (f, fontname) } } +/* Calculate the absolute position in frame F + from its current recorded position values and gravity. */ + x_calc_absolute_position (f) struct frame *f; { @@ -4993,17 +4921,18 @@ x_calc_absolute_position (f) position that fits on the screen. */ if (flags & XNegative) f->output_data.x->left_pos = (FRAME_X_DISPLAY_INFO (f)->width - - 2 * f->output_data.x->border_width - win_x - - PIXEL_WIDTH (f) - + f->output_data.x->left_pos); + - 2 * f->output_data.x->border_width - win_x + - PIXEL_WIDTH (f) + + f->output_data.x->left_pos); if (flags & YNegative) + /* We used to subtract f->output_data.x->menubar_height here + in the toolkit case, but PIXEL_HEIGHT already includes that. */ f->output_data.x->top_pos = (FRAME_X_DISPLAY_INFO (f)->height - - 2 * f->output_data.x->border_width - win_y - - PIXEL_HEIGHT (f) - - (FRAME_EXTERNAL_MENU_BAR (f) - ? f->output_data.x->menubar_height : 0) - + f->output_data.x->top_pos); + - 2 * f->output_data.x->border_width - win_y + - PIXEL_HEIGHT (f) + + f->output_data.x->top_pos); + /* The left_pos and top_pos are now relative to the top and left screen edges, so the flags should correspond. */ @@ -5071,9 +5000,12 @@ x_set_window_size (f, change_gravity, cols, rows) { int pixelwidth, pixelheight; int mask; + Lisp_Object window; + struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); -#ifdef USE_X_TOOLKIT BLOCK_INPUT; + +#ifdef USE_X_TOOLKIT { /* The x and y position of the widget is clobbered by the call to XtSetValues within EmacsFrameSetCharSize. @@ -5085,12 +5017,9 @@ x_set_window_size (f, change_gravity, cols, rows) f->output_data.x->widget->core.x = xpos; f->output_data.x->widget->core.y = ypos; } - UNBLOCK_INPUT; #else /* not USE_X_TOOLKIT */ - BLOCK_INPUT; - check_frame_size (f, &rows, &cols); f->output_data.x->vertical_scroll_bar_extra = (!FRAME_HAS_VERTICAL_SCROLL_BARS (f) @@ -5122,6 +5051,16 @@ x_set_window_size (f, change_gravity, cols, rows) PIXEL_WIDTH (f) = pixelwidth; PIXEL_HEIGHT (f) = pixelheight; + /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to + receive in the ConfigureNotify event; if we get what we asked + for, then the event won't cause the screen to become garbaged, so + we have to make sure to do it here. */ + SET_FRAME_GARBAGED (f); + + XFlush (FRAME_X_DISPLAY (f)); + +#endif /* not USE_X_TOOLKIT */ + /* If cursor was outside the new size, mark it as off. */ if (f->phys_cursor_y >= rows || f->phys_cursor_x >= cols) @@ -5130,15 +5069,19 @@ x_set_window_size (f, change_gravity, cols, rows) f->phys_cursor_y = -1; } - /* We've set {FRAME,PIXEL}_{WIDTH,HEIGHT} to the values we hope to - receive in the ConfigureNotify event; if we get what we asked - for, then the event won't cause the screen to become garbaged, so - we have to make sure to do it here. */ - SET_FRAME_GARBAGED (f); + /* Clear out any recollection of where the mouse highlighting was, + since it might be in a place that's outside the new frame size. + Actually checking whether it is outside is a pain in the neck, + so don't try--just let the highlighting be done afresh with new size. */ + window = dpyinfo->mouse_face_window; + if (! NILP (window) && XFRAME (window) == f) + { + dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1; + dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1; + dpyinfo->mouse_face_window = Qnil; + } - XFlush (FRAME_X_DISPLAY (f)); UNBLOCK_INPUT; -#endif /* not USE_X_TOOLKIT */ } /* Mouse warping. */ @@ -5245,11 +5188,11 @@ x_lower_frame (f) } static void -XTframe_raise_lower (f, raise) +XTframe_raise_lower (f, raise_flag) FRAME_PTR f; - int raise; + int raise_flag; { - if (raise) + if (raise_flag) x_raise_frame (f); else x_lower_frame (f); @@ -5468,6 +5411,11 @@ x_iconify_frame (f) x_wm_set_window_state (f, IconicState); /* This was XtPopup, but that did nothing for an iconified frame. */ XtMapWidget (f->output_data.x->widget); + /* The server won't give us any event to indicate + that an invisible frame was changed to an icon, + so we have to record it here. */ + f->iconified = 1; + f->async_iconified = 1; UNBLOCK_INPUT; return; } @@ -5543,16 +5491,33 @@ x_destroy_window (f) BLOCK_INPUT; - if (f->output_data.x->icon_desc != 0) - XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc); - XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->window_desc); + /* If a display connection is dead, don't try sending more + commands to the X server. */ + if (dpyinfo->display != 0) + { + if (f->output_data.x->icon_desc != 0) + XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->icon_desc); +#ifdef HAVE_X_I18N + if (FRAME_XIM (f)) + { + XDestroyIC (FRAME_XIC (f)); +#if ! defined (SOLARIS2) || defined (HAVE_X11R6) + /* This line causes crashes on Solaris with Openwin, + due to an apparent bug in XCloseIM. + X11R6 seems not to have the bug. */ + XCloseIM (FRAME_XIM (f)); +#endif + } +#endif + XDestroyWindow (FRAME_X_DISPLAY (f), f->output_data.x->window_desc); #ifdef USE_X_TOOLKIT - XtDestroyWidget (f->output_data.x->widget); - free_frame_menubar (f); + XtDestroyWidget (f->output_data.x->widget); + free_frame_menubar (f); #endif /* USE_X_TOOLKIT */ - free_frame_faces (f); - XFlush (FRAME_X_DISPLAY (f)); + free_frame_faces (f); + XFlush (FRAME_X_DISPLAY (f)); + } xfree (f->output_data.x); f->output_data.x = 0; @@ -5751,6 +5716,8 @@ x_wm_set_icon_pixmap (f, pixmap_id) struct frame *f; int pixmap_id; { + Pixmap icon_pixmap; + #ifdef USE_X_TOOLKIT Window window = XtWindow (f->output_data.x->widget); #else @@ -5759,7 +5726,7 @@ x_wm_set_icon_pixmap (f, pixmap_id) if (pixmap_id > 0) { - Pixmap icon_pixmap = x_bitmap_pixmap (f, pixmap_id); + icon_pixmap = x_bitmap_pixmap (f, pixmap_id); f->output_data.x->wm_hints.icon_pixmap = icon_pixmap; } else @@ -5778,8 +5745,20 @@ x_wm_set_icon_pixmap (f, pixmap_id) #endif } +#ifdef USE_X_TOOLKIT /* same as in x_wm_set_window_state. */ + + { + Arg al[1]; + XtSetArg (al[0], XtNiconPixmap, icon_pixmap); + XtSetValues (f->output_data.x->widget, al, 1); + } + +#else /* not USE_X_TOOLKIT */ + f->output_data.x->wm_hints.flags |= IconPixmapHint; XSetWMHints (FRAME_X_DISPLAY (f), window, &f->output_data.x->wm_hints); + +#endif /* not USE_X_TOOLKIT */ } x_wm_set_icon_position (f, icon_x, icon_y) @@ -5866,7 +5845,10 @@ x_term_init (display_name, xrm_option, resource_name) } #ifdef HAVE_X_I18N - setlocale (LC_ALL, NULL); + setlocale (LC_ALL, ""); + /* In case we just overrode what init_lread did, redo it. */ + setlocale (LC_NUMERIC, "C"); + setlocale (LC_TIME, "C"); #endif #ifdef USE_X_TOOLKIT @@ -5896,6 +5878,7 @@ x_term_init (display_name, xrm_option, resource_name) &argc, argv); #ifdef HAVE_X11XTR6 + /* I think this is to compensate for XtSetLanguageProc. */ setlocale (LC_NUMERIC, "C"); setlocale (LC_TIME, "C"); #endif @@ -6221,4 +6204,5 @@ syms_of_xterm () staticpro (&Qvendor_specific_keysyms); Qvendor_specific_keysyms = intern ("vendor-specific-keysyms"); } -#endif /* ! defined (HAVE_X_WINDOWS) */ + +#endif /* not HAVE_X_WINDOWS */