aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/xterm.c269
1 files changed, 142 insertions, 127 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 093b268f5c3..8ff17c4601c 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -38,11 +38,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
38 if this is not done before the other system files. */ 38 if this is not done before the other system files. */
39#include "xterm.h" 39#include "xterm.h"
40 40
41#ifndef USG
41/* Load sys/types.h if not already loaded. 42/* Load sys/types.h if not already loaded.
42 In some systems loading it twice is suicidal. */ 43 In some systems loading it twice is suicidal. */
43#ifndef makedev 44#ifndef makedev
44#include <sys/types.h> 45#include <sys/types.h>
45#endif 46#endif
47#endif
46 48
47#ifdef BSD 49#ifdef BSD
48#include <sys/ioctl.h> 50#include <sys/ioctl.h>
@@ -153,19 +155,6 @@ extern Lisp_Object Vcommand_line_args;
153char *hostname, *x_id_name; 155char *hostname, *x_id_name;
154Lisp_Object invocation_name; 156Lisp_Object invocation_name;
155 157
156/* These are the current window manager hints. It seems that
157 XSetWMHints, when presented with an unset bit in the `flags' member
158 of the hints structure, does not leave the corresponding attribute
159 unchanged; rather, it resets that attribute to its default value.
160 For example, unless you set the `icon_pixmap' field and the
161 `IconPixmapHint' bit, XSetWMHints will forget what your icon pixmap
162 was. This is rather troublesome, since some of the members (for
163 example, `input' and `icon_pixmap') want to stay the same
164 throughout the execution of Emacs. So, we keep this structure
165 around, just leaving values in it and adding new bits to the mask
166 as we go. */
167XWMHints x_wm_hints;
168
169/* This is the X connection that we are using. */ 158/* This is the X connection that we are using. */
170 159
171Display *x_current_display; 160Display *x_current_display;
@@ -270,6 +259,62 @@ void dumpborder ();
270static int XTcursor_to (); 259static int XTcursor_to ();
271static int XTclear_end_of_line (); 260static int XTclear_end_of_line ();
272 261
262/* R3/R4 compatibility stuff. Rah. */
263
264
265/* Set the property PROPERTY on the window displaying FRAME to VALUE.
266 VALUE must be a string.
267
268 We use this function instead of XSetWMName and XStoreName, since
269 the former isn't present in R3, while the latter isn't likely to
270 stay around. XChangeProperty, however, is likely to be around.
271
272 I have no idea if this is the right thing to do. Someone who is more
273 hip on how X is supposed to work should let us know if this is wrong. */
274
275x_set_text_property (f, property, value)
276 FRAME_PTR f;
277 Atom property;
278 Lisp_Object value;
279{
280 BLOCK_INPUT;
281
282#ifdef HAVE_X11R4
283 {
284 XTextProperty text;
285 text.value = XSTRING (value)->data;
286 text.encoding = XA_STRING;
287 text.format = 8;
288 text.nitems = XSTRING (value)->size;
289 switch (property)
290 {
291 case XA_WM_NAME:
292 XSetWMName (x_current_display, f->display.x->window_desc, &text);
293 break;
294 case XA_WM_ICON_NAME:
295 XSetWMIconName (x_current_display, f->display.x->window_desc, &text);
296 break;
297 default:
298 /* If you want to use this function, you have to make sure it supports
299 the atoms you want! Dummy. */
300 abort ();
301 }
302 }
303#else
304 XChangeProperty (x_current_display,
305 f->display.x->window_desc,
306 prop,
307 XA_STRING, /* type */
308 8, /* format */
309 PropModeReplace, /* mode */
310 XSTRING (value)->data,
311 XSTRING (value)->size);
312#endif
313
314 UNBLOCK_INPUT;
315}
316
317
273/* These hooks are called by update_frame at the beginning and end 318/* These hooks are called by update_frame at the beginning and end
274 of a frame update. We record in `updating_frame' the identity 319 of a frame update. We record in `updating_frame' the identity
275 of the frame being updated, so that the XT... functions do not 320 of the frame being updated, so that the XT... functions do not
@@ -2862,7 +2907,10 @@ x_text_icon (f, icon_name)
2862/* Handling X errors. */ 2907/* Handling X errors. */
2863 2908
2864/* A handler for SIGPIPE, when it occurs on the X server's connection. 2909/* A handler for SIGPIPE, when it occurs on the X server's connection.
2865 This basically does an orderly shutdown of Emacs. */ 2910 This basically does an orderly shutdown of Emacs. The arg to
2911 Fkill_emacs is an exit status value and also prevents any
2912 questions. */
2913
2866static SIGTYPE 2914static SIGTYPE
2867x_death_handler () 2915x_death_handler ()
2868{ 2916{
@@ -2996,6 +3044,11 @@ static char *x_proto_requests[] =
2996 "NoOperation" 3044 "NoOperation"
2997}; 3045};
2998 3046
3047/* 94 is the code for X_CreateGlyphCursor. The idea is that we
3048 probably shouldn't let a bad mouse cursor request crash Emacs.
3049 You'd think we could #include <X11/Xproto.h> and use a symbolic
3050 constant for this, but that's been commented out above; perhaps
3051 that file is not available on all systems. */
2999#define acceptable_x_error_p(type) ((type) == 94) 3052#define acceptable_x_error_p(type) ((type) == 94)
3000 3053
3001x_handle_error_gracefully (event) 3054x_handle_error_gracefully (event)
@@ -3018,11 +3071,7 @@ extern int x_converting_selection;
3018 3071
3019/* Handle X Errors. If the error is not traumatic, 3072/* Handle X Errors. If the error is not traumatic,
3020 just call error (). Otherwise print a (hopefully) interesting 3073 just call error (). Otherwise print a (hopefully) interesting
3021 message and quit. 3074 message and quit. */
3022
3023 The arg to Fkill_emacs is an exit status value
3024 and also prevents any questions. */
3025
3026x_error_handler (disp, event) 3075x_error_handler (disp, event)
3027 Display *disp; 3076 Display *disp;
3028#ifdef HAVE_X11 3077#ifdef HAVE_X11
@@ -3048,14 +3097,15 @@ x_error_handler (disp, event)
3048#endif 3097#endif
3049 if (acceptable_x_error_p (event->request_code)) 3098 if (acceptable_x_error_p (event->request_code))
3050 x_handle_error_gracefully (event); 3099 x_handle_error_gracefully (event);
3051 else
3052 _XDefaultError (disp, event);
3053 }
3054 else
3055 {
3056 disp->flags |= XlibDisplayIOError;
3057 _XDefaultIOError (disp);
3058 } 3100 }
3101
3102 {
3103 char message[80];
3104
3105 XGetErrorText (disp, event->error_code, message, sizeof (message));
3106 fprintf (stderr, "Fatal X error:\n%s\n", message);
3107 }
3108
3059 UNBLOCK_INPUT; 3109 UNBLOCK_INPUT;
3060 3110
3061 x_death_handler (); 3111 x_death_handler ();
@@ -3430,34 +3480,32 @@ x_make_frame_invisible (f)
3430 3480
3431 BLOCK_INPUT; 3481 BLOCK_INPUT;
3432#ifdef HAVE_X11 3482#ifdef HAVE_X11
3433#if 0 3483 /* It would be nice if we didn't have to be backward compatible with
3484 very old versions of X, because then we could use the
3485 XWithdrawWindow function in R4 instead of writing it out ourselves. */
3486
3487 /* Tell the window manager what we've done. */
3434 if (! EQ (Vx_no_window_manager, Qt)) 3488 if (! EQ (Vx_no_window_manager, Qt))
3435 { 3489 {
3436 XUnmapEvent unmap; 3490 XEvent unmap;
3437
3438 unmap.type = UnmapNotify;
3439 unmap.window = f->display.x->window_desc;
3440 unmap.event = DefaultRootWindow (x_current_display);
3441 unmap.from_configure = False;
3442 XSendEvent (x_current_display, DefaultRootWindow (x_current_display),
3443 False, SubstructureRedirectMask|SubstructureNotifyMask,
3444 &unmap);
3445 }
3446
3447 /* The new function below does the same as the above code, plus unmapping
3448 the window. Sending the event without actually unmapping can make
3449 the window manager start ignoring the window (i.e., no more title bar,
3450 icon manager stuff.) */
3451#endif
3452 3491
3453 /* New function available with R4 */ 3492 unmap.xunmap.type = UnmapNotify;
3454 if (! XWithdrawWindow (x_current_display, f->display.x->window_desc, 3493 unmap.xunmap.window = f->display.x->window_desc;
3455 DefaultScreen (x_current_display))) 3494 unmap.xunmap.event = DefaultRootWindow (x_current_display);
3456 { 3495 unmap.xunmap.from_configure = False;
3457 UNBLOCK_INPUT_RESIGNAL; 3496 if (! XSendEvent (x_current_display,
3458 error ("Can't notify window manager of iconification."); 3497 DefaultRootWindow (x_current_display),
3498 False,
3499 SubstructureRedirectMask|SubstructureNotifyMask,
3500 &unmap))
3501 {
3502 UNBLOCK_INPUT_RESIGNAL;
3503 error ("can't notify window manager of withdrawal");
3504 }
3459 } 3505 }
3460 3506
3507 /* Unmap the window ourselves. Cheeky! */
3508 XUnmapWindow (x_current_display, f->display.x->window_desc);
3461#else 3509#else
3462 XUnmapWindow (XDISPLAY f->display.x->window_desc); 3510 XUnmapWindow (XDISPLAY f->display.x->window_desc);
3463 3511
@@ -3470,7 +3518,7 @@ x_make_frame_invisible (f)
3470 UNBLOCK_INPUT; 3518 UNBLOCK_INPUT;
3471} 3519}
3472 3520
3473 /* Window manager communication. Created in Fx_open_connection. */ 3521/* Window manager communication. Created in Fx_open_connection. */
3474extern Atom Xatom_wm_change_state; 3522extern Atom Xatom_wm_change_state;
3475 3523
3476/* Change window state from mapped to iconified. */ 3524/* Change window state from mapped to iconified. */
@@ -3486,37 +3534,36 @@ x_iconify_frame (f)
3486 BLOCK_INPUT; 3534 BLOCK_INPUT;
3487 3535
3488#ifdef HAVE_X11 3536#ifdef HAVE_X11
3489 if (! EQ (Vx_no_window_manager, Qt)) 3537 /* Since we don't know which revision of X we're running, we'll use both
3490 if (! XIconifyWindow (x_current_display, f->display.x->window_desc, 3538 the X11R3 and X11R4 techniques. I don't know if this is a good idea. */
3491 DefaultScreen (x_current_display))) 3539
3540 /* X11R4: send a ClientMessage to the window manager using the
3541 WM_CHANGE_STATE type. */
3542 {
3543 XEvent message;
3544
3545 message.xclient.window = f->display.x->window_desc;
3546 message.xclient.type = ClientMessage;
3547 message.xclient.message_type = Xatom_wm_change_state;
3548 message.xclient.format = 32;
3549 message.xclient.data.l[0] = IconicState;
3550
3551 if (! XSendEvent (x_current_display,
3552 DefaultRootWindow (x_current_display),
3553 False,
3554 SubstructureRedirectMask | SubstructureNotifyMask,
3555 &message))
3492 { 3556 {
3493 UNBLOCK_INPUT_RESIGNAL; 3557 UNBLOCK_INPUT_RESIGNAL;
3494 error ("Can't notify window manager of iconification."); 3558 error ("Can't notify window manager of iconification.");
3495 } 3559 }
3560 }
3496 3561
3497 f->iconified = 1; 3562 /* X11R3: set the initial_state field of the window manager hints to
3498 3563 IconicState. */
3499#if 0 3564 x_wm_set_window_state (f, IconicState);
3500 {
3501 XClientMessageEvent message;
3502
3503 message.window = f->display.x->window_desc;
3504 message.type = ClientMessage;
3505 message.message_type = Xatom_wm_change_state;
3506 message.format = 32;
3507 message.data.l[0] = IconicState;
3508 3565
3509 if (! XSendEvent (x_current_display, 3566 f->iconified = 1;
3510 DefaultRootWindow (x_current_display),
3511 False,
3512 SubstructureRedirectMask | SubstructureNotifyMask,
3513 &message))
3514 {
3515 UNBLOCK_INPUT_RESIGNAL;
3516 error ("Can't notify window manager of iconification.");
3517 }
3518 }
3519#endif
3520#else /* X10 */ 3567#else /* X10 */
3521 XUnmapWindow (XDISPLAY f->display.x->window_desc); 3568 XUnmapWindow (XDISPLAY f->display.x->window_desc);
3522 3569
@@ -3654,23 +3701,15 @@ x_wm_set_size_hint (f, prompting)
3654 (x_screen_height - ((2 * f->display.x->internal_border_width) 3701 (x_screen_height - ((2 * f->display.x->internal_border_width)
3655 + f->display.x->h_scrollbar_height)); 3702 + f->display.x->h_scrollbar_height));
3656 { 3703 {
3657 int base_width = ((2 * f->display.x->internal_border_width) 3704 int min_rows = 0, min_cols = 0;
3658 + f->display.x->v_scrollbar_width); 3705 check_frame_size (f, &min_rows, &min_cols);
3659 int base_height = ((2 * f->display.x->internal_border_width) 3706 size_hints.min_width = ((2 * f->display.x->internal_border_width)
3660 + f->display.x->h_scrollbar_height); 3707 + min_cols * size_hints.width_inc
3661 3708 + f->display.x->v_scrollbar_width);
3662#ifdef PBaseSize 3709 size_hints.min_height = ((2 * f->display.x->internal_border_width)
3663 size_hints.flags |= PBaseSize; 3710 + min_rows * size_hints.height_inc
3664 size_hints.base_width = base_width; 3711 + f->display.x->h_scrollbar_height);
3665 size_hints.base_height = base_height;
3666#endif
3667 3712
3668 {
3669 int min_rows = 0, min_cols = 0;
3670 check_frame_size (f, &min_rows, &min_cols);
3671 size_hints.min_width = base_width + min_cols * size_hints.width_inc;
3672 size_hints.min_height = base_height + min_rows * size_hints.height_inc;
3673 }
3674 } 3713 }
3675 3714
3676 if (prompting) 3715 if (prompting)
@@ -3689,11 +3728,8 @@ x_wm_set_size_hint (f, prompting)
3689 if (hints.flags & USSize) 3728 if (hints.flags & USSize)
3690 size_hints.flags |= USSize; 3729 size_hints.flags |= USSize;
3691 } 3730 }
3692 3731
3693#if 0 /* R3 */
3694 XSetNormalHints (x_current_display, window, &size_hints); 3732 XSetNormalHints (x_current_display, window, &size_hints);
3695#endif
3696 XSetWMNormalHints (x_current_display, window, &size_hints);
3697} 3733}
3698 3734
3699/* Used for IconicState or NormalState */ 3735/* Used for IconicState or NormalState */
@@ -3703,10 +3739,10 @@ x_wm_set_window_state (f, state)
3703{ 3739{
3704 Window window = f->display.x->window_desc; 3740 Window window = f->display.x->window_desc;
3705 3741
3706 x_wm_hints.flags |= StateHint; 3742 f->display.x->wm_hints.flags |= StateHint;
3707 x_wm_hints.initial_state = state; 3743 f->display.x->wm_hints.initial_state = state;
3708 3744
3709 XSetWMHints (x_current_display, window, &x_wm_hints); 3745 XSetWMHints (x_current_display, window, &f->display.x->wm_hints);
3710} 3746}
3711 3747
3712x_wm_set_icon_pixmap (f, icon_pixmap) 3748x_wm_set_icon_pixmap (f, icon_pixmap)
@@ -3715,15 +3751,10 @@ x_wm_set_icon_pixmap (f, icon_pixmap)
3715{ 3751{
3716 Window window = f->display.x->window_desc; 3752 Window window = f->display.x->window_desc;
3717 3753
3718 if (icon_pixmap) 3754 f->display.x->wm_hints.flags |= IconPixmapHint;
3719 { 3755 f->display.x->wm_hints.icon_pixmap = icon_pixmap ? icon_pixmap : None;
3720 x_wm_hints.flags |= IconPixmapHint;
3721 x_wm_hints.icon_pixmap = icon_pixmap;
3722 }
3723 else
3724 x_wm_hints.flags &= ~IconPixmapHint;
3725 3756
3726 XSetWMHints (x_current_display, window, &x_wm_hints); 3757 XSetWMHints (x_current_display, window, &f->display.x->wm_hints);
3727} 3758}
3728 3759
3729x_wm_set_icon_position (f, icon_x, icon_y) 3760x_wm_set_icon_position (f, icon_x, icon_y)
@@ -3732,11 +3763,11 @@ x_wm_set_icon_position (f, icon_x, icon_y)
3732{ 3763{
3733 Window window = f->display.x->window_desc; 3764 Window window = f->display.x->window_desc;
3734 3765
3735 x_wm_hints.flags |= IconPositionHint; 3766 f->display.x->wm_hints.flags |= IconPositionHint;
3736 x_wm_hints.icon_x = icon_x; 3767 f->display.x->wm_hints.icon_x = icon_x;
3737 x_wm_hints.icon_y = icon_y; 3768 f->display.x->wm_hints.icon_y = icon_y;
3738 3769
3739 XSetWMHints (x_current_display, window, &x_wm_hints); 3770 XSetWMHints (x_current_display, window, &f->display.x->wm_hints);
3740} 3771}
3741 3772
3742 3773
@@ -3759,7 +3790,7 @@ x_term_init (display_name)
3759 3790
3760#ifdef HAVE_X11 3791#ifdef HAVE_X11
3761 { 3792 {
3762 int hostname_size = MAXHOSTNAMELEN + 1; 3793 int hostname_size = 256;
3763 3794
3764 hostname = (char *) xmalloc (hostname_size); 3795 hostname = (char *) xmalloc (hostname_size);
3765 3796
@@ -3861,22 +3892,6 @@ x_term_init (display_name)
3861#endif /* SIGWINCH */ 3892#endif /* SIGWINCH */
3862 3893
3863 signal (SIGPIPE, x_death_handler); 3894 signal (SIGPIPE, x_death_handler);
3864
3865 /* When XSetWMHints eventually gets called, this will indicate that
3866 we use the "Passive Input" input model. Unless we do this, we
3867 don't get the Focus{In,Out} events that we need to draw the
3868 cursor correctly. Accursed bureaucrats.
3869
3870 We set this here and leave it, because we know, being decidedly
3871 non-humble programmers (nay, weigh'd low by our hubris!), that
3872 Fx_create_frame calls x_icon which begat x_wm_set_window_state
3873 which begat XSetWMHints, which will get this information to the
3874 right parties.
3875
3876 XWhipsAndChains (x_current_display, IronMaiden, &TheRack); */
3877
3878 x_wm_hints.input = True;
3879 x_wm_hints.flags |= InputHint;
3880} 3895}
3881 3896
3882void 3897void