diff --git a/hw/xwin/InitOutput.c b/hw/xwin/InitOutput.c index a8a8cac24..541503552 100644 --- a/hw/xwin/InitOutput.c +++ b/hw/xwin/InitOutput.c @@ -633,6 +633,9 @@ OsVendorInit(void) winFixupPaths(); + if (!OsVendorVErrorFProc) + OsVendorVErrorFProc = OsVendorVErrorF; + if (!g_fLogInited) { /* keep this order. If LogInit fails it calls Abort which then calls * ddxGiveUp where LogInit is called again and creates an infinite diff --git a/hw/xwin/win.h b/hw/xwin/win.h index 44736a08b..49a2031d3 100644 --- a/hw/xwin/win.h +++ b/hw/xwin/win.h @@ -742,6 +742,10 @@ void * winerror.c */ +void +OsVendorVErrorF(const char *pszFormat, va_list va_args) +_X_ATTRIBUTE_PRINTF(1, 0); + void winMessageBoxF(const char *pszError, UINT uType, ...) _X_ATTRIBUTE_PRINTF(1, 3); diff --git a/hw/xwin/winerror.c b/hw/xwin/winerror.c index 401481327..bdf03f053 100644 --- a/hw/xwin/winerror.c +++ b/hw/xwin/winerror.c @@ -39,6 +39,23 @@ #include "dix/input_priv.h" +void +OsVendorVErrorF(const char *pszFormat, va_list va_args) +{ + /* make sure the clipboard and multiwindow threads do not interfere the + * main thread */ + static pthread_mutex_t s_pmPrinting = PTHREAD_MUTEX_INITIALIZER; + + /* Lock the printing mutex */ + pthread_mutex_lock(&s_pmPrinting); + + /* Print the error message to a log file, could be stderr */ + LogVMessageVerb(X_NONE, 0, pszFormat, va_args); + + /* Unlock the printing mutex */ + pthread_mutex_unlock(&s_pmPrinting); +} + /* * os/log.c:FatalError () calls our vendor ErrorF, so the message * from a FatalError will be logged. diff --git a/hw/xwin/winprocarg.c b/hw/xwin/winprocarg.c index d87c40936..4f753982f 100644 --- a/hw/xwin/winprocarg.c +++ b/hw/xwin/winprocarg.c @@ -225,6 +225,12 @@ ddxProcessArgument(int argc, char *argv[], int i) /* Initialize once */ if (!s_fBeenHere) { + /* + * This initialises our hook into VErrorF () for catching log messages + * that are generated before OsInit () is called. + */ + OsVendorVErrorFProc = OsVendorVErrorF; + s_fBeenHere = TRUE; /* Initialize only if option is not -help */ diff --git a/os/log.c b/os/log.c index 045c5aafd..3e87b9541 100644 --- a/os/log.c +++ b/os/log.c @@ -105,6 +105,8 @@ OR PERFORMANCE OF THIS SOFTWARE. #pragma clang diagnostic ignored "-Wformat-nonliteral" #endif +void (*OsVendorVErrorFProc) (const char *, va_list args) = NULL; + /* Default logging parameters. */ #define DEFAULT_LOG_VERBOSITY 0 #define DEFAULT_LOG_FILE_VERBOSITY 3 @@ -890,7 +892,10 @@ FatalError(const char *f, ...) void VErrorF(const char *f, va_list args) { - LogVMessageVerb(X_NONE, -1, f, args); + if (OsVendorVErrorFProc) + OsVendorVErrorFProc(f, args); + else + LogVMessageVerb(X_NONE, -1, f, args); } void diff --git a/os/osdep.h b/os/osdep.h index 3c198a712..7a1b46bf3 100644 --- a/os/osdep.h +++ b/os/osdep.h @@ -174,6 +174,10 @@ int os_move_fd(int fd); depending on whether multithreading is used */ int xthread_sigmask(int how, const sigset_t *set, sigset_t *oldest); +/* callback for DDX specific error printing, if any (may be NULL) */ +extern void (*OsVendorVErrorFProc) (const char *, va_list args) + _X_ATTRIBUTE_PRINTF(1, 0); + typedef void (*OsSigHandlerPtr) (int sig); /* install signal handler */