Re: [AD] Windows unicode filename support |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
On Saturday 06 May 2006 17:08, Evert Glebbeek wrote:
> In particular, the patch I commited, which is the one attached to the
> original message, breaks Windows '9x and ME, right? So that one has to be
> reverted, but which of the other ones do I apply?
Yes and no. Here's my older patch fixed up to apply cleanly to the current
SNV. It does a check and calls the regular ansi file functions with ASCII
data on old Windows versions (Win9x), which makes it behave just like it did
before. WinNT/2k/XP use the _w* functions with UTF-16 data, which allows them
to use extended chars. So it basically reverts the behavior back to how it
was, and provides WinNT-based systems the ability to use extended character
filenames.
This still doesn't fix the open/unlink issue though, which will probably need
another method since they don't work for Unix users with non-UTF-8 locales
either.
Index: src/win/wfile.c
===================================================================
--- src/win/wfile.c (revision 5814)
+++ src/win/wfile.c (working copy)
@@ -30,7 +30,12 @@
#endif
+#define IS_OLD_WINDOWS (os_type==OSTYPE_WIN3 || os_type==OSTYPE_WIN95 || \
+ os_type==OSTYPE_WIN98 || os_type==OSTYPE_WINME || \
+ os_type==OSTYPE_UNKNOWN)
+
+
/* _al_file_isok:
* Helper function to check if it is safe to access a file on a floppy
* drive. This really only applies to the DOS library, so we don't bother
@@ -51,11 +56,19 @@
struct _stat s;
char tmp[1024];
- if (_wstat((wchar_t*)uconvert(filename, U_CURRENT, tmp, U_UNICODE,
- sizeof(tmp)), &s) != 0) {
- *allegro_errno = errno;
- return 0;
+ if (IS_OLD_WINDOWS) {
+ if (_stat(uconvert(filename, U_CURRENT, tmp, U_ASCII, sizeof(tmp)), &s) != 0) {
+ *allegro_errno = errno;
+ return 0;
+ }
}
+ else {
+ if (_wstat((wchar_t*)uconvert(filename, U_CURRENT, tmp, U_UNICODE,
+ sizeof(tmp)), &s) != 0) {
+ *allegro_errno = errno;
+ return 0;
+ }
+ }
return s.st_size;
}
@@ -70,11 +83,18 @@
struct _stat s;
char tmp[1024];
- if (_wstat((wchar_t*)uconvert(filename, U_CURRENT, tmp, U_UNICODE,
- sizeof(tmp)), &s) != 0) {
- *allegro_errno = errno;
- return 0;
+ if (IS_OLD_WINDOWS) {
+ if (_stat(uconvert(filename, U_CURRENT, tmp, U_ASCII, sizeof(tmp)), &s) != 0) {
+ *allegro_errno = errno;
+ return 0;
+ }
}
+ else {
+ if (_wstat((wchar_t*)uconvert(filename, U_CURRENT, tmp, U_UNICODE, sizeof(tmp)), &s) != 0) {
+ *allegro_errno = errno;
+ return 0;
+ }
+ }
return s.st_mtime;
}
@@ -84,7 +104,10 @@
/* structure for use by the directory scanning routines */
struct FF_DATA
{
- struct _wfinddata_t data;
+ union {
+ struct _finddata_t a;
+ struct _wfinddata_t w;
+ } data;
long handle;
int attrib;
};
@@ -98,12 +121,22 @@
{
struct FF_DATA *ff_data = (struct FF_DATA *) info->ff_data;
- info->attrib = ff_data->data.attrib;
- info->time = ff_data->data.time_write;
- info->size = ff_data->data.size;
+ if (IS_OLD_WINDOWS) {
+ info->attrib = ff_data->data.a.attrib;
+ info->time = ff_data->data.a.time_write;
+ info->size = ff_data->data.a.size;
- do_uconvert((const char*)ff_data->data.name, U_UNICODE, info->name, U_CURRENT,
- sizeof(info->name));
+ do_uconvert(ff_data->data.a.name, U_ASCII, info->name, U_CURRENT,
+ sizeof(info->name));
+ }
+ else {
+ info->attrib = ff_data->data.w.attrib;
+ info->time = ff_data->data.w.time_write;
+ info->size = ff_data->data.w.size;
+
+ do_uconvert((const char*)ff_data->data.w.name, U_UNICODE, info->name,
+ U_CURRENT, sizeof(info->name));
+ }
}
@@ -144,23 +177,47 @@
/* start the search */
errno = *allegro_errno = 0;
- ff_data->handle = _wfindfirst((wchar_t*)uconvert(pattern, U_CURRENT, tmp,
- U_UNICODE, sizeof(tmp)), &ff_data->data);
+ if (IS_OLD_WINDOWS) {
+ ff_data->handle = _findfirst(uconvert(pattern, U_CURRENT, tmp,
+ U_ASCII, sizeof(tmp)),
+ &ff_data->data.a);
- if (ff_data->handle < 0) {
- *allegro_errno = errno;
- _AL_FREE(ff_data);
- info->ff_data = NULL;
- return -1;
+ if (ff_data->handle < 0) {
+ *allegro_errno = errno;
+ _AL_FREE(ff_data);
+ info->ff_data = NULL;
+ return -1;
+ }
+
+ if (ff_data->data.a.attrib & ~ff_data->attrib) {
+ if (al_findnext(info) != 0) {
+ al_findclose(info);
+ return -1;
+ }
+ else
+ return 0;
+ }
}
+ else {
+ ff_data->handle = _wfindfirst((wchar_t*)uconvert(pattern, U_CURRENT, tmp,
+ U_UNICODE, sizeof(tmp)),
+ &ff_data->data.w);
- if (ff_data->data.attrib & ~ff_data->attrib) {
- if (al_findnext(info) != 0) {
- al_findclose(info);
+ if (ff_data->handle < 0) {
+ *allegro_errno = errno;
+ _AL_FREE(ff_data);
+ info->ff_data = NULL;
return -1;
}
- else
- return 0;
+
+ if (ff_data->data.w.attrib & ~ff_data->attrib) {
+ if (al_findnext(info) != 0) {
+ al_findclose(info);
+ return -1;
+ }
+ else
+ return 0;
+ }
}
fill_ffblk(info);
@@ -176,14 +233,23 @@
{
struct FF_DATA *ff_data = (struct FF_DATA *) info->ff_data;
- do {
- if (_wfindnext(ff_data->handle, &ff_data->data) != 0) {
- *allegro_errno = errno;
- return -1;
- }
+ if (IS_OLD_WINDOWS) {
+ do {
+ if (_findnext(ff_data->handle, &ff_data->data.a) != 0) {
+ *allegro_errno = errno;
+ return -1;
+ }
+ } while (ff_data->data.a.attrib & ~ff_data->attrib);
+ }
+ else {
+ do {
+ if (_wfindnext(ff_data->handle, &ff_data->data.w) != 0) {
+ *allegro_errno = errno;
+ return -1;
+ }
+ } while (ff_data->data.w.attrib & ~ff_data->attrib);
+ }
- } while (ff_data->data.attrib & ~ff_data->attrib);
-
fill_ffblk(info);
return 0;
}
@@ -233,10 +299,18 @@
{
wchar_t tmp[1024];
- if (_wgetdcwd(drive+1, tmp, sizeof(tmp)/sizeof(tmp[0])))
- do_uconvert((const char*)tmp, U_UNICODE, buf, U_CURRENT, size);
- else
- usetc(buf, 0);
+ if (IS_OLD_WINDOWS) {
+ if (_getdcwd(drive+1, tmp, sizeof(tmp)))
+ do_uconvert(tmp, U_ASCII, buf, U_CURRENT, size);
+ else
+ usetc(buf, 0);
+ }
+ else {
+ if (_wgetdcwd(drive+1, (wchar_t*)tmp, sizeof(tmp)/sizeof(wchar_t*)))
+ do_uconvert(tmp, U_UNICODE, buf, U_CURRENT, size);
+ else
+ usetc(buf, 0);
+ }
}
@@ -245,8 +319,15 @@
*/
uint64_t al_ffblk_get_size(struct al_ffblk *info)
{
+ struct FF_DATA *ff_data;
+
ASSERT(info);
- struct FF_DATA *ff_data = (struct FF_DATA *) info->ff_data;
+ ff_data = (struct FF_DATA *) info->ff_data;
- return ff_data->data.size;
+ if (IS_OLD_WINDOWS) {
+ return ff_data->data.a.size;
+ }
+ else {
+ return ff_data->data.w.size;
+ }
}