src/SDL_log.c
author Sam Lantinga
Mon, 09 Jan 2017 11:58:01 -0800
changeset 10802 6afc9b833867
parent 10737 3406a0f8b041
child 11284 3db78361e751
permissions -rw-r--r--
We only need the first few keymaps corresponding to the following constants:
K_NORMTAB, K_SHIFTTAB, K_ALTTAB, K_ALTSHIFTTAB

In the normal case we'll load all the keymaps from the kernel, but this reduces the size of the SDL library for the fallback case when we can't get to the tty.
slouken@8582
     1
/*
slouken@8582
     2
  Simple DirectMedia Layer
slouken@10737
     3
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
slouken@8582
     4
slouken@8582
     5
  This software is provided 'as-is', without any express or implied
slouken@8582
     6
  warranty.  In no event will the authors be held liable for any damages
slouken@8582
     7
  arising from the use of this software.
slouken@8582
     8
slouken@8582
     9
  Permission is granted to anyone to use this software for any purpose,
slouken@8582
    10
  including commercial applications, and to alter it and redistribute it
slouken@8582
    11
  freely, subject to the following restrictions:
slouken@8582
    12
slouken@8582
    13
  1. The origin of this software must not be misrepresented; you must not
slouken@8582
    14
     claim that you wrote the original software. If you use this software
slouken@8582
    15
     in a product, an acknowledgment in the product documentation would be
slouken@8582
    16
     appreciated but is not required.
slouken@8582
    17
  2. Altered source versions must be plainly marked as such, and must not be
slouken@8582
    18
     misrepresented as being the original software.
slouken@8582
    19
  3. This notice may not be removed or altered from any source distribution.
slouken@8582
    20
*/
icculus@8093
    21
#include "./SDL_internal.h"
slouken@8582
    22
slouken@8582
    23
#if defined(__WIN32__) || defined(__WINRT__)
slouken@8582
    24
#include "core/windows/SDL_windows.h"
slouken@8582
    25
#endif
slouken@8582
    26
slouken@8582
    27
/* Simple log messages in SDL */
slouken@8582
    28
slouken@8820
    29
#include "SDL_error.h"
slouken@8582
    30
#include "SDL_log.h"
slouken@8582
    31
slouken@8582
    32
#if HAVE_STDIO_H
slouken@8582
    33
#include <stdio.h>
slouken@8582
    34
#endif
slouken@8582
    35
slouken@8582
    36
#if defined(__ANDROID__)
slouken@8582
    37
#include <android/log.h>
slouken@8582
    38
#endif
slouken@8582
    39
slouken@8582
    40
#define DEFAULT_PRIORITY                SDL_LOG_PRIORITY_CRITICAL
slouken@8582
    41
#define DEFAULT_ASSERT_PRIORITY         SDL_LOG_PRIORITY_WARN
slouken@8582
    42
#define DEFAULT_APPLICATION_PRIORITY    SDL_LOG_PRIORITY_INFO
slouken@8582
    43
#define DEFAULT_TEST_PRIORITY           SDL_LOG_PRIORITY_VERBOSE
slouken@8582
    44
slouken@8582
    45
typedef struct SDL_LogLevel
slouken@8582
    46
{
slouken@8582
    47
    int category;
slouken@8582
    48
    SDL_LogPriority priority;
slouken@8582
    49
    struct SDL_LogLevel *next;
slouken@8582
    50
} SDL_LogLevel;
slouken@8582
    51
slouken@8582
    52
/* The default log output function */
slouken@8582
    53
static void SDL_LogOutput(void *userdata,
slouken@8582
    54
                          int category, SDL_LogPriority priority,
slouken@8582
    55
                          const char *message);
slouken@8582
    56
slouken@8582
    57
static SDL_LogLevel *SDL_loglevels;
slouken@8582
    58
static SDL_LogPriority SDL_default_priority = DEFAULT_PRIORITY;
slouken@8582
    59
static SDL_LogPriority SDL_assert_priority = DEFAULT_ASSERT_PRIORITY;
slouken@8582
    60
static SDL_LogPriority SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
slouken@8582
    61
static SDL_LogPriority SDL_test_priority = DEFAULT_TEST_PRIORITY;
slouken@8582
    62
