build fixes for MSVC, start moving back to TCHAR usage so we can switch unicode on and off

This commit is contained in:
Brad Parker 2016-12-02 12:15:38 -05:00
parent f77f3ecec4
commit 0a0cc6494a
11 changed files with 1797 additions and 868 deletions

View File

@ -1,7 +1,7 @@
/* RetroArch - A frontend for libretro. /* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2016 - Daniel De Matteis * Copyright (C) 2011-2016 - Daniel De Matteis
* *
* RetroArch is free software: you can redistribute it and/or modify it under the terms * RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found- * of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version. * ation, either version 3 of the License, or (at your option) any later version.
@ -19,6 +19,8 @@
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include <encodings/win32.h>
#ifndef _XBOX #ifndef _XBOX
#include <windows.h> #include <windows.h>
#include <mmreg.h> #include <mmreg.h>
@ -93,7 +95,7 @@ static INLINE bool grab_region(dsound_t *ds, uint32_t write_ptr,
struct audio_lock *region) struct audio_lock *region)
{ {
const char *err = NULL; const char *err = NULL;
HRESULT res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, HRESULT res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE,
&region->chunk1, &region->size1, &region->chunk2, &region->size2, 0); &region->chunk1, &region->size1, &region->chunk2, &region->size2, 0);
if (res == DSERR_BUFFERLOST) if (res == DSERR_BUFFERLOST)
@ -152,7 +154,7 @@ static void dsound_thread(void *data)
struct audio_lock region; struct audio_lock region;
DWORD read_ptr, avail, fifo_avail; DWORD read_ptr, avail, fifo_avail;
get_positions(ds, &read_ptr, NULL); get_positions(ds, &read_ptr, NULL);
avail = write_avail(read_ptr, write_ptr, ds->buffer_size); avail = write_avail(read_ptr, write_ptr, ds->buffer_size);
EnterCriticalSection(&ds->crit); EnterCriticalSection(&ds->crit);
@ -161,12 +163,12 @@ static void dsound_thread(void *data)
if (avail < CHUNK_SIZE || ((fifo_avail < CHUNK_SIZE) && (avail < ds->buffer_size / 2))) if (avail < CHUNK_SIZE || ((fifo_avail < CHUNK_SIZE) && (avail < ds->buffer_size / 2)))
{ {
/* No space to write, or we don't have data in our fifo, /* No space to write, or we don't have data in our fifo,
* but we can wait some time before it underruns ... */ * but we can wait some time before it underruns ... */
/* We could opt for using the notification interface, /* We could opt for using the notification interface,
* but it is not guaranteed to work, so use high * but it is not guaranteed to work, so use high
* priority sleeping patterns. * priority sleeping patterns.
*/ */
retro_sleep(1); retro_sleep(1);
@ -182,7 +184,7 @@ static void dsound_thread(void *data)
if (fifo_avail < CHUNK_SIZE) if (fifo_avail < CHUNK_SIZE)
{ {
/* Got space to write, but nothing in FIFO (underrun), /* Got space to write, but nothing in FIFO (underrun),
* fill block with silence. */ * fill block with silence. */
memset(region.chunk1, 0, region.size1); memset(region.chunk1, 0, region.size1);
@ -191,7 +193,7 @@ static void dsound_thread(void *data)
release_region(ds, &region); release_region(ds, &region);
write_ptr = (write_ptr + region.size1 + region.size2) % ds->buffer_size; write_ptr = (write_ptr + region.size1 + region.size2) % ds->buffer_size;
} }
else else
{ {
/* All is good. Pull from it and notify FIFO. */ /* All is good. Pull from it and notify FIFO. */
@ -291,11 +293,15 @@ struct dsound_dev
LPGUID guid; LPGUID guid;
}; };
static BOOL CALLBACK enumerate_cb(LPGUID guid, LPCSTR desc, LPCSTR module, LPVOID context) static BOOL CALLBACK enumerate_cb(LPGUID guid, LPCTSTR desc, LPCTSTR module, LPVOID context)
{ {
struct dsound_dev *dev = (struct dsound_dev*)context; struct dsound_dev *dev = (struct dsound_dev*)context;
WCHAR_TO_CHAR_ALLOC(desc, desc_str)
RARCH_LOG("\t%u: %s\n", dev->total_count, desc); RARCH_LOG("\t%u: %s\n", dev->total_count, desc_str);
if (desc_str)
free(desc_str);
if (dev->device == dev->total_count) if (dev->device == dev->total_count)
dev->guid = guid; dev->guid = guid;

View File

@ -48,7 +48,7 @@
#include "../../configuration.h" #include "../../configuration.h"
#include "../../verbosity.h" #include "../../verbosity.h"
#include "../tasks/tasks_internal.h" #include "../../tasks/tasks_internal.h"
#include "../input_config.h" #include "../input_config.h"
#include "../input_joypad_driver.h" #include "../input_joypad_driver.h"
#include "../input_keymaps.h" #include "../input_keymaps.h"

View File

@ -1,7 +1,7 @@
/* RetroArch - A frontend for libretro. /* RetroArch - A frontend for libretro.
* Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2010-2014 - Hans-Kristian Arntzen
* Copyright (C) 2011-2016 - Daniel De Matteis * Copyright (C) 2011-2016 - Daniel De Matteis
* *
* RetroArch is free software: you can redistribute it and/or modify it under the terms * RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found- * of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version. * ation, either version 3 of the License, or (at your option) any later version.
@ -17,6 +17,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include <encodings/win32.h>
#include <windowsx.h> #include <windowsx.h>
#include <dinput.h> #include <dinput.h>
@ -76,7 +77,7 @@ static void dinput_joypad_destroy(void)
IDirectInputDevice8_Unacquire(g_pads[i].joypad); IDirectInputDevice8_Unacquire(g_pads[i].joypad);
IDirectInputDevice8_Release(g_pads[i].joypad); IDirectInputDevice8_Release(g_pads[i].joypad);
} }
free(g_pads[i].joy_name); free(g_pads[i].joy_name);
g_pads[i].joy_name = NULL; g_pads[i].joy_name = NULL;
free(g_pads[i].joy_friendly_name); free(g_pads[i].joy_friendly_name);
@ -115,11 +116,11 @@ static bool guid_is_xinput_device(const GUID* product_guid)
unsigned i, num_raw_devs = 0; unsigned i, num_raw_devs = 0;
PRAWINPUTDEVICELIST raw_devs = NULL; PRAWINPUTDEVICELIST raw_devs = NULL;
/* Check for well known XInput device GUIDs, /* Check for well known XInput device GUIDs,
* thereby removing the need for the IG_ check. * thereby removing the need for the IG_ check.
* This lets us skip RAWINPUT for popular devices. * This lets us skip RAWINPUT for popular devices.
* *
* Also, we need to do this for the Valve Streaming Gamepad * Also, we need to do this for the Valve Streaming Gamepad
* because it's virtualized and doesn't show up in the device list. */ * because it's virtualized and doesn't show up in the device list. */
for (i = 0; i < ARRAY_SIZE(common_xinput_guids); ++i) for (i = 0; i < ARRAY_SIZE(common_xinput_guids); ++i)
@ -208,6 +209,7 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
#endif #endif
LPDIRECTINPUTDEVICE8 *pad = NULL; LPDIRECTINPUTDEVICE8 *pad = NULL;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
WCHAR_TO_CHAR_ALLOC(inst->tszInstanceName, name)
(void)p; (void)p;
@ -223,10 +225,13 @@ static BOOL CALLBACK enum_joypad_cb(const DIDEVICEINSTANCE *inst, void *p)
if (FAILED(IDirectInput8_CreateDevice( if (FAILED(IDirectInput8_CreateDevice(
g_dinput_ctx, &inst->guidInstance, pad, NULL))) g_dinput_ctx, &inst->guidInstance, pad, NULL)))
#endif #endif
return DIENUM_CONTINUE; return DIENUM_CONTINUE;
g_pads[g_joypad_cnt].joy_name = strdup(inst->tszProductName); g_pads[g_joypad_cnt].joy_name = strdup(name);
g_pads[g_joypad_cnt].joy_friendly_name = strdup(inst->tszInstanceName); g_pads[g_joypad_cnt].joy_friendly_name = strdup(name);
if (name)
free(name);
/* there may be more useful info in the GUID so leave this here for a while */ /* there may be more useful info in the GUID so leave this here for a while */
#if 0 #if 0

View File

@ -23,6 +23,7 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <dynamic/dylib.h> #include <dynamic/dylib.h>
#include <encodings/win32.h>
#ifdef NEED_DYNAMIC #ifdef NEED_DYNAMIC
@ -34,7 +35,7 @@
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
static char last_dyn_error[512]; static TCHAR last_dyn_error[512];
static void set_dl_error(void) static void set_dl_error(void)
{ {
@ -45,11 +46,16 @@ static void set_dl_error(void)
NULL, NULL,
err, err,
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
last_dyn_error, (LPTSTR)last_dyn_error,
sizeof(last_dyn_error) - 1, sizeof(last_dyn_error) - 1,
NULL) == 0) NULL) == 0)
snprintf(last_dyn_error, sizeof(last_dyn_error) - 1, {
WCHAR_TO_CHAR_ALLOC(last_dyn_error, last_dyn_error_str)
snprintf(last_dyn_error_str, sizeof(last_dyn_error) - 1,
"unknown error %lu", err); "unknown error %lu", err);
if (last_dyn_error_str)
free(last_dyn_error_str);
}
} }
#endif #endif
@ -65,8 +71,12 @@ dylib_t dylib_load(const char *path)
{ {
#ifdef _WIN32 #ifdef _WIN32
int prevmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); int prevmode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
dylib_t lib = LoadLibrary(path); dylib_t lib = NULL;
CHAR_TO_WCHAR_ALLOC(path, path_wide)
lib = LoadLibrary(path_wide);
free(path_wide);
SetErrorMode(prevmode); SetErrorMode(prevmode);
if (!lib) if (!lib)

View File

@ -24,6 +24,7 @@
#include <stdio.h> #include <stdio.h>
#include <retro_common.h> #include <retro_common.h>
#include <encodings/win32.h>
#include <boolean.h> #include <boolean.h>
#include <retro_stat.h> #include <retro_stat.h>
@ -97,7 +98,9 @@ const char *retro_dirent_get_name(struct RDIR *rdir)
{ {
#if defined(_WIN32) #if defined(_WIN32)
memset(rdir->path, 0, sizeof(rdir->path)); memset(rdir->path, 0, sizeof(rdir->path));
utf16_to_char_string(rdir->entry.cFileName, rdir->path, sizeof(rdir->path)); #ifdef UNICODE
utf16_to_char_string((const uint16_t*)rdir->entry.cFileName, rdir->path, sizeof(rdir->path));
#endif
return rdir->path; return rdir->path;
#elif defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__) #elif defined(VITA) || defined(PSP) || defined(__CELLOS_LV2__)
return rdir->entry.d_name; return rdir->entry.d_name;

View File

@ -0,0 +1,53 @@
/* Copyright (C) 2010-2016 The RetroArch team
*
* ---------------------------------------------------------------------------------------
* The following license statement only applies to this file (utf.h).
* ---------------------------------------------------------------------------------------
*
* Permission is hereby granted, free of charge,
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _LIBRETRO_ENCODINGS_WIN32_H
#define _LIBRETRO_ENCODINGS_WIN32_H
#ifndef _XBOX
#ifdef _WIN32
#define UNICODE
#include <tchar.h>
#include <wchar.h>
#include <encodings/utf.h>
#endif
#endif
#ifdef UNICODE
#define CHAR_TO_WCHAR_ALLOC(s, ws) \
size_t ws##_size = (s[0] ? strlen(s) : 0) + 1; \
wchar_t *ws = (wchar_t*)calloc(ws##_size, 2); \
if (s[0]) \
MultiByteToWideChar(CP_UTF8, 0, s, -1, ws, ws##_size / sizeof(wchar_t));
#define WCHAR_TO_CHAR_ALLOC(ws, s) \
size_t s##_size = ((ws[0] ? wcslen((const wchar_t*)ws) : 0) / 2) + 1; \
char *s = (char*)calloc(s##_size, 1); \
if (ws[0]) \
utf16_to_char_string((const uint16_t*)ws, s, s##_size);
#else
#define CHAR_TO_WCHAR_ALLOC(s, ws) char *ws = strdup(s);
#define WCHAR_TO_CHAR_ALLOC(ws, s) char *s = strdup(ws);
#endif
#endif

View File

@ -200,14 +200,12 @@ unsigned menu_event(uint64_t input, uint64_t trigger_input)
size_t new_scroll_accel = 0; size_t new_scroll_accel = 0;
menu_input_t *menu_input = NULL; menu_input_t *menu_input = NULL;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
static bool ok_old = false; static char ok_old = 0;
unsigned menu_ok_btn = settings->input.menu_swap_ok_cancel_buttons ? unsigned menu_ok_btn = settings->input.menu_swap_ok_cancel_buttons ?
RETRO_DEVICE_ID_JOYPAD_B : RETRO_DEVICE_ID_JOYPAD_A; RETRO_DEVICE_ID_JOYPAD_B : RETRO_DEVICE_ID_JOYPAD_A;
unsigned menu_cancel_btn = settings->input.menu_swap_ok_cancel_buttons ? unsigned menu_cancel_btn = settings->input.menu_swap_ok_cancel_buttons ?
RETRO_DEVICE_ID_JOYPAD_A : RETRO_DEVICE_ID_JOYPAD_B; RETRO_DEVICE_ID_JOYPAD_A : RETRO_DEVICE_ID_JOYPAD_B;
bool ok_current = input & UINT64_C(1) << menu_ok_btn; char ok_current = input & UINT64_C(1) << menu_ok_btn;
/* TODO/FIXME - unsafe use of type 'bool' in operation */
bool ok_trigger = ok_current & ~ok_old; bool ok_trigger = ok_current & ~ok_old;
ok_old = ok_current; ok_old = ok_current;

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <encodings/win32.h>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma comment( lib, "comctl32" ) #pragma comment( lib, "comctl32" )
@ -121,7 +122,7 @@ static void shader_dlg_refresh_trackbar_label(int index)
video_shader_driver_get_current_shader(&shader_info); video_shader_driver_get_current_shader(&shader_info);
if (floorf(shader_info.data->parameters[index].current) if (floorf(shader_info.data->parameters[index].current)
== shader_info.data->parameters[index].current) == shader_info.data->parameters[index].current)
snprintf(val_buffer, sizeof(val_buffer), "%.0f", snprintf(val_buffer, sizeof(val_buffer), "%.0f",
shader_info.data->parameters[index].current); shader_info.data->parameters[index].current);
@ -152,8 +153,8 @@ static void shader_dlg_params_refresh(void)
{ {
case SHADER_PARAM_CTRL_CHECKBOX: case SHADER_PARAM_CTRL_CHECKBOX:
{ {
bool checked = bool checked =
(shader_info.data->parameters[i].current == (shader_info.data->parameters[i].current ==
shader_info.data->parameters[i].maximum); shader_info.data->parameters[i].maximum);
SendMessageW(control->checkbox.hwnd, BM_SETCHECK, checked, 0); SendMessageW(control->checkbox.hwnd, BM_SETCHECK, checked, 0);
} }
@ -165,12 +166,12 @@ static void shader_dlg_params_refresh(void)
TBM_SETRANGEMIN, (WPARAM)TRUE, (LPARAM)0); TBM_SETRANGEMIN, (WPARAM)TRUE, (LPARAM)0);
SendMessageW(control->trackbar.hwnd, SendMessageW(control->trackbar.hwnd,
TBM_SETRANGEMAX, (WPARAM)TRUE, TBM_SETRANGEMAX, (WPARAM)TRUE,
(LPARAM)((shader_info.data->parameters[i].maximum - (LPARAM)((shader_info.data->parameters[i].maximum -
shader_info.data->parameters[i].minimum) shader_info.data->parameters[i].minimum)
/ shader_info.data->parameters[i].step)); / shader_info.data->parameters[i].step));
SendMessageW(control->trackbar.hwnd, TBM_SETPOS, (WPARAM)TRUE, SendMessageW(control->trackbar.hwnd, TBM_SETPOS, (WPARAM)TRUE,
(LPARAM)((shader_info.data->parameters[i].current - (LPARAM)((shader_info.data->parameters[i].current -
shader_info.data->parameters[i].minimum) / shader_info.data->parameters[i].minimum) /
shader_info.data->parameters[i].step)); shader_info.data->parameters[i].step));
break; break;
case SHADER_PARAM_CTRL_NONE: case SHADER_PARAM_CTRL_NONE:
@ -233,21 +234,16 @@ void shader_dlg_params_reload(void)
for (i = 0; i < (int)shader_info.data->num_parameters; i++) for (i = 0; i < (int)shader_info.data->num_parameters; i++)
{ {
shader_param_ctrl_t*control = &g_shader_dlg.controls[i]; shader_param_ctrl_t *control = &g_shader_dlg.controls[i];
size_t param_desc_wide_size = sizeof(shader_info.data->parameters[i].desc) * 2; CHAR_TO_WCHAR_ALLOC(shader_info.data->parameters[i].desc, param_desc_wide)
wchar_t param_desc_wide[param_desc_wide_size];
memset(param_desc_wide, 0, sizeof(param_desc_wide));
MultiByteToWideChar(CP_UTF8, 0, shader_info.data->parameters[i].desc, -1, param_desc_wide, sizeof(param_desc_wide) / sizeof(param_desc_wide[0]));
if ((shader_info.data->parameters[i].minimum == 0.0) if ((shader_info.data->parameters[i].minimum == 0.0)
&& (shader_info.data->parameters[i].maximum && (shader_info.data->parameters[i].maximum
== (shader_info.data->parameters[i].minimum == (shader_info.data->parameters[i].minimum
+ shader_info.data->parameters[i].step))) + shader_info.data->parameters[i].step)))
{ {
if ((pos_y + SHADER_DLG_CHECKBOX_HEIGHT if ((pos_y + SHADER_DLG_CHECKBOX_HEIGHT
+ SHADER_DLG_CTRL_MARGIN + 20) + SHADER_DLG_CTRL_MARGIN + 20)
> SHADER_DLG_MAX_HEIGHT) > SHADER_DLG_MAX_HEIGHT)
{ {
pos_y = g_shader_dlg.parameters_start_y; pos_y = g_shader_dlg.parameters_start_y;
@ -300,6 +296,8 @@ void shader_dlg_params_reload(void)
} }
if (param_desc_wide)
free(param_desc_wide);
} }
if (window && g_shader_dlg.separator.hwnd) if (window && g_shader_dlg.separator.hwnd)
@ -328,7 +326,7 @@ static void shader_dlg_update_on_top_state(void)
bool on_top = SendMessage(g_shader_dlg.on_top_checkbox.hwnd, bool on_top = SendMessage(g_shader_dlg.on_top_checkbox.hwnd,
BM_GETCHECK, 0, 0) == BST_CHECKED; BM_GETCHECK, 0, 0) == BST_CHECKED;
SetWindowPos(g_shader_dlg.window.hwnd, on_top SetWindowPos(g_shader_dlg.window.hwnd, on_top
? HWND_TOPMOST : HWND_NOTOPMOST , 0, 0, 0, 0, ? HWND_TOPMOST : HWND_NOTOPMOST , 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
} }
@ -397,10 +395,10 @@ static LRESULT CALLBACK ShaderDlgWndProc(HWND hwnd, UINT message,
if (SendMessageW(g_shader_dlg.controls[i].checkbox.hwnd, if (SendMessageW(g_shader_dlg.controls[i].checkbox.hwnd,
BM_GETCHECK, 0, 0) == BST_CHECKED) BM_GETCHECK, 0, 0) == BST_CHECKED)
shader_info.data->parameters[i].current = shader_info.data->parameters[i].current =
shader_info.data->parameters[i].maximum; shader_info.data->parameters[i].maximum;
else else
shader_info.data->parameters[i].current = shader_info.data->parameters[i].current =
shader_info.data->parameters[i].minimum; shader_info.data->parameters[i].minimum;
break; break;
@ -415,7 +413,7 @@ static LRESULT CALLBACK ShaderDlgWndProc(HWND hwnd, UINT message,
break; break;
pos = (int)SendMessageW(g_shader_dlg.controls[i].trackbar.hwnd, TBM_GETPOS, 0, 0); pos = (int)SendMessageW(g_shader_dlg.controls[i].trackbar.hwnd, TBM_GETPOS, 0, 0);
shader_info.data->parameters[i].current = shader_info.data->parameters[i].current =
shader_info.data->parameters[i].minimum + pos * shader_info.data->parameters[i].step; shader_info.data->parameters[i].minimum + pos * shader_info.data->parameters[i].step;
shader_dlg_refresh_trackbar_label(i); shader_dlg_refresh_trackbar_label(i);
@ -451,10 +449,10 @@ bool win32_window_init(WNDCLASSEX *wndclass,
if (!RegisterClassExW(wndclass)) if (!RegisterClassExW(wndclass))
return false; return false;
/* This is non-NULL when we want a window for shader dialogs, /* This is non-NULL when we want a window for shader dialogs,
* therefore early return here */ * therefore early return here */
/* TODO/FIXME - this is ugly. Find a better way */ /* TODO/FIXME - this is ugly. Find a better way */
if (class_name != NULL) if (class_name != NULL)
return true; return true;
if (!win32_shader_dlg_init()) if (!win32_shader_dlg_init())
@ -523,7 +521,7 @@ static bool win32_browser(
const char *initial_dir) const char *initial_dir)
{ {
bool result = false; bool result = false;
const ui_browser_window_t *browser = const ui_browser_window_t *browser =
ui_companion_driver_get_browser_window_ptr(); ui_companion_driver_get_browser_window_ptr();
if (browser) if (browser)
@ -534,14 +532,17 @@ static bool win32_browser(
browser_state.title = strdup(title); browser_state.title = strdup(title);
browser_state.startdir = strdup(initial_dir); browser_state.startdir = strdup(initial_dir);
browser_state.path = strdup(filename); browser_state.path = strdup(filename);
browser_state.window = owner;
result = browser->open(&browser_state); result = browser->open(&browser_state);
free(browser_state.filters); if (browser_state.filters)
free(browser_state.title); free(browser_state.filters);
free(browser_state.startdir); if (browser_state.title)
free(browser_state.path); free(browser_state.title);
if (browser_state.startdir)
free(browser_state.startdir);
if (browser_state.path)
free(browser_state.path);
} }
return result; return result;
@ -554,7 +555,7 @@ LRESULT win32_menu_loop(HWND owner, WPARAM wparam)
bool do_wm_close = false; bool do_wm_close = false;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
switch (mode) switch (mode)
{ {
case ID_M_LOAD_CORE: case ID_M_LOAD_CORE:
case ID_M_LOAD_CONTENT: case ID_M_LOAD_CONTENT:
@ -663,7 +664,7 @@ LRESULT win32_menu_loop(HWND owner, WPARAM wparam)
signed idx = -1; signed idx = -1;
settings->state_slot = idx; settings->state_slot = idx;
} }
else if (mode >= (ID_M_STATE_INDEX_AUTO+1) else if (mode >= (ID_M_STATE_INDEX_AUTO+1)
&& mode <= (ID_M_STATE_INDEX_AUTO+10)) && mode <= (ID_M_STATE_INDEX_AUTO+10))
{ {
signed idx = (mode - (ID_M_STATE_INDEX_AUTO+1)); signed idx = (mode - (ID_M_STATE_INDEX_AUTO+1));
@ -677,7 +678,7 @@ LRESULT win32_menu_loop(HWND owner, WPARAM wparam)
if (do_wm_close) if (do_wm_close)
PostMessageW(owner, WM_CLOSE, 0, 0); PostMessageW(owner, WM_CLOSE, 0, 0);
return 0L; return 0L;
} }

View File

@ -18,6 +18,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <encodings/win32.h>
#include <windows.h> #include <windows.h>
@ -26,23 +27,60 @@
static bool ui_browser_window_win32_core(ui_browser_window_state_t *state, bool save) static bool ui_browser_window_win32_core(ui_browser_window_state_t *state, bool save)
{ {
OPENFILENAME ofn = {}; OPENFILENAME ofn = {};
bool success = true;
#ifdef UNICODE
size_t filters_size = (state->filters ? strlen(state->filters) : 0) + 1;
size_t path_size = strlen(state->path) + 1;
size_t title_size = strlen(state->title) + 1;
size_t startdir_size = strlen(state->startdir) + 1;
ofn.lStructSize = sizeof(OPENFILENAME); wchar_t *filters_wide = (wchar_t*)calloc(filters_size, 2);
ofn.hwndOwner = (HWND)state->window; wchar_t *path_wide = (wchar_t*)calloc(path_size, 2);
wchar_t *title_wide = (wchar_t*)calloc(title_size, 2);
wchar_t *startdir_wide = (wchar_t*)calloc(startdir_size, 2);
if (state->filters)
MultiByteToWideChar(CP_UTF8, 0, state->filters, -1, filters_wide, filters_size);
if (state->title)
MultiByteToWideChar(CP_UTF8, 0, state->title, -1, title_wide, title_size);
if (state->path)
MultiByteToWideChar(CP_UTF8, 0, state->path, -1, path_wide, path_size);
if (state->startdir)
MultiByteToWideChar(CP_UTF8, 0, state->startdir, -1, startdir_wide, startdir_size);
ofn.lpstrFilter = filters_wide;
ofn.lpstrFile = path_wide;
ofn.lpstrTitle = title_wide;
ofn.lpstrInitialDir = startdir_wide;
#else
ofn.lpstrFilter = state->filters; ofn.lpstrFilter = state->filters;
ofn.lpstrFile = state->path; ofn.lpstrFile = state->path;
ofn.lpstrTitle = state->title; ofn.lpstrTitle = state->title;
ofn.lpstrInitialDir = state->startdir; ofn.lpstrInitialDir = state->startdir;
ofn.lpstrDefExt = ""; #endif
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = (HWND)state->window;
ofn.lpstrDefExt = TEXT("");
ofn.nMaxFile = PATH_MAX; ofn.nMaxFile = PATH_MAX;
ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR; ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY | OFN_NOCHANGEDIR;
if ( save && !GetOpenFileName(&ofn)) if ( save && !GetOpenFileName(&ofn))
return false; success = false;
if (!save && !GetSaveFileName(&ofn)) if (!save && !GetSaveFileName(&ofn))
return false; success = false;
return true; #ifdef UNICODE
if (filters_wide)
free(filters_wide);
if (title_wide)
free(title_wide);
if (path_wide)
free(path_wide);
if (startdir_wide)
free(startdir_wide);
#endif
return success;
} }
static bool ui_browser_window_win32_open(ui_browser_window_state_t *state) static bool ui_browser_window_win32_open(ui_browser_window_state_t *state)

View File

@ -20,6 +20,8 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <encodings/win32.h>
#include <windows.h> #include <windows.h>
#ifdef _MSC_VER #ifdef _MSC_VER
@ -62,7 +64,7 @@ static void ui_window_win32_set_focused(void *data)
SetFocus(window->hwnd); SetFocus(window->hwnd);
} }
static void ui_window_win32_set_visible(void *data, static void ui_window_win32_set_visible(void *data,
bool set_visible) bool set_visible)
{ {
ui_window_win32_t *window = (ui_window_win32_t*)data; ui_window_win32_t *window = (ui_window_win32_t*)data;
@ -72,7 +74,10 @@ static void ui_window_win32_set_visible(void *data,
static void ui_window_win32_set_title(void *data, char *buf) static void ui_window_win32_set_title(void *data, char *buf)
{ {
ui_window_win32_t *window = (ui_window_win32_t*)data; ui_window_win32_t *window = (ui_window_win32_t*)data;
SetWindowText(window->hwnd, buf); CHAR_TO_WCHAR_ALLOC(buf, buf_wide)
SetWindowText(window->hwnd, buf_wide);
if (buf_wide)
free(buf_wide);
} }
void ui_window_win32_set_droppable(void *data, bool droppable) void ui_window_win32_set_droppable(void *data, bool droppable)