To: [email protected]
Subject: patch 5.4o.4
Fcc: outbox
From: Bram Moolenaar <[email protected]>
------------

Patch 5.4o.4
Problem:    When running in an xterm and $WINDOWID is set to an illegal value,
           Vim would exit with "Vim: Got X error".
Solution:   When using the display which was opened for the xterm clipboard,
           check if x11_window is valid by trying to obtain the window title.
           Also add a check in setup_xterm_clip(), for when using X calls to
           get the pointer position in an xterm.
Files:      src/os_unix.c


*** ../vim-5.4o/src/os_unix.c   Sun Jul 11 20:10:59 1999
--- src/os_unix.c       Tue Jul 13 16:35:59 1999
***************
*** 121,126 ****
--- 121,127 ----

 # ifdef WANT_TITLE
 static int  get_x11_windis __ARGS((void));
+ static int  test_x11_window __ARGS((Display *dpy));
 static void set_x11_title __ARGS((char_u *));
 static void set_x11_icon __ARGS((char_u *));
 # endif
***************
*** 725,736 ****
     XGetErrorText(dpy, error_event->error_code, (char *)IObuff, IOSIZE);
     STRCAT(IObuff, "\nVim: Got X error\n");

! #if 1
     preserve_exit();              /* preserve files and exit */
- #else
-     printf(IObuff);               /* print error message and continue */
-                                   /* Makes my system hang */
- #endif

     return 0;         /* NOTREACHED */
 }
--- 726,735 ----
     XGetErrorText(dpy, error_event->error_code, (char *)IObuff, IOSIZE);
     STRCAT(IObuff, "\nVim: Got X error\n");

!     /* We cannot print a message and continue, because no X calls are allowed
!      * here (causes my system to hang).  Silently continuing might be an
!      * alternative... */
     preserve_exit();              /* preserve files and exit */

     return 0;         /* NOTREACHED */
 }
***************
*** 762,769 ****
 get_x11_windis()
 {
     char          *winid;
-     XTextProperty   text_prop;
-     int                   (*old_handler)();
     static int            result = -1;
 #define XD_NONE        0      /* x11_display not set here */
 #define XD_HERE        1      /* x11_display opened here */
--- 761,766 ----
***************
*** 786,794 ****
           XCloseDisplay(x11_display);
           x11_display = NULL;
       }
!       gui_get_x11_windis(&x11_window, &x11_display);
!       x11_display_from = XD_GUI;
!       return OK;
     }
     else if (x11_display_from == XD_GUI)
     {
--- 783,794 ----
           XCloseDisplay(x11_display);
           x11_display = NULL;
       }
!       if (gui_get_x11_windis(&x11_window, &x11_display) == OK)
!       {
!           x11_display_from = XD_GUI;
!           return OK;
!       }
!       return FAIL;
     }
     else if (x11_display_from == XD_GUI)
     {
***************
*** 819,824 ****
--- 819,832 ----
           XCloseDisplay(x11_display);
       x11_display = xterm_dpy;
       x11_display_from = XD_XTERM;
+       if (test_x11_window(x11_display) == FAIL)
+       {
+           /* probably bad $WINDOWID */
+           x11_window = 0;
+           x11_display = NULL;
+           x11_display_from = XD_NONE;
+           return FAIL;
+       }
       return OK;
     }
 #endif
***************
*** 854,872 ****
 #endif
       if (x11_display != NULL)
       {
!           /*
!            * Try to get the window title.  I don't actually want it yet, so
!            * there may be a simpler call to use, but this will cause the
!            * error handler x_error_check() to be called if anything is wrong,
!            * such as the window pointer being invalid (as can happen when the
!            * user changes his DISPLAY, but not his WINDOWID) -- webb
!            */
!           old_handler = XSetErrorHandler(x_error_check);
!           got_x_error = FALSE;
!           if (XGetWMName(x11_display, x11_window, &text_prop))
!               XFree((void *)text_prop.value);
!           XSync(x11_display, False);
!           if (got_x_error)
           {
               /* Maybe window id is bad */
               x11_window = 0;
--- 862,868 ----
 #endif
       if (x11_display != NULL)
       {
!           if (test_x11_window(x11_display) == FAIL)
           {
               /* Maybe window id is bad */
               x11_window = 0;
***************
*** 875,881 ****
           }
           else
               x11_display_from = XD_HERE;
-           XSetErrorHandler(old_handler);
       }
     }
     if (x11_window == 0 || x11_display == NULL)
--- 871,876 ----
***************
*** 884,889 ****
--- 879,908 ----
 }

 /*
+  * Test if "dpy" and x11_window are valid by getting the window title.
+  * I don't actually want it yet, so there may be a simpler call to use, but
+  * this will cause the error handler x_error_check() to be called if anything
+  * is wrong, such as the window pointer being invalid (as can happen when the
+  * user changes his DISPLAY, but not his WINDOWID) -- webb
+  */
+     static int
+ test_x11_window(dpy)
+     Display   *dpy;
+ {
+     int                       (*old_handler)();
+     XTextProperty     text_prop;
+
+     old_handler = XSetErrorHandler(x_error_check);
+     got_x_error = FALSE;
+     if (XGetWMName(dpy, x11_window, &text_prop))
+       XFree((void *)text_prop.value);
+     XSync(dpy, False);
+     (void)XSetErrorHandler(old_handler);
+
+     return (got_x_error ? FAIL : OK);
+ }
+
+ /*
  * Determine original x11 Window Title
  */
     static int
***************
*** 3825,3837 ****
     open_app_context();
     if (app_context != NULL && xterm_Shell == (Widget)0)
     {
       xterm_dpy = XtOpenDisplay(app_context, xterm_display,
               "vim_xterm", "Vim_xterm", NULL, 0, &z, &strp);
       if (xterm_dpy == NULL)
           return;
!       /*
!        * So converters work.
!        */
       AppShell = XtVaAppCreateShell("vim_xterm", "Vim_xterm",
               applicationShellWidgetClass, xterm_dpy,
               NULL);
--- 3844,3862 ----
     open_app_context();
     if (app_context != NULL && xterm_Shell == (Widget)0)
     {
+       /* Ignore X errors while opening the display */
+       XSetErrorHandler(x_error_check);
+
       xterm_dpy = XtOpenDisplay(app_context, xterm_display,
               "vim_xterm", "Vim_xterm", NULL, 0, &z, &strp);
+
+       /* Now handle X errors normally. */
+       XSetErrorHandler(x_error_handler);
+
       if (xterm_dpy == NULL)
           return;
!
!       /* Create a Shell to make converters work. */
       AppShell = XtVaAppCreateShell("vim_xterm", "Vim_xterm",
               applicationShellWidgetClass, xterm_dpy,
               NULL);
***************
*** 3859,3864 ****
--- 3884,3892 ----
       clip_init(TRUE);
       if (x11_window == 0 && (strp = getenv("WINDOWID")) != NULL)
           x11_window = (Window)atol(strp);
+       /* Check if $WINDOWID is valid. */
+       if (test_x11_window(xterm_dpy) == FAIL)
+           x11_window = 0;
       if (x11_window != 0)
           xterm_trace = 0;
     }

--
hundred-and-one symptoms of being an internet addict:
80. At parties, you introduce your spouse as your "service provider."

--/-/---- Bram Moolenaar ---- [email protected] ---- [email protected] ---\-\--
 \ \    www.vim.org/iccf      www.moolenaar.net       www.vim.org    / /