test/testnativew32.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 28 Nov 2014 04:51:33 -0800
changeset 9246 a761913e5e91
parent 8149 681eb46b8ac4
child 9619 b94b6d0bff0f
permissions -rw-r--r--
Fixed bug 2786 - "UCS-2-INTERNAL" iconv encoding is not supported everywhere, use UTF-16LE instead

Jonas Kulla

src/main/windows/SDL_windows_main.c:137:
cmdline = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char *)(text), (SDL_wcslen(text)+1)*sizeof(WCHAR));

I'm trying to compile an SDL2 application for windows using the mingw-w64 32bit toolchain provided by my distro (Fedora 19). However, even the simplest test program that does nothing at all fails to startup with a "Fatal error - out of memory" message because the mingw iconv library provided by my distro does not support the "UCS-2-INTERNAL" encoding and the conversion returns null.

From my little bit of research, it turns out that even though this encoding is supported by the external GNU libiconv library, some glibc versions (?) don't support it with their internal iconv routines, and will instead provide the native endian encoding when "UCS-2" is specified.

Nonetheless, I wonder why the native endianness is considered in the first place when Windows doesn't even run on any big endian archs (to my knowledge). And true enough, 'WIN_StringToUTF8' from core/windows/SDL_windows.h is used everywhere else in the windows backend, which is just a macro to iconv with "UTF-16LE" as source. Therefore it would IMO make sense to use this macro here as well, which would solve my problem (patch attached).
slouken@5535
     1
/*
slouken@8149
     2
  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     3
slouken@5535
     4
  This software is provided 'as-is', without any express or implied
slouken@5535
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     6
  arising from the use of this software.
slouken@5535
     7
slouken@5535
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
     9
  including commercial applications, and to alter it and redistribute it
slouken@5535
    10
  freely.
slouken@5535
    11
*/
slouken@3057
    12
slouken@3057
    13
#include "testnative.h"
slouken@3057
    14
slouken@5062
    15
#ifdef TEST_NATIVE_WINDOWS
slouken@3057
    16
slouken@5062
    17
static void *CreateWindowNative(int w, int h);
slouken@5062
    18
static void DestroyWindowNative(void *window);
slouken@3057
    19
slouken@5062
    20
NativeWindowFactory WindowsWindowFactory = {
slouken@5062
    21
    "windows",
slouken@5062
    22
    CreateWindowNative,
slouken@5062
    23
    DestroyWindowNative
slouken@3057
    24
};
slouken@3057
    25
slouken@3071
    26
LRESULT CALLBACK
slouken@3071
    27
WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
slouken@3060
    28
{
slouken@3071
    29
    switch (msg) {
slouken@3071
    30
    case WM_CLOSE:
slouken@3071
    31
        DestroyWindow(hwnd);
slouken@3060
    32
        break;
slouken@3071
    33
    case WM_DESTROY:
slouken@3071
    34
        PostQuitMessage(0);
slouken@3060
    35
        break;
slouken@3071
    36
    default:
slouken@3071
    37
        return DefWindowProc(hwnd, msg, wParam, lParam);
slouken@3060
    38
    }
slouken@3060
    39
    return 0;
slouken@3060
    40
}
slouken@3057
    41
slouken@3057
    42
static void *
slouken@5062
    43
CreateWindowNative(int w, int h)
slouken@3057
    44
{
slouken@3060
    45
    HWND hwnd;
slouken@3060
    46
    WNDCLASS wc;
slouken@3060
    47
slouken@3071
    48
    wc.style = 0;
slouken@3071
    49
    wc.lpfnWndProc = WndProc;
slouken@3071
    50
    wc.cbClsExtra = 0;
slouken@3071
    51
    wc.cbWndExtra = 0;
slouken@3071
    52
    wc.hInstance = GetModuleHandle(NULL);
slouken@3071
    53
    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
slouken@3071
    54
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
slouken@3071
    55
    wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
slouken@3071
    56
    wc.lpszMenuName = NULL;
slouken@3060
    57
    wc.lpszClassName = "SDL Test";
slouken@3060
    58
slouken@3071
    59
    if (!RegisterClass(&wc)) {
slouken@3060
    60
        MessageBox(NULL, "Window Registration Failed!", "Error!",
slouken@3071
    61
                   MB_ICONEXCLAMATION | MB_OK);
slouken@3060
    62
        return 0;
slouken@3060
    63
    }
slouken@3060
    64
slouken@3071
    65
    hwnd =
slouken@3071
    66
        CreateWindow("SDL Test", "", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
slouken@3071
    67
                     CW_USEDEFAULT, w, h, NULL, NULL, GetModuleHandle(NULL),
slouken@3071
    68
                     NULL);
slouken@3071
    69
    if (hwnd == NULL) {
slouken@3060
    70
        MessageBox(NULL, "Window Creation Failed!", "Error!",
slouken@3071
    71
                   MB_ICONEXCLAMATION | MB_OK);
slouken@3060
    72
        return 0;
slouken@3060
    73
    }
slouken@3060
    74
slouken@3060
    75
    ShowWindow(hwnd, SW_SHOW);
slouken@3060
    76
slouken@3060
    77
    return hwnd;
slouken@3057
    78
}
slouken@3057
    79
slouken@3057
    80
static void
slouken@5062
    81
DestroyWindowNative(void *window)
slouken@3057
    82
{
slouken@3071
    83
    DestroyWindow((HWND) window);
slouken@3057
    84
}
slouken@3057
    85
slouken@3057
    86
#endif