comparison src/xterm.c @ 1020:7c2565dd644c

* 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 <sys/types.h>. * 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.
author Jim Blandy <jimb@redhat.com>
date Wed, 19 Aug 1992 06:51:44 +0000
parents cbdfc337ec8f
children b8defcaf1b61
comparison
equal deleted inserted replaced
1019:aaa628aaf808 1020:7c2565dd644c
36 36
37 /* This may include sys/types.h, and that somehow loses 37 /* This may include sys/types.h, and that somehow loses
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>
46 #endif
45 #endif 47 #endif
46 48
47 #ifdef BSD 49 #ifdef BSD
48 #include <sys/ioctl.h> 50 #include <sys/ioctl.h>
49 #include <strings.h> 51 #include <strings.h>
151 153
152 extern Lisp_Object Vcommand_line_args; 154 extern Lisp_Object Vcommand_line_args;
153 char *hostname, *x_id_name; 155 char *hostname, *x_id_name;
154 Lisp_Object invocation_name; 156 Lisp_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. */
167 XWMHints 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
171 Display *x_current_display; 160 Display *x_current_display;
172 161
173 /* Frame being updated by update_frame. */ 162 /* Frame being updated by update_frame. */
267 #endif 256 #endif
268 257
269 void dumpborder (); 258 void dumpborder ();
270 static int XTcursor_to (); 259 static int XTcursor_to ();
271 static int XTclear_end_of_line (); 260 static int XTclear_end_of_line ();
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
275 x_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
272 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
276 need to take a frame as argument. Most of the XT... functions 321 need to take a frame as argument. Most of the XT... functions
2860 } 2905 }
2861 2906
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
2866 static SIGTYPE 2914 static SIGTYPE
2867 x_death_handler () 2915 x_death_handler ()
2868 { 2916 {
2869 if (_Xdebug) 2917 if (_Xdebug)
2870 abort (); 2918 abort ();
2994 "SetModifierMapping", 3042 "SetModifierMapping",
2995 "GetModifierMapping", 3043 "GetModifierMapping",
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
3001 x_handle_error_gracefully (event) 3054 x_handle_error_gracefully (event)
3002 XErrorEvent *event; 3055 XErrorEvent *event;
3003 { 3056 {
3016 extern int x_converting_selection; 3069 extern int x_converting_selection;
3017 #endif 3070 #endif
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
3026 x_error_handler (disp, event) 3075 x_error_handler (disp, event)
3027 Display *disp; 3076 Display *disp;
3028 #ifdef HAVE_X11 3077 #ifdef HAVE_X11
3029 XErrorEvent *event; 3078 XErrorEvent *event;
3030 3079
3046 else 3095 else
3047 #endif 3096 #endif
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 3100 }
3052 _XDefaultError (disp, event); 3101
3053 } 3102 {
3054 else 3103 char message[80];
3055 { 3104
3056 disp->flags |= XlibDisplayIOError; 3105 XGetErrorText (disp, event->error_code, message, sizeof (message));
3057 _XDefaultIOError (disp); 3106 fprintf (stderr, "Fatal X error:\n%s\n", message);
3058 } 3107 }
3108
3059 UNBLOCK_INPUT; 3109 UNBLOCK_INPUT;
3060 3110
3061 x_death_handler (); 3111 x_death_handler ();
3062 } 3112 }
3063 3113
3428 if (! f->visible) 3478 if (! f->visible)
3429 return; 3479 return;
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 3491
3438 unmap.type = UnmapNotify; 3492 unmap.xunmap.type = UnmapNotify;
3439 unmap.window = f->display.x->window_desc; 3493 unmap.xunmap.window = f->display.x->window_desc;
3440 unmap.event = DefaultRootWindow (x_current_display); 3494 unmap.xunmap.event = DefaultRootWindow (x_current_display);
3441 unmap.from_configure = False; 3495 unmap.xunmap.from_configure = False;
3442 XSendEvent (x_current_display, DefaultRootWindow (x_current_display), 3496 if (! XSendEvent (x_current_display,
3443 False, SubstructureRedirectMask|SubstructureNotifyMask, 3497 DefaultRootWindow (x_current_display),
3444 &unmap); 3498 False,
3445 } 3499 SubstructureRedirectMask|SubstructureNotifyMask,
3446 3500 &unmap))
3447 /* The new function below does the same as the above code, plus unmapping 3501 {
3448 the window. Sending the event without actually unmapping can make 3502 UNBLOCK_INPUT_RESIGNAL;
3449 the window manager start ignoring the window (i.e., no more title bar, 3503 error ("can't notify window manager of withdrawal");
3450 icon manager stuff.) */ 3504 }
3451 #endif 3505 }
3452 3506
3453 /* New function available with R4 */ 3507 /* Unmap the window ourselves. Cheeky! */
3454 if (! XWithdrawWindow (x_current_display, f->display.x->window_desc, 3508 XUnmapWindow (x_current_display, f->display.x->window_desc);
3455 DefaultScreen (x_current_display)))
3456 {
3457 UNBLOCK_INPUT_RESIGNAL;
3458 error ("Can't notify window manager of iconification.");
3459 }
3460
3461 #else 3509 #else
3462 XUnmapWindow (XDISPLAY f->display.x->window_desc); 3510 XUnmapWindow (XDISPLAY f->display.x->window_desc);
3463 3511
3464 f->visible = 0; /* Handled by the UnMap event for X11 */ 3512 f->visible = 0; /* Handled by the UnMap event for X11 */
3465 if (f->display.x->icon_desc != 0) 3513 if (f->display.x->icon_desc != 0)
3468 3516
3469 XFlushQueue (); 3517 XFlushQueue ();
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. */
3474 extern Atom Xatom_wm_change_state; 3522 extern Atom Xatom_wm_change_state;
3475 3523
3476 /* Change window state from mapped to iconified. */ 3524 /* Change window state from mapped to iconified. */
3477 3525
3478 x_iconify_frame (f) 3526 x_iconify_frame (f)
3484 return; 3532 return;
3485 3533
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 }
3561
3562 /* X11R3: set the initial_state field of the window manager hints to
3563 IconicState. */
3564 x_wm_set_window_state (f, IconicState);
3496 3565
3497 f->iconified = 1; 3566 f->iconified = 1;
3498
3499 #if 0
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
3509 if (! XSendEvent (x_current_display,
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
3523 f->visible = 0; /* Handled in the UnMap event for X11. */ 3570 f->visible = 0; /* Handled in the UnMap event for X11. */
3524 if (f->display.x->icon_desc != 0) 3571 if (f->display.x->icon_desc != 0)
3652 + f->display.x->v_scrollbar_width)); 3699 + f->display.x->v_scrollbar_width));
3653 size_hints.max_height = 3700 size_hints.max_height =
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; 3712
3666 #endif
3667
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)
3677 size_hints.flags |= prompting; 3716 size_hints.flags |= prompting;
3678 else 3717 else
3687 if (hints.flags & USPosition) 3726 if (hints.flags & USPosition)
3688 size_hints.flags |= USPosition; 3727 size_hints.flags |= USPosition;
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 */
3700 x_wm_set_window_state (f, state) 3736 x_wm_set_window_state (f, state)
3701 struct frame *f; 3737 struct frame *f;
3702 int state; 3738 int 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
3712 x_wm_set_icon_pixmap (f, icon_pixmap) 3748 x_wm_set_icon_pixmap (f, icon_pixmap)
3713 struct frame *f; 3749 struct frame *f;
3714 Pixmap icon_pixmap; 3750 Pixmap 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; 3756
3721 x_wm_hints.icon_pixmap = icon_pixmap; 3757 XSetWMHints (x_current_display, window, &f->display.x->wm_hints);
3722 }
3723 else
3724 x_wm_hints.flags &= ~IconPixmapHint;
3725
3726 XSetWMHints (x_current_display, window, &x_wm_hints);
3727 } 3758 }
3728 3759
3729 x_wm_set_icon_position (f, icon_x, icon_y) 3760 x_wm_set_icon_position (f, icon_x, icon_y)
3730 struct frame *f; 3761 struct frame *f;
3731 int icon_x, icon_y; 3762 int 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
3743 void 3774 void
3744 x_term_init (display_name) 3775 x_term_init (display_name)
3757 fatal ("X server %s not responding; check the DISPLAY environment variable or use \"-d\"\n", 3788 fatal ("X server %s not responding; check the DISPLAY environment variable or use \"-d\"\n",
3758 display_name); 3789 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
3766 #if 0 3797 #if 0
3767 XSetAfterFunction (x_current_display, x_trace_wire); 3798 XSetAfterFunction (x_current_display, x_trace_wire);
3859 #ifdef SIGWINCH 3890 #ifdef SIGWINCH
3860 signal (SIGWINCH, SIG_DFL); 3891 signal (SIGWINCH, SIG_DFL);
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
3882 void 3897 void
3883 syms_of_xterm () 3898 syms_of_xterm ()
3884 { 3899 {