src/SDL_log.c
changeset 7274 d9ef44d91559
parent 7215 41e739a52f69
child 7292 fdf42e4cdcec
     1.1 --- a/src/SDL_log.c	Tue Jun 04 22:13:06 2013 -0700
     1.2 +++ b/src/SDL_log.c	Wed Jun 05 07:22:45 2013 -0700
     1.3 @@ -39,6 +39,9 @@
     1.4  #define DEFAULT_APPLICATION_PRIORITY    SDL_LOG_PRIORITY_INFO
     1.5  #define DEFAULT_TEST_PRIORITY           SDL_LOG_PRIORITY_VERBOSE
     1.6  
     1.7 +/* Forward definition of error function */
     1.8 +extern int SDL_SetError(const char *fmt, ...);
     1.9 +
    1.10  typedef struct SDL_LogLevel
    1.11  {
    1.12      int category;
    1.13 @@ -288,6 +291,14 @@
    1.14      SDL_stack_free(message);
    1.15  }
    1.16  
    1.17 +#if defined(__WIN32__)
    1.18 +/* Flag tracking the attachment of the console: 0=unattached, 1=attached, -1=error */
    1.19 +static int consoleAttached = 0;
    1.20 +
    1.21 +/* Handle to stderr output of console. */
    1.22 +static HANDLE stderrHandle = NULL;
    1.23 +#endif
    1.24 +
    1.25  static void
    1.26  SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
    1.27                const char *message)
    1.28 @@ -298,12 +309,60 @@
    1.29          char *output;
    1.30          size_t length;
    1.31          LPTSTR tstr;
    1.32 +        BOOL pbRemoteDebuggerPresent;        
    1.33 +        BOOL attachResult;
    1.34 +        DWORD attachError;
    1.35 +        unsigned long charsWritten; 
    1.36 +
    1.37 +        /* Maybe attach console and get stderr handle */
    1.38 +        if (consoleAttached == 0) {
    1.39 +            attachResult = AttachConsole(ATTACH_PARENT_PROCESS);
    1.40 +            if (!attachResult) {
    1.41 +                    attachError = GetLastError();
    1.42 +                    if (attachError == ERROR_INVALID_HANDLE) {
    1.43 +                        SDL_SetError("Parent process has no console");
    1.44 +                        consoleAttached = -1;
    1.45 +                    } else if (attachError == ERROR_GEN_FAILURE) {
    1.46 +                         SDL_SetError("Could not attach to console of parent process");
    1.47 +                         consoleAttached = -1;
    1.48 +                    } else if (attachError == ERROR_ACCESS_DENIED) {  
    1.49 +                         /* Already attached */
    1.50 +                        consoleAttached = 1;
    1.51 +                    } else {
    1.52 +                        SDL_SetError("Error %d attaching console", attachError);
    1.53 +                        consoleAttached = -1;
    1.54 +                    }
    1.55 +                } else {
    1.56 +                    /* Newly attached */
    1.57 +                    consoleAttached = 1;
    1.58 +                }
    1.59 +			
    1.60 +                if (consoleAttached == 1) {
    1.61 +                        stderrHandle = GetStdHandle(STD_ERROR_HANDLE);
    1.62 +                }
    1.63 +        }
    1.64  
    1.65          length = SDL_strlen(SDL_priority_prefixes[priority]) + 2 + SDL_strlen(message) + 1 + 1;
    1.66          output = SDL_stack_alloc(char, length);
    1.67          SDL_snprintf(output, length, "%s: %s\n", SDL_priority_prefixes[priority], message);
    1.68          tstr = WIN_UTF8ToString(output);
    1.69 -        OutputDebugString(tstr);
    1.70 +        
    1.71 +        /* Debugger output, if attached. Check each time since debugger can be attached at runtime. */
    1.72 +        CheckRemoteDebuggerPresent(GetCurrentProcess(), &pbRemoteDebuggerPresent);
    1.73 +        if (pbRemoteDebuggerPresent || IsDebuggerPresent()) {
    1.74 +            OutputDebugString(tstr);
    1.75 +        }
    1.76 +       
    1.77 +        /* Screen output to stderr, if console was attached. */
    1.78 +        if (consoleAttached == 1) {
    1.79 +                if (!WriteConsole(stderrHandle, tstr, lstrlen(tstr), &charsWritten, NULL)) {
    1.80 +                    SDL_SetError("Error %d calling WriteConsole", GetLastError());
    1.81 +                }
    1.82 +                if (charsWritten == ERROR_NOT_ENOUGH_MEMORY) {
    1.83 +                    SDL_SetError("Insufficient heap memory to write message of size %d", length);
    1.84 +                }
    1.85 +        }
    1.86 +
    1.87          SDL_free(tstr);
    1.88          SDL_stack_free(output);
    1.89      }