static SDL_LogOutputFunction SDL_log_function = SDL_LogOutput;
slouken@8582
    63
static void *SDL_log_userdata = NULL;
slouken@8582
    64
slouken@8582
    65
static const char *SDL_priority_prefixes[SDL_NUM_LOG_PRIORITIES] = {
slouken@8582
    66
    NULL,
slouken@8582
    67
    "VERBOSE",
slouken@8582
    68
    "DEBUG",
slouken@8582
    69
    "INFO",
slouken@8582
    70
    "WARN",
slouken@8582
    71
    "ERROR",
slouken@8582
    72
    "CRITICAL"
slouken@8582
    73
};
slouken@8582
    74
slouken@8582
    75
#ifdef __ANDROID__
slouken@8582
    76
static const char *SDL_category_prefixes[SDL_LOG_CATEGORY_RESERVED1] = {
slouken@8582
    77
    "APP",
slouken@8582
    78
    "ERROR",
slouken@8582
    79
    "SYSTEM",
slouken@8582
    80
    "AUDIO",
slouken@8582
    81
    "VIDEO",
slouken@8582
    82
    "RENDER",
slouken@8582
    83
    "INPUT"
slouken@8582
    84
};
slouken@8582
    85
slouken@8582
    86
static int SDL_android_priority[SDL_NUM_LOG_PRIORITIES] = {
slouken@8582
    87
    ANDROID_LOG_UNKNOWN,
slouken@8582
    88
    ANDROID_LOG_VERBOSE,
slouken@8582
    89
    ANDROID_LOG_DEBUG,
slouken@8582
    90
    ANDROID_LOG_INFO,
slouken@8582
    91
    ANDROID_LOG_WARN,
slouken@8582
    92
    ANDROID_LOG_ERROR,
slouken@8582
    93
    ANDROID_LOG_FATAL
slouken@8582
    94
};
slouken@8582
    95
#endif /* __ANDROID__ */
slouken@8582
    96
slouken@8582
    97
slouken@8582
    98
void
slouken@8582
    99
SDL_LogSetAllPriority(SDL_LogPriority priority)
slouken@8582
   100
{
slouken@8582
   101
    SDL_LogLevel *entry;
slouken@8582
   102
slouken@8582
   103
    for (entry = SDL_loglevels; entry; entry = entry->next) {
slouken@8582
   104
        entry->priority = priority;
slouken@8582
   105
    }
slouken@8582
   106
    SDL_default_priority = priority;
slouken@8582
   107
    SDL_assert_priority = priority;
slouken@8582
   108
    SDL_application_priority = priority;
slouken@8582
   109
}
slouken@8582
   110
slouken@8582
   111
void
slouken@8582
   112
SDL_LogSetPriority(int category, SDL_LogPriority priority)
slouken@8582
   113
{
slouken@8582
   114
    SDL_LogLevel *entry;
slouken@8582
   115
slouken@8582
   116
    for (entry = SDL_loglevels; entry; entry = entry->next) {
slouken@8582
   117
        if (entry->category == category) {
slouken@8582
   118
            entry->priority = priority;
slouken@8582
   119
            return;
slouken@8582
   120
        }
slouken@8582
   121
    }
slouken@8582
   122
slouken@8582
   123
    /* Create a new entry */
slouken@8582
   124
    entry = (SDL_LogLevel *)SDL_malloc(sizeof(*entry));
slouken@8582
   125
    if (entry) {
slouken@8582
   126
        entry->category = category;
slouken@8582
   127
        entry->priority = priority;
slouken@8582
   128
        entry->next = SDL_loglevels;
slouken@8582
   129
        SDL_loglevels = entry;
slouken@8582
   130
    }
slouken@8582
   131
}
slouken@8582
   132
slouken@8582
   133
SDL_LogPriority
slouken@8582
   134
