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;
+   }
 }


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/