# HG changeset patch # User Jim Blandy # Date 714207104 0 # Node ID 7c2565dd644cac0095ae031ee014812894b23d1f # Parent aaa628aaf808b3e174be7605f27035624feb795d * xterm.c (x_wm_hints): Variable deleted. This has to be per-screen. Duh. * xterm.c (x_wm_set_window_state, x_wm_set_icon_pixmap, x_wm_set_icon_position): Use F->display.x->wm_hints, rather than x_wm_hints. (x_term_init): Don't initialize x_wm_hints here. * xterm.c (x_set_text_property): Properly balance the BLOCK_INPUTs and UNBLOCK_INPUTs. And remember that VALUE is the strin we want to set the name to, not PROPERTY. * xterm.c (x_set_text_property): Define this appropriately for X11R3 and X11R4. * xterm.c (x_set_text_property): Make this take a Lisp_Object string as an argument, rather than a pointer and a length. * xterm.c: Doc fixes. * xterm.c [USG5]: Don't include . * xterm.c (x_make_frame_invisible): Instead of calling XWithdraw window, which isn't widely available, write out what it does, since that's not much. (x_iconify_frame): Explicitly perform both the X11R3 and X11R4 methods for iconification; don't use XIconifyWindow, since that's not present in R3. * xterm.c (x_wm_set_size_hint): Don't bother setting the base_width and base_height members; their function is performed just as well by the min_width and min_height members, and if we use XSetNormalHints instead of XSetWMNormalHints, we can be compatible with R3. * xterm.c (x_error_handler): There is no way to invoke the default error handler which works on all versions of X11, so don't bother; call XGetErrorText and print the message ourselves. * xterm.c (x_term_init): Don't use MAXHOSTNAMELEN; this isn't defined on all systems. Since we only use that as an initial guess anyway, it's not very important. * xterm.c (x_set_text_property): New function. diff -r aaa628aaf808 -r 7c2565dd644c src/xterm.c --- a/src/xterm.c Wed Aug 19 06:51:17 1992 +0000 +++ b/src/xterm.c Wed Aug 19 06:51:44 1992 +0000 @@ -38,11 +38,13 @@ if this is not done before the other system files. */ #include "xterm.h" +#ifndef USG /* Load sys/types.h if not already loaded. In some systems loading it twice is suicidal. */ #ifndef makedev #include #endif +#endif #ifdef BSD #include @@ -153,19 +155,6 @@ char *hostname, *x_id_name; Lisp_Object invocation_name; -/* These are the current window manager hints. It seems that - XSetWMHints, when presented with an unset bit in the `flags' member - of the hints structure, does not leave the corresponding attribute - unchanged; rather, it resets that attribute to its default value. - For example, unless you set the `icon_pixmap' field and the - `IconPixmapHint' bit, XSetWMHints will forget what your icon pixmap - was. This is rather troublesome, since some of the members (for - example, `input' and `icon_pixmap') want to stay the same - throughout the execution of Emacs. So, we keep this structure - around, just leaving values in it and adding new bits to the mask - as we go. */ -XWMHints x_wm_hints; - /* This is the X connection that we are using. */ Display *x_current_display; @@ -270,6 +259,62 @@ static int XTcursor_to (); static int XTclear_end_of_line (); +/* R3/R4 compatibility stuff. Rah. */ + + +/* Set the property PROPERTY on the window displaying FRAME to VALUE. + VALUE must be a string. + + We use this function instead of XSetWMName and XStoreName, since + the former isn't present in R3, while the latter isn't likely to + stay around. XChangeProperty, however, is likely to be around. + + I have no idea if this is the right thing to do. Someone who is more + hip on how X is supposed to work should let us know if this is wrong. */ + +x_set_text_property (f, property, value) + FRAME_PTR f; + Atom property; + Lisp_Object value; +{ + BLOCK_INPUT; + +#ifdef HAVE_X11R4 + { + XTextProperty text; + text.value = XSTRING (value)->data; + text.encoding = XA_STRING; + text.format = 8; + text.nitems = XSTRING (value)->size; + switch (property) + { + case XA_WM_NAME: + XSetWMName (x_current_display, f->display.x->window_desc, &text); + break; + case XA_WM_ICON_NAME: + XSetWMIconName (x_current_display, f->display.x->window_desc, &text); + break; + default: + /* If you want to use this function, you have to make sure it supports + the atoms you want! Dummy. */ + abort (); + } + } +#else + XChangeProperty (x_current_display, + f->display.x->window_desc, + prop, + XA_STRING, /* type */ + 8, /* format */ + PropModeReplace, /* mode */ + XSTRING (value)->data, + XSTRING (value)->size); +#endif + + UNBLOCK_INPUT; +} + + /* These hooks are called by update_frame at the beginning and end of a frame update. We record in `updating_frame' the identity of the frame being updated, so that the XT... functions do not @@ -2862,7 +2907,10 @@ /* Handling X errors. */ /* A handler for SIGPIPE, when it occurs on the X server's connection. - This basically does an orderly shutdown of Emacs. */ + This basically does an orderly shutdown of Emacs. The arg to + Fkill_emacs is an exit status value and also prevents any + questions. */ + static SIGTYPE x_death_handler () { @@ -2996,6 +3044,11 @@ "NoOperation" }; +/* 94 is the code for X_CreateGlyphCursor. The idea is that we + probably shouldn't let a bad mouse cursor request crash Emacs. + You'd think we could #include and use a symbolic + constant for this, but that's been commented out above; perhaps + that file is not available on all systems. */ #define acceptable_x_error_p(type) ((type) == 94) x_handle_error_gracefully (event) @@ -3018,11 +3071,7 @@ /* Handle X Errors. If the error is not traumatic, just call error (). Otherwise print a (hopefully) interesting - message and quit. - - The arg to Fkill_emacs is an exit status value - and also prevents any questions. */ - + message and quit. */ x_error_handler (disp, event) Display *disp; #ifdef HAVE_X11 @@ -3048,14 +3097,15 @@ #endif if (acceptable_x_error_p (event->request_code)) x_handle_error_gracefully (event); - else - _XDefaultError (disp, event); } - else - { - disp->flags |= XlibDisplayIOError; - _XDefaultIOError (disp); - } + + { + char message[80]; + + XGetErrorText (disp, event->error_code, message, sizeof (message)); + fprintf (stderr, "Fatal X error:\n%s\n", message); + } + UNBLOCK_INPUT; x_death_handler (); @@ -3430,34 +3480,32 @@ BLOCK_INPUT; #ifdef HAVE_X11 -#if 0 + /* It would be nice if we didn't have to be backward compatible with + very old versions of X, because then we could use the + XWithdrawWindow function in R4 instead of writing it out ourselves. */ + + /* Tell the window manager what we've done. */ if (! EQ (Vx_no_window_manager, Qt)) { - XUnmapEvent unmap; - - unmap.type = UnmapNotify; - unmap.window = f->display.x->window_desc; - unmap.event = DefaultRootWindow (x_current_display); - unmap.from_configure = False; - XSendEvent (x_current_display, DefaultRootWindow (x_current_display), - False, SubstructureRedirectMask|SubstructureNotifyMask, - &unmap); + XEvent unmap; + + unmap.xunmap.type = UnmapNotify; + unmap.xunmap.window = f->display.x->window_desc; + unmap.xunmap.event = DefaultRootWindow (x_current_display); + unmap.xunmap.from_configure = False; + if (! XSendEvent (x_current_display, + DefaultRootWindow (x_current_display), + False, + SubstructureRedirectMask|SubstructureNotifyMask, + &unmap)) + { + UNBLOCK_INPUT_RESIGNAL; + error ("can't notify window manager of withdrawal"); + } } - /* The new function below does the same as the above code, plus unmapping - the window. Sending the event without actually unmapping can make - the window manager start ignoring the window (i.e., no more title bar, - icon manager stuff.) */ -#endif - - /* New function available with R4 */ - if (! XWithdrawWindow (x_current_display, f->display.x->window_desc, - DefaultScreen (x_current_display))) - { - UNBLOCK_INPUT_RESIGNAL; - error ("Can't notify window manager of iconification."); - } - + /* Unmap the window ourselves. Cheeky! */ + XUnmapWindow (x_current_display, f->display.x->window_desc); #else XUnmapWindow (XDISPLAY f->display.x->window_desc); @@ -3470,7 +3518,7 @@ UNBLOCK_INPUT; } - /* Window manager communication. Created in Fx_open_connection. */ +/* Window manager communication. Created in Fx_open_connection. */ extern Atom Xatom_wm_change_state; /* Change window state from mapped to iconified. */ @@ -3486,37 +3534,36 @@ BLOCK_INPUT; #ifdef HAVE_X11 - if (! EQ (Vx_no_window_manager, Qt)) - if (! XIconifyWindow (x_current_display, f->display.x->window_desc, - DefaultScreen (x_current_display))) + /* Since we don't know which revision of X we're running, we'll use both + the X11R3 and X11R4 techniques. I don't know if this is a good idea. */ + + /* X11R4: send a ClientMessage to the window manager using the + WM_CHANGE_STATE type. */ + { + XEvent message; + + message.xclient.window = f->display.x->window_desc; + message.xclient.type = ClientMessage; + message.xclient.message_type = Xatom_wm_change_state; + message.xclient.format = 32; + message.xclient.data.l[0] = IconicState; + + if (! XSendEvent (x_current_display, + DefaultRootWindow (x_current_display), + False, + SubstructureRedirectMask | SubstructureNotifyMask, + &message)) { UNBLOCK_INPUT_RESIGNAL; error ("Can't notify window manager of iconification."); } + } + + /* X11R3: set the initial_state field of the window manager hints to + IconicState. */ + x_wm_set_window_state (f, IconicState); f->iconified = 1; - -#if 0 - { - XClientMessageEvent message; - - message.window = f->display.x->window_desc; - message.type = ClientMessage; - message.message_type = Xatom_wm_change_state; - message.format = 32; - message.data.l[0] = IconicState; - - if (! XSendEvent (x_current_display, - DefaultRootWindow (x_current_display), - False, - SubstructureRedirectMask | SubstructureNotifyMask, - &message)) - { - UNBLOCK_INPUT_RESIGNAL; - error ("Can't notify window manager of iconification."); - } - } -#endif #else /* X10 */ XUnmapWindow (XDISPLAY f->display.x->window_desc); @@ -3654,23 +3701,15 @@ (x_screen_height - ((2 * f->display.x->internal_border_width) + f->display.x->h_scrollbar_height)); { - int base_width = ((2 * f->display.x->internal_border_width) - + f->display.x->v_scrollbar_width); - int base_height = ((2 * f->display.x->internal_border_width) - + f->display.x->h_scrollbar_height); - -#ifdef PBaseSize - size_hints.flags |= PBaseSize; - size_hints.base_width = base_width; - size_hints.base_height = base_height; -#endif - - { - int min_rows = 0, min_cols = 0; - check_frame_size (f, &min_rows, &min_cols); - size_hints.min_width = base_width + min_cols * size_hints.width_inc; - size_hints.min_height = base_height + min_rows * size_hints.height_inc; - } + int min_rows = 0, min_cols = 0; + check_frame_size (f, &min_rows, &min_cols); + size_hints.min_width = ((2 * f->display.x->internal_border_width) + + min_cols * size_hints.width_inc + + f->display.x->v_scrollbar_width); + size_hints.min_height = ((2 * f->display.x->internal_border_width) + + min_rows * size_hints.height_inc + + f->display.x->h_scrollbar_height); + } if (prompting) @@ -3689,11 +3728,8 @@ if (hints.flags & USSize) size_hints.flags |= USSize; } - -#if 0 /* R3 */ + XSetNormalHints (x_current_display, window, &size_hints); -#endif - XSetWMNormalHints (x_current_display, window, &size_hints); } /* Used for IconicState or NormalState */ @@ -3703,10 +3739,10 @@ { Window window = f->display.x->window_desc; - x_wm_hints.flags |= StateHint; - x_wm_hints.initial_state = state; - - XSetWMHints (x_current_display, window, &x_wm_hints); + f->display.x->wm_hints.flags |= StateHint; + f->display.x->wm_hints.initial_state = state; + + XSetWMHints (x_current_display, window, &f->display.x->wm_hints); } x_wm_set_icon_pixmap (f, icon_pixmap) @@ -3715,15 +3751,10 @@ { Window window = f->display.x->window_desc; - if (icon_pixmap) - { - x_wm_hints.flags |= IconPixmapHint; - x_wm_hints.icon_pixmap = icon_pixmap; - } - else - x_wm_hints.flags &= ~IconPixmapHint; - - XSetWMHints (x_current_display, window, &x_wm_hints); + f->display.x->wm_hints.flags |= IconPixmapHint; + f->display.x->wm_hints.icon_pixmap = icon_pixmap ? icon_pixmap : None; + + XSetWMHints (x_current_display, window, &f->display.x->wm_hints); } x_wm_set_icon_position (f, icon_x, icon_y) @@ -3732,11 +3763,11 @@ { Window window = f->display.x->window_desc; - x_wm_hints.flags |= IconPositionHint; - x_wm_hints.icon_x = icon_x; - x_wm_hints.icon_y = icon_y; - - XSetWMHints (x_current_display, window, &x_wm_hints); + f->display.x->wm_hints.flags |= IconPositionHint; + f->display.x->wm_hints.icon_x = icon_x; + f->display.x->wm_hints.icon_y = icon_y; + + XSetWMHints (x_current_display, window, &f->display.x->wm_hints); } @@ -3759,7 +3790,7 @@ #ifdef HAVE_X11 { - int hostname_size = MAXHOSTNAMELEN + 1; + int hostname_size = 256; hostname = (char *) xmalloc (hostname_size); @@ -3861,22 +3892,6 @@ #endif /* SIGWINCH */ signal (SIGPIPE, x_death_handler); - - /* When XSetWMHints eventually gets called, this will indicate that - we use the "Passive Input" input model. Unless we do this, we - don't get the Focus{In,Out} events that we need to draw the - cursor correctly. Accursed bureaucrats. - - We set this here and leave it, because we know, being decidedly - non-humble programmers (nay, weigh'd low by our hubris!), that - Fx_create_frame calls x_icon which begat x_wm_set_window_state - which begat XSetWMHints, which will get this information to the - right parties. - - XWhipsAndChains (x_current_display, IronMaiden, &TheRack); */ - - x_wm_hints.input = True; - x_wm_hints.flags |= InputHint; } void