allow Windows build to live in a path that includes non-ASCII characters

svn: r2907
This commit is contained in:
Matthew Flatt 2006-05-11 18:08:27 +00:00
parent 0416367a7f
commit fd9266eb79
24 changed files with 369 additions and 441 deletions

View File

@ -1,19 +1,21 @@
(module windlldir mzscheme (module windlldir mzscheme
(require (lib "port.ss")) (require (lib "port.ss")
"winutf16.ss")
(provide update-dll-dir (provide update-dll-dir
get-current-dll-dir) get-current-dll-dir)
(define label "dLl dIRECTORy:") (define label (byte-regexp (bytes->utf-16-bytes #"dLl dIRECTORy:")))
(define max-dir-len 512) (define max-dir-len (* 512 2)) ; sizeof(wchar_t) is 2
(define (update-dll-dir dest path) (define (update-dll-dir dest path)
(let ([path-bytes (if (eq? path #t) (let ([path-bytes (bytes->utf-16-bytes
#"<system>" (if (eq? path #t)
(if (path? path) #"<system>"
(path->bytes path) (if (path? path)
(string->bytes/locale path)))]) (path->bytes path)
(string->bytes/locale path))))])
(unless ((bytes-length path-bytes) . <= . max-dir-len) (unless ((bytes-length path-bytes) . <= . max-dir-len)
(error 'update-dll-dir "path too long: ~e" path)) (error 'update-dll-dir "path too long: ~e" path))
(let ([m (with-input-from-file dest (let ([m (with-input-from-file dest
@ -27,7 +29,6 @@
(write-bytes path-bytes) (write-bytes path-bytes)
(write-byte 0)) (write-byte 0))
'update)))) 'update))))
(define (get-current-dll-dir dest) (define (get-current-dll-dir dest)
(with-input-from-file dest (with-input-from-file dest
@ -35,5 +36,5 @@
(unless (regexp-match label (current-input-port)) (unless (regexp-match label (current-input-port))
(error 'get-current-dll-dir "cannot find DLL path in file: ~e" dest)) (error 'get-current-dll-dir "cannot find DLL path in file: ~e" dest))
(let ([p (make-limited-input-port (current-input-port) max-dir-len)]) (let ([p (make-limited-input-port (current-input-port) max-dir-len)])
(let ([m (regexp-match #rx#"[^\0]*" p)]) (let ([m (regexp-match #rx#"(?:[^\0].|.[^\0])*" p)])
(bytes->path (car m)))))))) (bytes->path (utf-16-bytes->bytes (car m)))))))))

View File

@ -0,0 +1,36 @@
(module winutf16 mzscheme
(provide bytes->utf-16-bytes
utf-16-bytes->bytes)
;; Convert bytes for a path into a UTF-16 encoding
;; (which can have unpaired surrogates)
(define (bytes->utf-16-bytes b)
(let ([c (bytes-open-converter "platform-UTF-8-permissive" "platform-UTF-16")])
(let-values ([(s n status) (bytes-convert c b)])
(if (eq? status 'complete)
s
;; Must be a trailing unpaired surrogate.
;; Force it to convert by adding an "a" suffix, then
;; strip the "a" back off:
(bytes-append
s
(let-values ([(s n status)
(bytes-convert c (bytes-append (subbytes b n) #"a"))])
(subbytes s 0 (- (bytes-length s) 2))))))))
;; Convert a UTF-16 encoding (which can have unpaired surrogates)
;; into bytes for a path
(define (utf-16-bytes->bytes b)
(let ([c (bytes-open-converter "platform-UTF-16" "platform-UTF-8")])
(let-values ([(s n status) (bytes-convert c b)])
(if (eq? status 'complete)
s
;; Must be a trailing unpaired surrogate.
;; Force it to convert by adding an "a" suffix, then
;; strip the "a" back off:
(bytes-append
s
(let-values ([(s n status)
(bytes-convert c (bytes-append (subbytes b n) #"a\0"))])
(subbytes s 0 (sub1 (bytes-length s))))))))))

View File

@ -10,7 +10,9 @@
(lib "embed.ss" "compiler") (lib "embed.ss" "compiler")
(lib "plthome.ss" "setup") (lib "plthome.ss" "setup")
"launcher-sig.ss") "launcher-sig.ss"
(lib "winutf16.ss" "compiler" "private"))
(provide launcher@) (provide launcher@)
@ -367,6 +369,11 @@
(assemble-exec exec args)) (assemble-exec exec args))
(close-output-port p)))) (close-output-port p))))
(define (utf-16-regexp b)
(byte-regexp (bytes-append (bytes->utf-16-bytes b)
#"[^>]*"
(bytes->utf-16-bytes #">"))))
(define (make-windows-launcher kind variant flags dest aux) (define (make-windows-launcher kind variant flags dest aux)
(if (not (and (let ([m (assq 'independent? aux)]) (if (not (and (let ([m (assq 'independent? aux)])
(and m (cdr m))))) (and m (cdr m)))))
@ -380,20 +387,22 @@
;; Independent launcher (needed for Setup PLT): ;; Independent launcher (needed for Setup PLT):
(begin (begin
(install-template dest kind "mzstart.exe" "mrstart.exe") (install-template dest kind "mzstart.exe" "mrstart.exe")
(let ([bstr (string->bytes/utf-8 (str-list->dos-str flags))] (let ([bstr (bytes->utf-16-bytes
(string->bytes/utf-8 (str-list->dos-str flags)))]
[p (open-input-file dest)] [p (open-input-file dest)]
[m #rx#"<Command Line: Replace This[^>]*>"] [m (utf-16-regexp #"<Command Line: Replace This")]
[x #rx#"<Executable Directory: Replace This[^>]*>"] [x (utf-16-regexp #"<Executable Directory: Replace This")]
[v #rx#"<Executable Variant: Replace This>"]) [v (byte-regexp #"<Executable Variant: Replace This")])
(let* ([exedir (bytes-append (let* ([exedir (bytes->utf-16-bytes
(path->bytes (if (let ([m (assq 'relative? aux)]) (bytes-append
(and m (cdr m))) (path->bytes (if (let ([m (assq 'relative? aux)])
(or (relativize (normalize+explode-path plthome) (and m (cdr m)))
(normalize+explode-path dest)) (or (relativize (normalize+explode-path plthome)
(build-path 'same)) (normalize+explode-path dest))
plthome)) (build-path 'same))
;; null character marks end of executable directory plthome))
#"\0")] ;; null wchar marks end of executable directory
#"\0\0"))]
[find-it ; Find the magic start [find-it ; Find the magic start
(lambda (magic s) (lambda (magic s)
(file-position p 0) (file-position p 0)
@ -436,7 +445,7 @@
(check-len len-command bstr "collection/file name") (check-len len-command bstr "collection/file name")
(let ([p (open-output-file dest 'update)]) (let ([p (open-output-file dest 'update)])
(write-magic p exedir pos-exedir len-exedir) (write-magic p exedir pos-exedir len-exedir)
(write-magic p bstr pos-command len-command) (write-magic p (bytes-append bstr #"\0\0") pos-command len-command)
(when (eq? '3m (current-launcher-variant)) (when (eq? '3m (current-launcher-variant))
(write-magic p #"3" pos-variant 1)) (write-magic p #"3" pos-variant 1))
(close-output-port p))))))) (close-output-port p)))))))

View File

@ -18,7 +18,10 @@
(lib "port.ss") (lib "port.ss")
(lib "etc.ss") (lib "etc.ss")
(lib "kw.ss") (lib "kw.ss")
(lib "filename-version.ss" "dynext")) (lib "filename-version.ss" "dynext")
;; For windows-lib-dir; remove it when that goes into
;; a different library:
(lib "winutf16.ss" "compiler" "private"))
(provide ssl-available? (provide ssl-available?
ssl-load-fail-reason ssl-load-fail-reason
@ -58,12 +61,17 @@
(find-executable-path (find-system-path 'exec-file)))]) (find-executable-path (find-system-path 'exec-file)))])
(with-input-from-file exe (with-input-from-file exe
(lambda () (lambda ()
(let ([m (regexp-match #rx#"dLl dIRECTORy:([^\0]*)\0" (current-input-port))]) (let ([m (regexp-match (byte-regexp
(bytes-append
#"("
(bytes->utf-16-bytes #"dLl dIRECTORy:")
#".*?)\0\0"))
(current-input-port))])
(unless m (error "cannot find DLL directory")) (unless m (error "cannot find DLL directory"))
(if (regexp-match #rx#"^<" (cadr m)) (if (regexp-match #rx#"^<" (cadr m))
#f ; no lib dir #f ; no lib dir
(let-values ([(dir name dir?) (split-path exe)]) (let-values ([(dir name dir?) (split-path exe)])
(build-path dir (bytes->path (cadr m))))))))))) (build-path dir (bytes->path (utf-16-bytes->bytes (cadr m))))))))))))
(define (ffi-lib-win name) (define (ffi-lib-win name)
(let* ([d (force windows-lib-dir)] (let* ([d (force windows-lib-dir)]

View File

@ -20,7 +20,7 @@
"Found an unknown source directory: ~s\n" "Found an unknown source directory: ~s\n"
lib)])] lib)])]
[so-name (build-path top-dir "compiled" "native" [so-name (build-path top-dir "compiled" "native"
(system-library-subpath) (system-library-subpath #f)
(append-extension-suffix libname))]) (append-extension-suffix libname))])
(parameterize ([current-directory lib] (parameterize ([current-directory lib]
[current-extension-compiler-flags [current-extension-compiler-flags

View File

@ -1592,6 +1592,10 @@
"Simulate Down" p2 "Simulate Down" p2
(lambda (c e) (lambda (c e)
(simulate (sub1 (send s get-value))))) (simulate (sub1 (send s get-value)))))
(make-object check-box%
"Disabled" p2
(lambda (c e)
(send s enable (not (send c get-value)))))
(instructions p "slider-steps.txt") (instructions p "slider-steps.txt")
(send f show #t)) (send f show #t))

View File

@ -78,6 +78,12 @@ extern char **wxGetCompleteFaceList(int *_len);
#endif #endif
#endif #endif
#ifdef wx_msw
# define fopen_to_read(fn) _wfopen(wxWIDE_STRING(fn), L"rb")
#else
# define fopen_to_read(fn) fopen(fn, "rb")
#endif
class GCBitmap { class GCBitmap {
public: public:
#ifdef MZ_PRECISE_GC #ifdef MZ_PRECISE_GC
@ -2565,7 +2571,8 @@ int wxsGetImageType(char *fn)
#endif #endif
GC_CAN_IGNORE unsigned char *expect = NULL; GC_CAN_IGNORE unsigned char *expect = NULL;
f = fopen(fn, "rb"); f = fopen_to_read(fn, "rb");
if (f) { if (f) {
switch ((unsigned)fgetc(f)) { switch ((unsigned)fgetc(f)) {
case 'B': case 'B':
@ -2711,7 +2718,7 @@ int wxGetPreference(const char *name, char *res, long len)
/*************** Common ***************/ /*************** Common ***************/
fp = fopen(s, "rb"); fp = fopen_to_read(s, "rb");
if (!fp) if (!fp)
return 0; return 0;

View File

@ -8,7 +8,7 @@
#include "myssink_i.c" #include "myssink_i.c"
#include "Sink.h" #include "Sink.h"
#define DLL_RELATIVE_PATH "." #define DLL_RELATIVE_PATH L"."
#include "../../mzscheme/delayed.inc" #include "../../mzscheme/delayed.inc"
CComModule _Module; CComModule _Module;

View File

@ -5012,7 +5012,7 @@ void browserHwndMsgLoop (LPVOID p)
} }
} }
#define DLL_RELATIVE_PATH "../../../../../../../lib" #define DLL_RELATIVE_PATH L"../../../../../../../lib"
#include "../mzscheme/delayed.inc" #include "../mzscheme/delayed.inc"
BOOL APIENTRY DllMain (HANDLE hModule, DWORD reason, LPVOID lpReserved) BOOL APIENTRY DllMain (HANDLE hModule, DWORD reason, LPVOID lpReserved)

View File

@ -92,7 +92,7 @@ LPCTSTR FindOneOf(LPCTSTR p1, LPCTSTR p2)
return NULL; return NULL;
} }
#define DLL_RELATIVE_PATH "lib" #define DLL_RELATIVE_PATH L"lib"
#include "../mzscheme/delayed.inc" #include "../mzscheme/delayed.inc"
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View File

@ -36,14 +36,14 @@ static int _coldir_offset = 19; /* Skip permanent tag */
#ifdef DOS_FILE_SYSTEM #ifdef DOS_FILE_SYSTEM
# include <Windows.h> # include <Windows.h>
#define DLL_RELATIVE_PATH "lib" #define DLL_RELATIVE_PATH L"lib"
#include "delayed.inc" #include "delayed.inc"
extern extern
# ifdef __cplusplus # ifdef __cplusplus
"C" "C"
# endif # endif
__declspec(dllexport) void scheme_set_dll_path(char *s); __declspec(dllexport) void scheme_set_dll_path(wchar_t *s);
static void record_dll_path(void) static void record_dll_path(void)
{ {
@ -539,17 +539,17 @@ static int run_from_cmd_line(int argc, char *_argv[],
where the old end was, and cmdline_exe_hack[8] where the old end was, and cmdline_exe_hack[8]
says how long the cmdline string is. It might says how long the cmdline string is. It might
be relative to the executable. */ be relative to the executable. */
char *path; wchar_t *path;
HANDLE fd; HANDLE fd;
path = (char *)malloc(1024); path = (wchar_t *)malloc(1024 * sizeof(wchar_t));
GetModuleFileName(NULL, path, 1024); GetModuleFileNameW(NULL, path, 1024);
fd = CreateFile(path, GENERIC_READ, fd = CreateFileW(path, GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, NULL,
OPEN_EXISTING, OPEN_EXISTING,
0, 0,
NULL); NULL);
if (fd == INVALID_HANDLE_VALUE) if (fd == INVALID_HANDLE_VALUE)
p = (unsigned char *)"\0\0\0"; p = (unsigned char *)"\0\0\0";
else { else {
@ -576,13 +576,24 @@ static int run_from_cmd_line(int argc, char *_argv[],
} else { } else {
/* Make it absolute, relative to this executable */ /* Make it absolute, relative to this executable */
int plen = strlen(prog); int plen = strlen(prog);
int mlen = strlen(path); int mlen, len;
char *s2; char *s2, *p2;
while (mlen && (path[mlen - 1] != '\\')) {
/* UTF-8 encode path: */
for (len = 0; path[len]; len++) { }
mlen = scheme_utf8_encode((unsigned int *)path, 0, len,
NULL, 0,
1 /* UTF-16 */);
p2 = (char *)malloc(mlen + 1);
mlen = scheme_utf8_encode((unsigned int *)path, 0, len,
(unsigned char *)p2, 0,
1 /* UTF-16 */);
while (mlen && (p2[mlen - 1] != '\\')) {
mlen--; mlen--;
} }
s2 = (char *)malloc(mlen + plen + 1); s2 = (char *)malloc(mlen + plen + 1);
memcpy(s2, path, mlen); memcpy(s2, p2, mlen);
memcpy(s2 + mlen, prog, plen + 1); memcpy(s2 + mlen, prog, plen + 1);
prog = s2; prog = s2;
} }

View File

@ -4,17 +4,17 @@
# else # else
# define DLL_3M_SUFFIX "" # define DLL_3M_SUFFIX ""
# endif # endif
static char *_dlldir = "dLl dIRECTORy:" /* <- this tag stays, so we can find it again */ static wchar_t *_dlldir = L"dLl dIRECTORy:" /* <- this tag stays, so we can find it again */
DLL_RELATIVE_PATH "\0" DLL_RELATIVE_PATH L"\0"
/* Pad with 512 bytes: */ /* Pad with 512 characters: */
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************"; L"****************************************************************";
static int _dlldir_offset = 14; /* Skip permanent tag */ static int _dlldir_offset = 14; /* Skip permanent tag */
# ifdef MZ_PRECISE_GC # ifdef MZ_PRECISE_GC
@ -24,7 +24,7 @@ START_XFORM_SKIP;
static void load_delayed_dll(HINSTANCE me, char *lib) static void load_delayed_dll(HINSTANCE me, char *lib)
{ {
/* Don't use the C library here! */ /* Don't use the C library here! */
char *dlldir = _dlldir + _dlldir_offset; wchar_t *dlldir = _dlldir + _dlldir_offset;
if (dlldir[0] != '<') { if (dlldir[0] != '<') {
if ((dlldir[0] == '\\') if ((dlldir[0] == '\\')
@ -34,11 +34,12 @@ static void load_delayed_dll(HINSTANCE me, char *lib)
/* Absolute path */ /* Absolute path */
} else { } else {
/* Make it absolute, relative to this module */ /* Make it absolute, relative to this module */
char name[1024], *s; wchar_t *name, *s;
int j, i; int j, i;
GetModuleFileName(me, name, 1024); name = (wchar_t *)GlobalAlloc(GMEM_FIXED, 1024 * sizeof(wchar_t));
GetModuleFileNameW(me, name, 1024);
name[1023] = 0; name[1023] = 0;
s = (char *)GlobalAlloc(GMEM_FIXED, 2048); s = (wchar_t *)GlobalAlloc(GMEM_FIXED, 2048 * sizeof(wchar_t));
for (i = 0; name[i]; i++) { } for (i = 0; name[i]; i++) { }
--i; --i;
while (i && (name[i] != '\\')) { while (i && (name[i] != '\\')) {
@ -58,10 +59,10 @@ static void load_delayed_dll(HINSTANCE me, char *lib)
} }
{ {
char *t; wchar_t *t;
int j, i; int j, i;
t = (char *)GlobalAlloc(GMEM_FIXED, 2048); t = (wchar_t *)GlobalAlloc(GMEM_FIXED, 2048 * sizeof(wchar_t));
for (i = 0; dlldir[i]; i++) { for (i = 0; dlldir[i]; i++) {
t[i] = dlldir[i]; t[i] = dlldir[i];
} }
@ -72,8 +73,8 @@ static void load_delayed_dll(HINSTANCE me, char *lib)
} }
t[i] = 0; t[i] = 0;
if (!LoadLibrary(t)) { if (!LoadLibraryW(t)) {
MessageBox(NULL, t, "Failure: cannot load DLL", MB_OK); MessageBoxW(NULL, t, L"Failure: cannot load DLL", MB_OK);
ExitProcess(1); ExitProcess(1);
} }
} }

View File

@ -18,16 +18,18 @@
#endif #endif
#ifdef MRSTART #ifdef MRSTART
# define GOSUBDIR "\\" # define GOSUBDIR L"\\"
# define GOEXE "mred.exe" # define GOEXE L"mred.exe"
# define GOEXE3M "mred3m.exe" # define sGOEXE "mred.exe"
# define GOEXE3M L"mred3m.exe"
# define WAITTILLDONE 0 # define WAITTILLDONE 0
#endif #endif
#ifdef MZSTART #ifdef MZSTART
# define GOSUBDIR "\\" # define GOSUBDIR L"\\"
# define GOEXE "mzscheme.exe" # define GOEXE L"mzscheme.exe"
# define GOEXE3M "mzscheme3m.exe" # define sGOEXE "mzscheme.exe"
# define GOEXE3M L"mzscheme3m.exe"
# define WAITTILDONE 1 # define WAITTILDONE 1
#endif #endif
@ -44,57 +46,81 @@
/* Win command lines limited to 1024 chars, so 1024 chars for /* Win command lines limited to 1024 chars, so 1024 chars for
command tail is ample */ command tail is ample */
static char *input = static wchar_t *input =
"<Command Line: Replace This ************************************" L"<Command Line: Replace This ************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"****************************************************************" L"****************************************************************"
"***************************************************************>"; L"***************************************************************>";
/* Win long filenames limited to 255 chars, so 254 chars for /* Win long filenames limited to 255 chars, so 254 chars for
directory is ample */ directory is ample */
static char *exedir = "<Executable Directory: Replace This ********" static wchar_t *exedir = L"<Executable Directory: Replace This ********"
"********************************************" L"********************************************"
"********************************************" L"********************************************"
"********************************************" L"********************************************"
"********************************************" L"********************************************"
"********************************************>"; L"********************************************>";
static char *variant = "<Executable Variant: Replace This>"; static char *variant = "<Executable Variant: Replace This>";
static char *protect(char *s) static int wc_strlen(const wchar_t *ws)
{ {
char *naya; int l;
for (l = 0; ws[l]; l++) { }
return l;
}
static void wc_strcpy(wchar_t *dest, const wchar_t *src)
{
while (*src) {
*dest = *src;
dest++;
src++;
}
*dest = 0;
}
static void wc_strcat(wchar_t *dest, const wchar_t *src)
{
while (*dest)
dest++;
wc_strcpy(dest, src);
}
static wchar_t *protect(wchar_t *s)
{
wchar_t *naya;
int has_space = 0, has_quote = 0, was_slash = 0; int has_space = 0, has_quote = 0, was_slash = 0;
for (naya = s; *naya; naya++) { for (naya = s; *naya; naya++) {
if (isspace(*naya) || (*naya == '\'')) { if (((*naya < 128) && isspace(*naya)) || (*naya == '\'')) {
has_space = 1; has_space = 1;
was_slash = 0; was_slash = 0;
} else if (*naya == '"') { } else if (*naya == '"') {
@ -107,10 +133,10 @@ static char *protect(char *s)
} }
if (has_space || has_quote) { if (has_space || has_quote) {
char *p; wchar_t *p;
int wrote_slash = 0; int wrote_slash = 0;
naya = malloc(strlen(s) + 3 + 3*has_quote); naya = (wchar_t *)malloc((wc_strlen(s) + 3 + 3*has_quote) * sizeof(wchar_t));
naya[0] = '"'; naya[0] = '"';
for (p = naya + 1; *s; s++) { for (p = naya + 1; *s; s++) {
if (*s == '"') { if (*s == '"') {
@ -138,21 +164,21 @@ static char *protect(char *s)
return s; return s;
} }
static int parse_command_line(int count, char **command, static int parse_command_line(int count, wchar_t **command,
char *buf, int maxargs) wchar_t *buf, int maxargs)
{ {
char *parse, *created, *write; wchar_t *parse, *created, *write;
int findquote = 0; int findquote = 0;
parse = created = write = buf; parse = created = write = buf;
while (*parse) { while (*parse) {
while (*parse && isspace(*parse)) parse++; while (*parse && (*parse < 128) && isspace(*parse)) parse++;
while (*parse && (!isspace(*parse) || findquote)) { while (*parse && ((*parse > 128) || !isspace(*parse) || findquote)) {
if (*parse== '"') { if (*parse== '"') {
findquote = !findquote; findquote = !findquote;
} else if (*parse== '\\') { } else if (*parse== '\\') {
char *next; wchar_t *next;
for (next = parse; *next == '\\'; next++); for (next = parse; *next == '\\'; next++);
if (*next == '"') { if (*next == '"') {
/* Special handling: */ /* Special handling: */
@ -174,7 +200,7 @@ static int parse_command_line(int count, char **command,
parse++; parse++;
*(write++) = 0; *(write++) = 0;
if (*created) { if (*created) {
command[count++] = created; command[count++] = created;
if (count == maxargs) if (count == maxargs)
return count; return count;
@ -185,22 +211,23 @@ static int parse_command_line(int count, char **command,
return count; return count;
} }
static char *make_command_line(int argc, char **argv) static wchar_t *make_command_line(int argc, wchar_t **argv)
{ {
int i, len = 0; int i, len = 0;
char *r; wchar_t *r;
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
len += strlen(argv[i]) + 1; len += wc_strlen(argv[i]) + 1;
} }
r = malloc(len); r = (wchar_t *)malloc(len * sizeof(wchar_t));
len = 0; len = 0;
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
int l = strlen(argv[i]); int l = wc_strlen(argv[i]);
if (len) r[len++] = ' '; if (len) r[len++] = ' ';
memcpy(r + len, argv[i], l); memcpy(r + len, argv[i], l * sizeof(wchar_t));
len += l; len += l;
} }
r[len] = 0; r[len] = 0;
return r; return r;
} }
@ -213,28 +240,28 @@ void WriteStr(HANDLE h, const char *s) {
#endif #endif
#ifdef DUPLICATE_INPUT #ifdef DUPLICATE_INPUT
static char *copy_string(char *s) static wchar_t *copy_string(wchar_t *s)
{ {
int l = strlen(s); int l = wc_strlen(s);
char *d = malloc(l + 1); wchar_t *d = (wchar_t *)malloc((l + 1) * sizeof(wchar_t));
memcpy(d, s, l + 1); memcpy(d, s, (l + 1) * sizeof(wchar_t));
return d; return d;
} }
#endif #endif
#ifdef MRSTART #ifdef MRSTART
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR m_lpCmdLine, int nCmdShow) LPWSTR m_lpCmdLine, int nCmdShow)
#else #else
int main(int argc_in, char **argv_in) int wmain(int argc_in, wchar_t **argv_in)
#endif #endif
{ {
char go[MAXCOMMANDLEN * 2]; wchar_t go[MAXCOMMANDLEN * 2];
char *args[MAX_ARGS + 1]; wchar_t *args[MAX_ARGS + 1];
char *command_line; wchar_t *command_line;
int count, i; int count, i, cl_len;
struct MSC_IZE(stat) st; struct MSC_IZE(stat) st;
STARTUPINFO si; STARTUPINFOW si;
PROCESS_INFORMATION pi; PROCESS_INFORMATION pi;
#ifdef MZSTART #ifdef MZSTART
HANDLE out; HANDLE out;
@ -261,34 +288,35 @@ int main(int argc_in, char **argv_in)
/* Make it absolute, relative to this executable */ /* Make it absolute, relative to this executable */
int plen; int plen;
int mlen; int mlen;
char *s2, *path; wchar_t *s2, *path;
path = (char *)malloc(1024); path = (wchar_t *)malloc(1024 * sizeof(wchar_t));
GetModuleFileName(NULL, path, 1024); GetModuleFileNameW(NULL, path, 1024);
plen = strlen(exedir); plen = wc_strlen(exedir);
mlen = strlen(path); mlen = wc_strlen(path);
while (mlen && (path[mlen - 1] != '\\')) { while (mlen && (path[mlen - 1] != '\\')) {
mlen--; mlen--;
} }
s2 = (char *)malloc(mlen + plen + 1); s2 = (wchar_t *)malloc((mlen + plen + 1) * sizeof(wchar_t));
memcpy(s2, path, mlen); memcpy(s2, path, mlen * sizeof(wchar_t));
memcpy(s2 + mlen, exedir, plen + 1); memcpy(s2 + mlen, exedir, (plen + 1) * sizeof(wchar_t));
exedir = s2; exedir = s2;
} }
strcpy(go, exedir); wc_strcpy(go, exedir);
strcat(go, GOSUBDIR); wc_strcat(go, GOSUBDIR);
strcat(go, (variant[0] != '<') ? GOEXE3M : GOEXE); wc_strcat(go, (variant[0] != '<') ? GOEXE3M : GOEXE);
if (_stat(go, &st)) { if (_wstat(go, &st)) {
char errbuff[MAXCOMMANDLEN * 2];
#ifdef MRSTART #ifdef MRSTART
sprintf(errbuff,"Can't find %s",go); wchar_t errbuff[MAXCOMMANDLEN * 2];
MessageBox(NULL,errbuff,"Error",MB_OK); swprintf(errbuff,L"Can't find %s",go);
MessageBoxW(NULL,errbuff,L"Error",MB_OK);
#else #else
sprintf(errbuff,"Can't find %s\n",go); char errbuff[MAXCOMMANDLEN * 2];
sprintf(errbuff,"Can't find %S\n",go);
WriteStr(out,errbuff); WriteStr(out,errbuff);
#endif #endif
exit(-1); exit(-1);
@ -298,10 +326,12 @@ int main(int argc_in, char **argv_in)
#ifdef MRSTART #ifdef MRSTART
{ {
char *buf; wchar_t *buf;
buf = malloc(strlen(m_lpCmdLine) + 1); m_lpCmdLine = GetCommandLineW();
memcpy(buf, m_lpCmdLine, strlen(m_lpCmdLine) + 1);
buf = (wchar_t *)malloc((wc_strlen(m_lpCmdLine) + 1) * sizeof(wchar_t));
memcpy(buf, m_lpCmdLine, (wc_strlen(m_lpCmdLine) + 1) * sizeof(wchar_t));
count = parse_command_line(count, args, buf, MAX_ARGS); count = parse_command_line(count, args, buf, MAX_ARGS);
} }
#else #else
@ -319,35 +349,36 @@ int main(int argc_in, char **argv_in)
/* MessageBox(NULL, args[i], "Argument", MB_OK); */ /* MessageBox(NULL, args[i], "Argument", MB_OK); */
} }
for (i = 0; i < sizeof(si); i++) memset(&si, 0, sizeof(si));
((char *)&si)[i] = 0;
si.cb = sizeof(si); si.cb = sizeof(si);
command_line = make_command_line(count, args); command_line = make_command_line(count, args);
if (strlen(command_line) > MAXCOMMANDLEN) { cl_len = wc_strlen(command_line);
char errbuff[MAXCOMMANDLEN * 2]; if (cl_len > MAXCOMMANDLEN) {
#ifdef MRSTART #ifdef MRSTART
sprintf(errbuff,"Command line exceeds %d characters: %s", wchar_t errbuff[MAXCOMMANDLEN * 2];
MAXCOMMANDLEN,go); swprintf(errbuff,L"Command line of %d characters exceeds %d characters: %.1024s",
MessageBox(NULL,errbuff,"Error",MB_OK); cl_len, MAXCOMMANDLEN,command_line);
MessageBoxW(NULL,errbuff,L"Error",MB_OK);
#else #else
sprintf(errbuff,"Command line exceeds %d characters: %s\n", char errbuff[MAXCOMMANDLEN * 2];
MAXCOMMANDLEN,go); sprintf(errbuff,"Command line of %d characters exceeds %d characters: %.1024S\n",
cl_len, MAXCOMMANDLEN,command_line);
WriteStr(out,errbuff); WriteStr(out,errbuff);
#endif #endif
exit(-1); exit(-1);
} }
if (!CreateProcess(go, if (!CreateProcessW(go,
command_line, command_line,
NULL, NULL, TRUE, NULL, NULL, TRUE,
0, NULL, NULL, &si, &pi)) { 0, NULL, NULL, &si, &pi)) {
#ifdef MRSTART #ifdef MRSTART
MessageBox(NULL, "Can't start " GOEXE, "Error", MB_OK); MessageBoxW(NULL, L"Can't start " GOEXE, L"Error", MB_OK);
#else #else
WriteStr(out, "Can't start " GOEXE "\n"); WriteStr(out, "Can't start " sGOEXE "\n");
#endif #endif
return -1; return -1;
} else { } else {

View File

@ -4768,30 +4768,30 @@ void scheme_set_original_dir(Scheme_Object *d)
#ifdef DOS_FILE_SYSTEM #ifdef DOS_FILE_SYSTEM
static char *dlldir; static wchar_t *dlldir;
__declspec(dllexport) char *scheme_get_dll_path(char *s); __declspec(dllexport) wchar_t *scheme_get_dll_path(wchar_t *s);
__declspec(dllexport) void scheme_set_dll_path(char *p); __declspec(dllexport) void scheme_set_dll_path(wchar_t *p);
char *scheme_get_dll_path(char *s) wchar_t *scheme_get_dll_path(wchar_t *s)
{ {
if (dlldir) { if (dlldir) {
int len1, len2; int len1, len2;
char *p; wchar_t *p;
len1 = strlen(dlldir); len1 = wc_strlen(dlldir);
len2 = strlen(s); len2 = wc_strlen(s);
p = (char *)scheme_malloc_atomic(len1 + len2 + 2); p = (wchar_t *)scheme_malloc_atomic((len1 + len2 + 2) * sizeof(wchar_t));
memcpy(p, dlldir, len1); memcpy(p, dlldir, len1);
if (p[len1 - 1] != '\\') { if (p[len1 - 1] != '\\') {
p[len1++] = '\\'; p[len1++] = '\\';
} }
memcpy(p + len1, s, len2 + 1); memcpy(p + len1, s, (len2 + 1) * sizeof(wchar_t));
return p; return p;
} else } else
return s; return s;
} }
void scheme_set_dll_path(char *p) void scheme_set_dll_path(wchar_t *p)
{ {
dlldir = p; dlldir = p;
} }

View File

@ -81,16 +81,16 @@ static int get_iconv_errno(void)
# define HAVE_CODESET 1 # define HAVE_CODESET 1
# define CODESET 0 # define CODESET 0
# define ICONV_errno get_iconv_errno() # define ICONV_errno get_iconv_errno()
extern char *scheme_get_dll_path(char *s); extern wchar_t *scheme_get_dll_path(wchar_t *s);
static int iconv_ready = 0; static int iconv_ready = 0;
static void init_iconv() static void init_iconv()
{ {
# ifdef MZ_NO_ICONV # ifdef MZ_NO_ICONV
# else # else
HMODULE m; HMODULE m;
m = LoadLibrary(scheme_get_dll_path("iconv.dll")); m = LoadLibraryW(scheme_get_dll_path(L"iconv.dll"));
if (!m) if (!m)
m = LoadLibrary(scheme_get_dll_path("libiconv.dll")); m = LoadLibraryW(scheme_get_dll_path(L"libiconv.dll"));
if (!m) if (!m)
m = LoadLibrary("iconv.dll"); m = LoadLibrary("iconv.dll");
if (!m) if (!m)
@ -1091,12 +1091,7 @@ do_byte_string_to_char_string(const char *who,
ulen = utf8_decode_x((unsigned char *)chars, istart, ifinish, ulen = utf8_decode_x((unsigned char *)chars, istart, ifinish,
NULL, 0, -1, NULL, 0, -1,
NULL, NULL, 0, NULL, NULL, 0, 0,
#ifdef WINDOWS_UNICODE_SUPPORT
as_locale ? 1 : 0,
#else
0,
#endif
NULL, 0, NULL, 0,
(perm > -1) ? 0xD800 : 0); (perm > -1) ? 0xD800 : 0);
if (ulen < 0) { if (ulen < 0) {
@ -1108,12 +1103,7 @@ do_byte_string_to_char_string(const char *who,
v = (unsigned int *)scheme_malloc_atomic((ulen + 1) * sizeof(unsigned int)); v = (unsigned int *)scheme_malloc_atomic((ulen + 1) * sizeof(unsigned int));
utf8_decode_x((unsigned char *)chars, istart, ifinish, utf8_decode_x((unsigned char *)chars, istart, ifinish,
v, 0, -1, v, 0, -1,
NULL, NULL, 0, NULL, NULL, 0, 0,
#ifdef WINDOWS_UNICODE_SUPPORT
as_locale ? 1 : 0,
#else
0,
#endif
NULL, 0, NULL, 0,
(perm > -1) ? 0xD800 : 0); (perm > -1) ? 0xD800 : 0);
@ -4209,7 +4199,7 @@ static Scheme_Object *convert_one(const char *who, int opos, int argc, Scheme_Ob
/* Copy to word-align */ /* Copy to word-align */
char *c2; char *c2;
c2 = (char *)scheme_malloc_atomic(ifinish - istart); c2 = (char *)scheme_malloc_atomic(ifinish - istart);
memcpy(c, instr XFORM_OK_PLUS istart, ifinish - istart); memcpy(c2, instr XFORM_OK_PLUS istart, ifinish - istart);
ifinish = ifinish - istart; ifinish = ifinish - istart;
istart = 0; istart = 0;
instr = c2; instr = c2;

View File

@ -246,7 +246,13 @@
srcs))]) srcs))])
(link-dll objs null null dll "" #f)) (link-dll objs null null dll "" #f))
(unless (file-exists? "mzscheme.res")
(system- (string-append
"rc /l 0x409 "
"/fomzscheme.res ../mzscheme/mzscheme.rc")))
(let ([objs (list (let ([objs (list
"mzscheme.res"
"xsrc/main.obj" "xsrc/main.obj"
"../mzscheme/Release/uniplt.obj" "../mzscheme/Release/uniplt.obj"
"../../../lib/msvc/libmzsch3mxxxxxxx.lib")]) "../../../lib/msvc/libmzsch3mxxxxxxx.lib")])

View File

@ -49,6 +49,17 @@ static wxColor *the_color;
extern void wxmeError(const char *e); extern void wxmeError(const char *e);
extern int wxGetPreference(const char *name, char *res, long len); extern int wxGetPreference(const char *name, char *res, long len);
#ifdef wx_msw
# include "wx_utils.h"
# define wxFOpen(fn, m) _wfopen(wxWIDE_STRING(fn), m)
# define wx_RB_mode L"rb"
# define wx_WB_mode L"wb"
#else
# define wxFOpen(fn, m) fopen(fn, m)
# define wx_RB_mode "rb"
# define wx_WB_mode "wb"
#endif
#ifndef DRAW_SCANLINE_DEFINED #ifndef DRAW_SCANLINE_DEFINED
static void draw_scanline(JSAMPROW row, int cols, int rownum, int step, JSAMPARRAY colormap, wxMemoryDC *dc, static void draw_scanline(JSAMPROW row, int cols, int rownum, int step, JSAMPARRAY colormap, wxMemoryDC *dc,
@ -201,7 +212,7 @@ int read_JPEG_file(char * filename, wxBitmap *bm)
* requires it in order to read binary files. * requires it in order to read binary files.
*/ */
if ((infile = fopen(filename, "rb")) == NULL) { if ((infile = wxFOpen(filename, wx_RB_mode)) == NULL) {
sprintf(jpeg_err_buffer, "can't open %.255s\n", filename); sprintf(jpeg_err_buffer, "can't open %.255s\n", filename);
wxmeError(jpeg_err_buffer); wxmeError(jpeg_err_buffer);
return 0; return 0;
@ -355,7 +366,7 @@ int write_JPEG_file(char *filename, wxBitmap *bm, int quality)
wid = bm->GetWidth(); wid = bm->GetWidth();
row_pointer = new WXGC_ATOMIC JSAMPLE[3 * wid]; row_pointer = new WXGC_ATOMIC JSAMPLE[3 * wid];
if ((outfile = fopen(filename, "wb")) == NULL) { if ((outfile = wxFOpen(filename, wx_WB_mode)) == NULL) {
if (desel) if (desel)
dc->SelectObject(NULL); dc->SelectObject(NULL);
sprintf(jpeg_err_buffer, "can't open %.255s\n", filename); sprintf(jpeg_err_buffer, "can't open %.255s\n", filename);
@ -629,7 +640,7 @@ int wx_read_png(char *file_name, wxBitmap *bm, int w_mask, wxColour *bg)
wxMemoryDC *mdc = NULL; wxMemoryDC *mdc = NULL;
wxBitmap *mbm = NULL; wxBitmap *mbm = NULL;
if ((fp = fopen(file_name, "rb")) == NULL) if ((fp = wxFOpen(file_name, wx_RB_mode)) == NULL)
return 0; return 0;
/* Create and initialize the png_struct with the desired error handler /* Create and initialize the png_struct with the desired error handler
@ -918,7 +929,7 @@ int wx_write_png(char *file_name, wxBitmap *bm)
volatile int desel = 1; volatile int desel = 1;
volatile int mdesel = 1; volatile int mdesel = 1;
if ((fp = fopen(file_name, "wb")) == NULL) if ((fp = wxFOpen(file_name, wx_WB_mode)) == NULL)
return 0; return 0;
/* Create and initialize the png_struct with the desired error handler /* Create and initialize the png_struct with the desired error handler

View File

@ -53,6 +53,10 @@
#endif #endif
#endif #endif
/* Need wxWIDE_STRING for Windows: */
extern wchar_t *_wx_convert_to_wchar(char *s, int do_copy);
#define wxWIDE_STRING(s) _wx_convert_to_wchar(s, 0)
/* 3.2 backward compatibility code */ /* 3.2 backward compatibility code */
LFUNC(CreateOldColorTable, int, (XpmColor *ct, int ncolors, LFUNC(CreateOldColorTable, int, (XpmColor *ct, int ncolors,
XpmColor ***oldct)); XpmColor ***oldct));
@ -454,7 +458,7 @@ XpmReadFileToBuffer(char *filename, char **buffer_return)
*buffer_return = NULL; *buffer_return = NULL;
fd = open(filename, O_RDONLY); fd = _wopen(wxWIDE_STRING(filename), O_RDONLY);
if (fd < 0) if (fd < 0)
return XpmOpenFailed; return XpmOpenFailed;
@ -488,7 +492,7 @@ int
XpmWriteFileFromBuffer(char *filename, char *buffer) XpmWriteFileFromBuffer(char *filename, char *buffer)
{ {
int fcheck, len; int fcheck, len;
FILE *fp = fopen(filename, "w"); FILE *fp = _wfopen(wxWIDE_STRING(filename), L"w");
if (!fp) if (!fp)
return XpmOpenFailed; return XpmOpenFailed;

View File

@ -1948,7 +1948,9 @@ Bool wxBitmap::LoadFile(char *bitmap_file, long flags, wxColour *bg)
if (flags & wxBITMAP_TYPE_BMP_RESOURCE) if (flags & wxBITMAP_TYPE_BMP_RESOURCE)
{ {
ms_bitmap = LoadBitmap(wxhInstance, bitmap_file); wchar_t *ws;
ws = wxWIDE_STRING(bitmap_file);
ms_bitmap = LoadBitmapW(wxhInstance, ws);
if (ms_bitmap) { if (ms_bitmap) {
BITMAP bm; BITMAP bm;
RegisterGDIObject(ms_bitmap); RegisterGDIObject(ms_bitmap);

View File

@ -50,13 +50,15 @@ Bool wxMessage::Create(wxPanel *panel, char *label, wxBitmap *image, int iconID,
bm_label = image; bm_label = image;
} else if (iconID) { } else if (iconID) {
if (!icon_w) { if (!icon_w) {
char name[1024]; wchar_t *name;
name = new WXGC_ATOMIC wchar_t[1024];
icon_w = GetSystemMetrics(SM_CXICON); icon_w = GetSystemMetrics(SM_CXICON);
icon_h = GetSystemMetrics(SM_CYICON); icon_h = GetSystemMetrics(SM_CYICON);
::GetModuleFileName(NULL, name, 1023); ::GetModuleFileNameW(NULL, name, 1023);
icn = ExtractIcon(NULL, name, 0); icn = ExtractIconW(NULL, name, 0);
icons[wxMSGICON_APP - 1] = (icn ? icn : LoadIcon(NULL, IDI_APPLICATION)); icons[wxMSGICON_APP - 1] = (icn ? icn : LoadIcon(NULL, IDI_APPLICATION));
icons[wxMSGICON_WARNING - 1] = LoadIcon(NULL, IDI_WARNING); icons[wxMSGICON_WARNING - 1] = LoadIcon(NULL, IDI_WARNING);
icons[wxMSGICON_ERROR - 1] = LoadIcon(NULL, IDI_ERROR); icons[wxMSGICON_ERROR - 1] = LoadIcon(NULL, IDI_ERROR);

View File

@ -462,6 +462,13 @@ wchar_t *wx_convert_to_wchar(char *s, int do_copy)
return ws; return ws;
} }
extern "C" {
wchar_t *_wx_convert_to_wchar(char *s, int do_copy)
{
return wx_convert_to_wchar(s, do_copy);
}
}
char *wx_convert_from_wchar(wchar_t *ws) char *wx_convert_from_wchar(wchar_t *ws)
{ {
long len, l; long len, l;

View File

@ -76,9 +76,11 @@ wxGIF::wxGIF( char * path)
lpbi = NULL; lpbi = NULL;
for (ushort i=0; i<13; i++) { code_mask[i] = Code_Mask[i]; } for (ushort i=0; i<13; i++) { code_mask[i] = Code_Mask[i]; }
if (path) { if (path) {
fp = fopen(path,"rb"); wchar_t *wp;
wp = wxWIDE_STRING(path);
fp = _wfopen(wp, L"rb");
if (!fp) if (!fp)
return; return;
if (ReadHeader(fp)) { if (ReadHeader(fp)) {
Create(image.w, image.h, 8); Create(image.w, image.h, 8);
if (GetRawImage() != 0) if (GetRawImage() != 0)

View File

@ -23,6 +23,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "wximgxbm.h" #include "wximgxbm.h"
#include "wx_utils.h"
/* /*
@ -69,7 +70,7 @@ char *wxLoadXBM(char *fname, int *width, int *height)
k = 0; k = 0;
fp=fopen(fname,"rt"); fp=_wfopen(wxWIDE_STRING(fname),L"rt");
if (!fp) return NULL; if (!fp) return NULL;
/* figure out the file size (for Informational Purposes Only) */ /* figure out the file size (for Informational Purposes Only) */

View File

@ -19,24 +19,17 @@
* DibFromBitmap() - Creates a DIB repr. the DDB passed in. * * DibFromBitmap() - Creates a DIB repr. the DDB passed in. *
* * * *
* * * *
* lread() - Private routine to read more than 64k *
* *
* lwrite() - Private routine to write more than 64k *
* * * *
*******************************************************************************/ *******************************************************************************/
#include <common.h> #include "common.h"
#include <stdio.h> #include <stdio.h>
#include <wx_gdi.h> #include <fcntl.h>
#include <io.h>
#include "wx_gdi.h"
#include "wx_utils.h"
#include "dib.h" #include "dib.h"
#ifndef SEEK_CUR
/* flags for _lseek */
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0
#endif
#define MAXREAD 32768 /* Number of bytes to be read during */ #define MAXREAD 32768 /* Number of bytes to be read during */
/* each read operation. */ /* each read operation. */
@ -59,9 +52,6 @@
#define PALVERSION 0x300 #define PALVERSION 0x300
#define MAXPALETTE 256 /* max. # supported palette entries */ #define MAXPALETTE 256 /* max. # supported palette entries */
DWORD PASCAL lread(int fh, VOID FAR *pv, DWORD ul);
DWORD PASCAL lwrite(int fh, VOID FAR *pv, DWORD ul);
BOOL WriteDIB (LPSTR szFile,HANDLE hdib); BOOL WriteDIB (LPSTR szFile,HANDLE hdib);
DWORD PaletteSize (VOID FAR * pv); DWORD PaletteSize (VOID FAR * pv);
DWORD DibNumColors (VOID FAR * pv); DWORD DibNumColors (VOID FAR * pv);
@ -86,12 +76,11 @@ BOOL WriteDIB(LPSTR szFile, HANDLE hdib)
BITMAPFILEHEADER hdr; BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER lpbi; LPBITMAPINFOHEADER lpbi;
int fh; int fh;
OFSTRUCT of;
if (!hdib) if (!hdib)
return FALSE; return FALSE;
fh = OpenFile(szFile, &of, OF_CREATE | OF_READWRITE); fh = _wopen(wxWIDE_STRING(szFile), _O_BINARY | _O_RDWR | _O_CREAT);
if (fh == -1) if (fh == -1)
return FALSE; return FALSE;
@ -106,10 +95,10 @@ BOOL WriteDIB(LPSTR szFile, HANDLE hdib)
PaletteSize(lpbi); PaletteSize(lpbi);
/* Write the file header */ /* Write the file header */
_lwrite(fh, (LPSTR) &hdr, sizeof(BITMAPFILEHEADER)); _write(fh, (LPSTR) &hdr, sizeof(BITMAPFILEHEADER));
/* Write the DIB header and the bits */ /* Write the DIB header and the bits */
lwrite(fh, (LPSTR) lpbi, GlobalSize(hdib)); _write(fh, (LPSTR) lpbi, GlobalSize(hdib));
GlobalUnlock(hdib); GlobalUnlock(hdib);
_lclose(fh); _lclose(fh);
@ -311,59 +300,6 @@ HANDLE DibFromBitmap(HBITMAP hbm, DWORD biStyle, WORD biBits, HPALETTE hpal)
} }
#endif #endif
/************* PRIVATE ROUTINES TO READ/WRITE MORE THAN 64K ***************/
/****************************************************************************
* *
* FUNCTION : lread(int fh, VOID FAR *pv, DWORD ul) *
* *
* PURPOSE : Reads data in steps of 32k till all the data has been read.*
* *
* RETURNS : 0 - If read did not proceed correctly. *
* number of bytes read otherwise. *
* *
****************************************************************************/
DWORD PASCAL lread(int fh, VOID far *pv, DWORD ul)
{
DWORD ulT = ul;
BYTE *hp = (BYTE *) pv;
while (ul > (DWORD) MAXREAD) {
if (_lread(fh, (LPSTR) hp, MAXREAD) != MAXREAD)
return 0;
ul -= MAXREAD;
hp += MAXREAD;
}
if (_lread(fh, (LPSTR) hp, ul) != ul)
return 0;
return ulT;
}
/****************************************************************************
* *
* FUNCTION : lwrite(int fh, VOID FAR *pv, DWORD ul) *
* *
* PURPOSE : Writes data in steps of 32k till all the data is written. *
* *
* RETURNS : 0 - If write did not proceed correctly. *
* number of bytes written otherwise. *
* *
****************************************************************************/
DWORD PASCAL lwrite(int fh, VOID FAR *pv, DWORD ul)
{
DWORD ulT = ul;
BYTE *hp = (BYTE *) pv;
while (ul > MAXREAD) {
if (_lwrite(fh, (LPSTR) hp, MAXREAD) != MAXREAD)
return 0;
ul -= MAXREAD;
hp += MAXREAD;
}
if (_lwrite(fh, (LPSTR) hp, ul) != ul)
return 0;
return ulT;
}
/**************************************************************************** /****************************************************************************
* *
* FUNCTION : ReadDIB(hWnd) * FUNCTION : ReadDIB(hWnd)
@ -383,19 +319,18 @@ BOOL ReadDIB(LPSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
{ {
int fh; int fh;
LPBITMAPINFOHEADER lpbi; LPBITMAPINFOHEADER lpbi;
OFSTRUCT of;
BITMAPFILEHEADER bf; BITMAPFILEHEADER bf;
DWORD nNumColors; DWORD nNumColors;
BOOL result = FALSE; BOOL result = FALSE;
char str[128]; DWORD offBits, got;
DWORD offBits, extra_space, got;
HDC hDC; HDC hDC;
BOOL bCoreHead = FALSE; BOOL bCoreHead = FALSE;
HANDLE hDIB = 0; HANDLE hDIB = 0;
/* Open the file and get a handle to it's BITMAPINFO */ /* Open the file and get a handle to it's BITMAPINFO */
fh = OpenFile (lpFileName, &of, OF_READ); fh = _wopen(wxWIDE_STRING(lpFileName), _O_BINARY | _O_RDONLY);
if (fh == -1) { if (fh == -1) {
// wsprintf(str,"Can't open file '%ls'", (LPSTR)lpFileName); // wsprintf(str,"Can't open file '%ls'", (LPSTR)lpFileName);
// MessageBox(NULL, str, "Error", MB_ICONSTOP | MB_OK); // MessageBox(NULL, str, "Error", MB_ICONSTOP | MB_OK);
@ -412,13 +347,13 @@ BOOL ReadDIB(LPSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB); lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
/* read the BITMAPFILEHEADER */ /* read the BITMAPFILEHEADER */
if (sizeof (bf) != _lread (fh, (LPSTR)&bf, sizeof (bf))) if (sizeof (bf) != _read (fh, (LPSTR)&bf, sizeof (bf)))
goto ErrExit; goto ErrExit;
if (bf.bfType != 0x4d42) /* 'BM' */ if (bf.bfType != 0x4d42) /* 'BM' */
goto ErrExit; goto ErrExit;
if (sizeof(BITMAPCOREHEADER) != _lread (fh, (LPSTR)lpbi, sizeof(BITMAPCOREHEADER))) if (sizeof(BITMAPCOREHEADER) != _read (fh, (LPSTR)lpbi, sizeof(BITMAPCOREHEADER)))
goto ErrExit; goto ErrExit;
if (lpbi->biSize == sizeof(BITMAPCOREHEADER)) if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
@ -433,8 +368,8 @@ BOOL ReadDIB(LPSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
else else
{ {
// get to the start of the header and read INFOHEADER // get to the start of the header and read INFOHEADER
_llseek(fh,sizeof(BITMAPFILEHEADER),SEEK_SET); _lseek(fh,sizeof(BITMAPFILEHEADER),SEEK_SET);
if (sizeof(BITMAPINFOHEADER) != _lread (fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER))) if (sizeof(BITMAPINFOHEADER) != _read (fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)))
goto ErrExit; goto ErrExit;
} }
@ -468,14 +403,14 @@ BOOL ReadDIB(LPSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
/* read the color table */ /* read the color table */
if (!bCoreHead) if (!bCoreHead)
_lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD)); _read(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD));
else else
{ {
signed int i; signed int i;
RGBQUAD FAR *pQuad; RGBQUAD FAR *pQuad;
RGBTRIPLE FAR *pTriple; RGBTRIPLE FAR *pTriple;
_lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBTRIPLE)); _read(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBTRIPLE));
pQuad = (RGBQUAD FAR *)((LPSTR)lpbi + lpbi->biSize); pQuad = (RGBQUAD FAR *)((LPSTR)lpbi + lpbi->biSize);
pTriple = (RGBTRIPLE FAR *) pQuad; pTriple = (RGBTRIPLE FAR *) pQuad;
@ -493,10 +428,10 @@ BOOL ReadDIB(LPSTR lpFileName, HBITMAP *bitmap, HPALETTE *palette)
if (bf.bfOffBits != 0L) if (bf.bfOffBits != 0L)
{ {
_llseek(fh,bf.bfOffBits,SEEK_SET); _lseek(fh,bf.bfOffBits,SEEK_SET);
} }
got = lread(fh, (LPSTR)lpbi + offBits, lpbi->biSizeImage); got = _read(fh, (LPSTR)lpbi + offBits, lpbi->biSizeImage);
if (lpbi->biSizeImage == got) if (lpbi->biSizeImage == got)
{ {
@ -528,146 +463,6 @@ ErrExit2:
return(result); return(result);
} }
/****************************************************************************
*
* FUNCTION : ReadDIB2(hWnd)
*
* PURPOSE : Reads a DIB from a file, obtains a handle to its
* BITMAPINFO struct. and loads the DIB. Returns the DIB handle.
* Experimental code hacked about by Julian Smart.
*
****************************************************************************/
HANDLE ReadDIB2(LPSTR lpFileName)
{
int fh;
LPBITMAPINFOHEADER lpbi;
OFSTRUCT of;
BITMAPFILEHEADER bf;
DWORD nNumColors;
BOOL result = FALSE;
char str[128];
DWORD offBits;
HDC hDC;
BOOL bCoreHead = FALSE;
HANDLE hDIB = 0;
/* Open the file and get a handle to it's BITMAPINFO */
fh = OpenFile (lpFileName, &of, OF_READ);
if (fh == -1) {
// wsprintf(str,"Can't open file '%ls'", (LPSTR)lpFileName);
// MessageBox(NULL, str, "Error", MB_ICONSTOP | MB_OK);
return (NULL);
}
hDIB = GlobalAlloc(GHND, (DWORD)(sizeof(BITMAPINFOHEADER) +
256 * sizeof(RGBQUAD)));
if (!hDIB)
return(NULL);
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
/* read the BITMAPFILEHEADER */
if (sizeof (bf) != _lread (fh, (LPSTR)&bf, sizeof (bf)))
goto ErrExit;
if (bf.bfType != 0x4d42) /* 'BM' */
goto ErrExit;
if (sizeof(BITMAPCOREHEADER) != _lread (fh, (LPSTR)lpbi, sizeof(BITMAPCOREHEADER)))
goto ErrExit;
if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
{
lpbi->biSize = sizeof(BITMAPINFOHEADER);
lpbi->biBitCount = ((LPBITMAPCOREHEADER)lpbi)->bcBitCount;
lpbi->biPlanes = ((LPBITMAPCOREHEADER)lpbi)->bcPlanes;
lpbi->biHeight = ((LPBITMAPCOREHEADER)lpbi)->bcHeight;
lpbi->biWidth = ((LPBITMAPCOREHEADER)lpbi)->bcWidth;
bCoreHead = TRUE;
}
else
{
// get to the start of the header and read INFOHEADER
_llseek(fh,sizeof(BITMAPFILEHEADER),SEEK_SET);
if (sizeof(BITMAPINFOHEADER) != _lread (fh, (LPSTR)lpbi, sizeof(BITMAPINFOHEADER)))
goto ErrExit;
}
if (!(nNumColors = lpbi->biClrUsed))
{
/* no color table for 24-bit, default size otherwise */
if (lpbi->biBitCount != 24)
nNumColors = 1 << lpbi->biBitCount; /* standard size table */
}
/* fill in some default values if they are zero */
if (lpbi->biClrUsed == 0)
lpbi->biClrUsed = nNumColors;
if (lpbi->biSizeImage == 0)
{
lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3)
* lpbi->biHeight;
}
/* get a proper-sized buffer for header, color table and bits */
GlobalUnlock(hDIB);
hDIB = GlobalReAlloc(hDIB, lpbi->biSize +
nNumColors * sizeof(RGBQUAD) +
lpbi->biSizeImage, 0);
if (!hDIB) /* can't resize buffer for loading */
goto ErrExit2;
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDIB);
/* read the color table */
if (!bCoreHead)
_lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBQUAD));
else
{
signed int i;
RGBQUAD FAR *pQuad;
RGBTRIPLE FAR *pTriple;
_lread(fh, (LPSTR)(lpbi) + lpbi->biSize, nNumColors * sizeof(RGBTRIPLE));
pQuad = (RGBQUAD FAR *)((LPSTR)lpbi + lpbi->biSize);
pTriple = (RGBTRIPLE FAR *) pQuad;
for (i = nNumColors - 1; i >= 0; i--)
{
pQuad[i].rgbRed = pTriple[i].rgbtRed;
pQuad[i].rgbBlue = pTriple[i].rgbtBlue;
pQuad[i].rgbGreen = pTriple[i].rgbtGreen;
pQuad[i].rgbReserved = 0;
}
}
/* offset to the bits from start of DIB header */
offBits = lpbi->biSize + nNumColors * sizeof(RGBQUAD);
if (bf.bfOffBits != 0L)
{
_llseek(fh,bf.bfOffBits,SEEK_SET);
}
if (lpbi->biSizeImage == lread(fh, (LPSTR)lpbi + offBits, lpbi->biSizeImage))
{
GlobalUnlock(hDIB);
return hDIB;
}
else
{
ErrExit:
GlobalUnlock(hDIB);
ErrExit2:
GlobalFree(hDIB);
}
_lclose(fh);
return 0;
}
/**************************************************************************** /****************************************************************************
* *
* FUNCTION : MakeBitmapAndPalette * FUNCTION : MakeBitmapAndPalette
@ -689,7 +484,7 @@ BOOL NEAR PASCAL MakeBitmapAndPalette(HDC hDC, HANDLE hDIB,
LPBITMAPINFOHEADER lpInfo; LPBITMAPINFOHEADER lpInfo;
BOOL result = FALSE; BOOL result = FALSE;
HBITMAP hBitmap; HBITMAP hBitmap;
HPALETTE hPalette, hOldPal; HPALETTE hPalette;
LPSTR lpBits; LPSTR lpBits;
lpInfo = (LPBITMAPINFOHEADER) GlobalLock(hDIB); lpInfo = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
@ -759,7 +554,7 @@ HPALETTE PASCAL NEAR MakeDIBPalette(LPBITMAPINFOHEADER lpInfo)
return(FALSE); return(FALSE);
npPal->palVersion = 0x300; npPal->palVersion = 0x300;
npPal->palNumEntries = lpInfo->biClrUsed; npPal->palNumEntries = (WORD)lpInfo->biClrUsed;
/* get pointer to the color table */ /* get pointer to the color table */
lpRGB = (RGBQUAD FAR *)((LPSTR)lpInfo + lpInfo->biSize); lpRGB = (RGBQUAD FAR *)((LPSTR)lpInfo + lpInfo->biSize);