X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/8c29f6bf9760b01ed227739c64bf84741ca3e062..f000f5c5ac061ad8075841b9c8fb2019ae5fc531:/src/xterm.c diff --git a/src/xterm.c b/src/xterm.c index ce426fb0af..977e1b8020 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -84,6 +84,10 @@ Boston, MA 02111-1307, 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 (); @@ -105,13 +109,16 @@ extern void _XEditResCheckMessages (); #endif #endif -#ifdef HAVE_X11XTR6 +#ifdef HAVE_SETLOCALE /* So we can do setlocale. */ #include #endif #ifdef SOLARIS2 -#define X_CONNECTION_LOCK_FLAG XlibDisplayWriting +/* 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 @@ -137,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; @@ -166,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 @@ -175,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; @@ -225,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; @@ -1840,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? */ @@ -1863,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); } } @@ -2261,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) @@ -3004,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 @@ -3104,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 @@ -3338,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) @@ -3387,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); @@ -3592,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; @@ -4516,9 +4483,6 @@ x_connection_closed (display, error_message) struct x_display_info *dpyinfo = x_display_info_for_display (display); Lisp_Object frame, tail; - if (_Xdebug) - abort (); - /* Indicate that this display is dead. */ dpyinfo->display = 0; @@ -4555,7 +4519,7 @@ x_connection_closed (display, error_message) if (x_display_list == 0) { - fprintf (stderr, "%s", error_message); + fprintf (stderr, "%s\n", error_message); shut_down_emacs (0, 0, Qnil); exit (70); } @@ -4567,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); } @@ -4606,55 +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. + 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. */ - 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. */ - - -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); - - x_connection_close_if_hung (x_connection_signal_dpyinfo); - - 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. */ @@ -4818,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 @@ -4863,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)); @@ -4891,8 +4825,6 @@ x_new_font (f, fontname) break; } - - XFree (atom); } n_fonts = FRAME_X_DISPLAY_INFO (f)->n_fonts; @@ -5479,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; } @@ -5564,7 +5501,12 @@ x_destroy_window (f) 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); @@ -5774,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 @@ -5782,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 @@ -5801,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) @@ -5890,6 +5846,9 @@ x_term_init (display_name, xrm_option, resource_name) #ifdef HAVE_X_I18N 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 @@ -5919,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 @@ -6244,49 +6204,5 @@ syms_of_xterm () staticpro (&Qvendor_specific_keysyms); Qvendor_specific_keysyms = intern ("vendor-specific-keysyms"); } - -/* Avoid warnings or errors from including Xlibint.h. - We don't need these functions for the rest of this file. */ -#undef bzero -#undef bcopy -#undef bcmp -#undef min -#undef max - -#ifdef X_CONNECTION_LOCK_FLAG -#define free loserfree -#define malloc losermalloc -#define exit loserexit -#define abort loserabort -/* For XlibDisplayWriting */ -#include -#endif - -/* Check whether display connection DPYINFO is hung - because its thread-interlock is locked. - If it is, close the connection. - Do nothing if this system does not have a thread interlock. */ - -x_connection_close_if_hung (dpyinfo) - struct x_display_info *dpyinfo; -{ - /* This tests (1) whether X_CONNECTION_LOCK_FLAG is defined at all, - and (2) whether the name it is defined as is itself defined. - (It ought to have been defined by Xlibint.h. */ -#if X_CONNECTION_LOCK_FLAG - - if (dpyinfo->display->flags & X_CONNECTION_LOCK_FLAG) - { - /* If the thread-interlock is locked, assume this connection is dead. - This assumes that the library does not make other threads - that can be locking the display legitimately. */ - - dpyinfo->display->flags &= ~X_CONNECTION_LOCK_FLAG; - x_connection_closed (dpyinfo->display, "connection was lost"); - } -#endif /* X_CONNECTION_LOCK_FLAG */ -} - -/* Don't put any additional functions here! */ #endif /* not HAVE_X_WINDOWS */