SDL_LogGetPriority(int category)
slouken@8582
   135
{
slouken@8582
   136
    SDL_LogLevel *entry;
slouken@8582
   137
slouken@8582
   138
    for (entry = SDL_loglevels; entry; entry = entry->next) {
slouken@8582
   139
        if (entry->category == category) {
slouken@8582
   140
            return entry->priority;
slouken@8582
   141
        }
slouken@8582
   142
    }
slouken@8582
   143
slouken@8582
   144
    if (category == SDL_LOG_CATEGORY_TEST) {
slouken@8582
   145
        return SDL_test_priority;
slouken@8582
   146
    } else if (category == SDL_LOG_CATEGORY_APPLICATION) {
slouken@8582
   147
        return SDL_application_priority;
slouken@8582
   148
    } else if (category == SDL_LOG_CATEGORY_ASSERT) {
slouken@8582
   149
        return SDL_assert_priority;
slouken@8582
   150
    } else {
slouken@8582
   151
        return SDL_default_priority;
slouken@8582
   152
    }
slouken@8582
   153
}
slouken@8582
   154
slouken@8582
   155
void
slouken@8582
   156
SDL_LogResetPriorities(void)
slouken@8582
   157
{
slouken@8582
   158
    SDL_LogLevel *entry;
slouken@8582
   159
slouken@8582
   160
    while (SDL_loglevels) {
slouken@8582
   161
        entry = SDL_loglevels;
slouken@8582
   162
        SDL_loglevels = entry->next;
slouken@8582
   163
        SDL_free(entry);
slouken@8582
   164
    }
slouken@8582
   165
slouken@8582
   166
    SDL_default_priority = DEFAULT_PRIORITY;
slouken@8582
   167
    SDL_assert_priority = DEFAULT_ASSERT_PRIORITY;
slouken@8582
   168
    SDL_application_priority = DEFAULT_APPLICATION_PRIORITY;
slouken@8582
   169
    SDL_test_priority = DEFAULT_TEST_PRIORITY;
slouken@8582
   170
}
slouken@8582
   171
slouken@8582
   172
void
slouken@8820
   173
