diff --git a/hw/xquartz/X11Application.h b/hw/xquartz/X11Application.h index 56806867e..a20c13e64 100644 --- a/hw/xquartz/X11Application.h +++ b/hw/xquartz/X11Application.h @@ -108,6 +108,9 @@ X11ApplicationCanEnterRandR(void); void X11ApplicationMain(int argc, char **argv, char **envp); +void +X11ApplicationFatalError(const char *f, va_list args) __printflike(1, 0); + #define PREFS_APPSMENU "apps_menu" #define PREFS_FAKEBUTTONS "enable_fake_buttons" #define PREFS_KEYEQUIVS "enable_key_equivalents" diff --git a/hw/xquartz/X11Application.m b/hw/xquartz/X11Application.m index e1d35abbf..6f55bcd65 100644 --- a/hw/xquartz/X11Application.m +++ b/hw/xquartz/X11Application.m @@ -70,6 +70,7 @@ static dispatch_queue_t eventTranslationQueue; extern Bool noTestExtensions; extern Bool noRenderExtension; +extern BOOL serverRunning; #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 static TISInputSourceRef last_key_layout; @@ -1067,6 +1068,50 @@ NO] || XQuartzShieldingWindowLevel != 0) } } +void +X11ApplicationFatalError(const char *f, va_list args) +{ +#ifdef HAVE_LIBDISPATCH + NSString *title, *msg; + char *error_msg; + + /* This is called by FatalError() in the server thread just before + * we would abort. If the server never got off the ground, We should + * inform the user of the error rather than letting the ever-so-friendly + * CrashReporter do it for us. + * + * This also has the benefit of forcing user interaction rather than + * allowing an infinite throttled-restart if the crash occurs before + * we can drain the launchd socket. + */ + + if (serverRunning) { + return; + } + + title = NSLocalizedString(@"The application X11 could not be opened.", + @"Dialog title when encountering a fatal error"); + msg = NSLocalizedString(@"An error occurred while starting the X11 server: \"%s\"\n\nClick Quit to quit X11. Click Report to see more details or send a report to Apple.", + @"Dialog when encountering a fatal error"); + + vasprintf(&error_msg, f, args); + msg = [NSString stringWithFormat:msg, error_msg]; + + /* We want the AppKit thread to actually service the alert or we will race [NSApp run] and create an + * 'NSInternalInconsistencyException', reason: 'NSApp with wrong _running count' + */ + dispatch_sync(dispatch_get_main_queue(), ^{ + if (NSAlertDefaultReturn == NSRunAlertPanel(title, msg, NSLocalizedString(@"Quit", @""), + NSLocalizedString (@"Report...", @""), nil)) { + exit(EXIT_FAILURE); + } + }); + + /* fall back to caller to do the abort() in the DIX */ +#endif +} + + static void check_xinitrc(void) { diff --git a/hw/xquartz/bundle/Resources/English.lproj/Localizable.strings b/hw/xquartz/bundle/Resources/English.lproj/Localizable.strings index bf2089ca1..36ae0ffb3 100644 Binary files a/hw/xquartz/bundle/Resources/English.lproj/Localizable.strings and b/hw/xquartz/bundle/Resources/English.lproj/Localizable.strings differ diff --git a/hw/xquartz/darwin.c b/hw/xquartz/darwin.c index 3dd41cba8..f9acf906c 100644 --- a/hw/xquartz/darwin.c +++ b/hw/xquartz/darwin.c @@ -78,6 +78,8 @@ #include "quartzKeyboard.h" #include "quartz.h" +#include "X11Application.h" + aslclient aslc; void @@ -636,7 +638,7 @@ InitOutput(ScreenInfo * pScreenInfo, int argc, char **argv) void OsVendorFatalError(const char *f, va_list args) { - ErrorF(" OsVendorFatalError\n"); + X11ApplicationFatalError(f, args); } /*