To: vim-dev@vim.org Subject: patch 5.4o.4 Fcc: outbox From: Bram Moolenaar ------------ 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 ---- Bram@moolenaar.net ---- Bram@vim.org ---\-\-- \ \ www.vim.org/iccf www.moolenaar.net www.vim.org / /