SDL_Log(SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
slouken@8582
   174
{
slouken@8582
   175
    va_list ap;
slouken@8582
   176
slouken@8582
   177
    va_start(ap, fmt);
slouken@8582
   178
    SDL_LogMessageV(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, fmt, ap);
slouken@8582
   179
    va_end(ap);
slouken@8582
   180
}
slouken@8582
   181
slouken@8582
   182
void
slouken@8820
   183
SDL_LogVerbose(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
slouken@8582
   184
{
slouken@8582
   185
    va_list ap;
slouken@8582
   186
slouken@8582
   187
    va_start(ap, fmt);
slouken@8582
   188
    SDL_LogMessageV(category, SDL_LOG_PRIORITY_VERBOSE, fmt, ap);
slouken@8582
   189
    va_end(ap);
slouken@8582
   190
}
slouken@8582
   191
slouken@8582
   192
void
slouken@8820
   193
SDL_LogDebug(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
slouken@8582
   194
{
slouken@8582
   195
    va_list ap;
slouken@8582
   196
slouken@8582
   197
    va_start(ap, fmt);
slouken@8582
   198
    SDL_LogMessageV(category, SDL_LOG_PRIORITY_DEBUG, fmt, ap);
slouken@8582
   199
    va_end(ap);
slouken@8582
   200
}
slouken@8582
   201
slouken@8582
   202
void
slouken@8820
   203
SDL_LogInfo(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
slouken@8582
   204
{
slouken@8582
   205
    va_list ap;
slouken@8582
   206
slouken@8582
   207
    va_start(ap, fmt);
slouken@8582
   208
    SDL_LogMessageV(category, SDL_LOG_PRIORITY_INFO, fmt, ap);
slouken@8582
   209
    va_end(ap);
slouken@8582
   210
}
slouken@8582
   211
slouken@8582
   212
void
slouken@8820
   213
SDL_LogWarn(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
slouken@8582
   214
{
slouken@8582
   215
    va_list ap;
slouken@8582
   216
slouken@8582
   217
    va_start(ap, fmt);
slouken@8582
   218
    SDL_LogMessageV(category, SDL_LOG_PRIORITY_WARN, fmt, ap);
slouken@8582
   219
    va_end(ap);
slouken@8582
   220
}
slouken@8582
   221
slouken@8582
   222
void
slouken@8820
   223
SDL_LogError(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
slouken@8582
   224
{
slouken@8582
   225
    va_list ap;
slouken@8582
   226
slouken@8582
   227
    va_start(ap, fmt);
slouken@8582
   228
    SDL_LogMessageV(category, SDL_LOG_PRIORITY_ERROR, fmt, ap);
slouken@8582
   229
    va_end(ap);
slouken@8582
   230
}
slouken@8582
   231
slouken@8582
   232
void
slouken@8820
   233
SDL_LogCritical(int category, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
slouken@8582
   234
{
slouken@8582
   235
    va_list ap;
slouken@8582
   236
slouken@8582
   237
    va_start(ap, fmt);
slouken@8582
   238
    SDL_LogMessageV(category, SDL_LOG_PRIORITY_CRITICAL, fmt, ap);
slouken@8582
   239
    va_end(ap);
slouken@8582
   240
}
slouken@8582
   241
slouken@8582
   242
void
slouken@8820
   243
SDL_LogMessage(int category, SDL_LogPriority priority, SDL_PRINTF_FORMAT_STRING const char *fmt, ...)
slouken@8582
   244
{
slouken@8582
   245
    va_list ap;
slouken@8582
   246
slouken@8582
   247
    va_start(ap, fmt);
slouken@8582
   248
    SDL_LogMessageV(category, priority, fmt, ap);
slouken@8582
   249
    va_end(ap);
slouken@8582
   250
}
slouken@8582
   251
slouken@8582
   252
#ifdef __ANDROID__
slouken@8582
   253
static const char *
slouken@8582
   254
GetCategoryPrefix(int category)
slouken@8582
   255
{
slouken@8582
   256
    if (category < SDL_LOG_CATEGORY_RESERVED1) {
slouken@8582
   257
        return SDL_category_prefixes[category];
slouken@8582
   258
    }
slouken@8582
   259
    if (category < SDL_LOG_CATEGORY_CUSTOM) {
slouken@8582
   260
        return "RESERVED";
slouken@8582
   261
    }
slouken@8582
   262
    return "CUSTOM";
slouken@8582
   263
}
slouken@8582
   264
#endif /* __ANDROID__ */
slouken@8582
   265
slouken@8582
   266
void
slouken@8582
   267
SDL_LogMessageV(int category, SDL_LogPriority priority, const char *fmt, va_list ap)
slouken@8582
   268
{
slouken@8582
   269
    char *message;
slouken@8582
   270
    size_t len;
slouken@8582
   271
slouken@8582
   272
    /* Nothing to do if we don't have an output function */
slouken@8582
   273
    if (!SDL_log_function) {
slouken@8582
   274
        return;
slouken@8582
   275
    }
slouken@8582
   276
slouken@8582
   277
    /* Make sure we don't exceed array bounds */
slouken@8582
   278
    if ((int)priority < 0 || priority >= SDL_NUM_LOG_PRIORITIES) {
slouken@8582
   279
        return;
slouken@8582
   280
    }
slouken@8582
   281
slouken@8582
   282
    /* See if we want to do anything with this message */
slouken@8582
   283
    if (priority < SDL_LogGetPriority(category)) {
slouken@8582
   284
        return;
slouken@8582
   285
    }
slouken@8582
   286
slouken@8582
   287
    message = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
slouken@8582
   288
    if (!message) {
slouken@8582
   289
        return;
slouken@8582
   290
    }
slouken@8582
   291
slouken@8582
   292
    SDL_vsnprintf(message, SDL_MAX_LOG_MESSAGE, fmt, ap);
slouken@8582
   293
slouken@8582
   294
    /* Chop off final endline. */
slouken@8582
   295
    len = SDL_strlen(message);
slouken@8582
   296
    if ((len > 0) && (message[len-1] == '\n')) {
slouken@8582
   297
        message[--len] = '\0';
slouken@8582
   298
        if ((len > 0) && (message[len-1] == '\r')) {  /* catch "\r\n", too. */
slouken@8582
   299
            message[--len] = '\0';
slouken@8582
   300
        }
slouken@8582
   301
    }
slouken@8582
   302
slouken@8582
   303
    SDL_log_function(SDL_log_userdata, category, priority, message);
slouken@8582
   304
    SDL_stack_free(message);
slouken@8582
   305
}
slouken@8582
   306
slouken@10637
   307
#if defined(__WIN32__) && !defined(HAVE_STDIO_H) && !defined(__WINRT__)
slouken@8582
   308
/* Flag tracking the attachment of the console: 0=unattached, 1=attached, -1=error */
slouken@8582
   309
static int consoleAttached = 0;
slouken@8582
   310
slouken@8582
   311
/* Handle to stderr output of console. */
slouken@8582
   312
static HANDLE stderrHandle = NULL;
slouken@8582
   313
#endif
slouken@8582
   314
slouken@8582
   315
static void
slouken@8582
   316
SDL_LogOutput(void *userdata, int category, SDL_LogPriority priority,
slouken@8582
   317
              const char *message)
slouken@8582
   318
{
slouken@8582
   319
#if defined(__WIN32__) || defined(__WINRT__)
slouken@8582
   320
    /* Way too many allocations here, urgh */
slouken@8582
   321
    /* Note: One can't call SDL_SetError here, since that function itself logs. */
slouken@8582
   322
    {
slouken@8582
   323
        char *output;
slouken@8582
   324
        size_t length;
slouken@8582
   325
        LPTSTR tstr;
slouken@8582
   326
slouken@10412
   327
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__)
slouken@8582
   328
        BOOL attachResult;
slouken@8582
   329
        DWORD attachError;
slouken@8582
   330
        unsigned long charsWritten; 
slouken@8582
   331
slouken@8582
   332
        /* Maybe attach console and get stderr handle */
slouken@8582
   333
        if (consoleAttached == 0) {
slouken@8582
   334
            attachResult = AttachConsole(ATTACH_PARENT_PROCESS);
slouken@8582
   335
            if (!attachResult) {
slouken@8582
   336
                    attachError = GetLastError();
slouken@8582
   337
                    if (attachError == ERROR_INVALID_HANDLE) {
slouken@10686
   338
                        /* This is expected when running from Visual Studio */
slouken@10686
   339
                        /*OutputDebugString(TEXT("Parent process has no console\r\n"));*/
slouken@8582
   340
                        consoleAttached = -1;
slouken@8582
   341
                    } else if (attachError == ERROR_GEN_FAILURE) {
slouken@8582
   342
                         OutputDebugString(TEXT("Could not attach to console of parent process\r\n"));
slouken@8582
   343
                         consoleAttached = -1;
slouken@8582
   344
                    } else if (attachError == ERROR_ACCESS_DENIED) {  
slouken@8582
   345
                         /* Already attached */
slouken@8582
   346
                        consoleAttached = 1;
slouken@8582
   347
                    } else {
slouken@8582
   348
                        OutputDebugString(TEXT("Error attaching console\r\n"));
slouken@8582
   349
                        consoleAttached = -1;
slouken@8582
   350
                    }
slouken@8582
   351
                } else {
slouken@8582
   352
                    /* Newly attached */
slouken@8582
   353
                    consoleAttached = 1;
slouken@8582
   354
                }
slouken@8582
   355
			
slouken@8582
   356
                if (consoleAttached == 1) {
slouken@8582
   357
                        stderrHandle = GetStdHandle(STD_ERROR_HANDLE);
slouken@8582
   358
                }
slouken@8582
   359
        }
slouken@10412
   360
#endif /* !defined(HAVE_STDIO_H) && !defined(__WINRT__) */
slouken@8582
   361
slouken@8582
   362
        length = SDL_strlen(SDL_priority_prefixes[priority]) + 2 + SDL_strlen(message) + 1 + 1 + 1;
slouken@8582
   363
        output = SDL_stack_alloc(char, length);
slouken@8582
   364
        SDL_snprintf(output, length, "%s: %s\r\n", SDL_priority_prefixes[priority], message);
slouken@8582
   365
        tstr = WIN_UTF8ToString(output);
slouken@8582
   366
        
slouken@8582
   367
        /* Output to debugger */
slouken@8582
   368
        OutputDebugString(tstr);
slouken@8582
   369
       
slouken@10412
   370
#if !defined(HAVE_STDIO_H) && !defined(__WINRT__)
slouken@8582
   371
        /* Screen output to stderr, if console was attached. */
slouken@8582
   372
        if (consoleAttached == 1) {
slouken@8582
   373
                if (!WriteConsole(stderrHandle, tstr, lstrlen(tstr), &charsWritten, NULL)) {
slouken@8582
   374
                    OutputDebugString(TEXT("Error calling WriteConsole\r\n"));
philipp@9805
   375
                    if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY) {
philipp@9805
   376
                        OutputDebugString(TEXT("Insufficient heap memory to write message\r\n"));
philipp@9805
   377
                    }
slouken@8582
   378
                }
slouken@8582
   379
        }
slouken@10412
   380
#endif /* !defined(HAVE_STDIO_H) && !defined(__WINRT__) */
slouken@8582
   381
slouken@8582
   382
        SDL_free(tstr);
slouken@8582
   383
        SDL_stack_free(output);
slouken@8582
   384
    }
slouken@8582
   385
#elif defined(__ANDROID__)
slouken@8582
   386
    {
slouken@8582
   387
        char tag[32];
slouken@8582
   388
slouken@8582
   389
        SDL_snprintf(tag, SDL_arraysize(tag), "SDL/%s", GetCategoryPrefix(category));
slouken@8582
   390
        __android_log_write(SDL_android_priority[priority], tag, message);
slouken@8582
   391
    }
slouken@8582
   392
#elif defined(__APPLE__) && defined(SDL_VIDEO_DRIVER_COCOA)
slouken@8582
   393
    /* Technically we don't need SDL_VIDEO_DRIVER_COCOA, but that's where this function is defined for now.
slouken@8582
   394
    */
slouken@8582
   395
    extern void SDL_NSLog(const char *text);
slouken@8582
   396
    {
slouken@8582
   397
        char *text;
slouken@8582
   398
slouken@8582
   399
        text = SDL_stack_alloc(char, SDL_MAX_LOG_MESSAGE);
slouken@8582
   400
        if (text) {
slouken@8582
   401
            SDL_snprintf(text, SDL_MAX_LOG_MESSAGE, "%s: %s", SDL_priority_prefixes[priority], message);
slouken@8582
   402
            SDL_NSLog(text);
slouken@8582
   403
            SDL_stack_free(text);
slouken@8582
   404
            return;
slouken@8582
   405
        }
slouken@8582
   406
    }
slouken@8582
   407
#elif defined(__PSP__)
slouken@8582
   408
    {
slouken@8582
   409
        FILE*        pFile;
slouken@8582
   410
        pFile = fopen ("SDL_Log.txt", "a");
slouken@8582
   411
        fprintf(pFile, "%s: %s\n", SDL_priority_prefixes[priority], message);
slouken@8582
   412
        fclose (pFile);
slouken@8582
   413
    }
slouken@8582
   414
#endif
slouken@8582
   415
#if HAVE_STDIO_H
slouken@8582
   416
    fprintf(stderr, "%s: %s\n", SDL_priority_prefixes[priority], message);
gabomdq@8833
   417
#if __NACL__
gabomdq@8833
   418
    fflush(stderr);
gabomdq@8833
   419
#endif
slouken@8582
   420
#endif
slouken@8582
   421
}
slouken@8582
   422
slouken@8582
   423
void
slouken@8582
   424
SDL_LogGetOutputFunction(SDL_LogOutputFunction *callback, void **userdata)
slouken@8582
   425
{
slouken@8582
   426
    if (callback) {
slouken@8582
   427
        *callback = SDL_log_function;
slouken@8582
   428
    }
slouken@8582
   429
    if (userdata) {
slouken@8582
   430
        *userdata = SDL_log_userdata;
slouken@8582
   431
    }
slouken@8582
   432
}
slouken@8582
   433
slouken@8582
   434
void
slouken@8582
   435
SDL_LogSetOutputFunction(SDL_LogOutputFunction callback, void *userdata)
slouken@8582
   436
{
slouken@8582
   437
    SDL_log_function = callback;
slouken@8582
   438
    SDL_log_userdata = userdata;
slouken@8582
   439
}
slouken@8582
   440
slouken@8582
   441
/* vi: set ts=4 sw=4 expandtab: */