cs Windows: fill in GUI mode for GRacket
Still need to create console on demand.
This commit is contained in:
parent
a24c6fe4f9
commit
b5084977c0
2
Makefile
2
Makefile
|
@ -385,7 +385,7 @@ win32-racket-then-cs:
|
||||||
$(MAKE) win32-base PKGS="" $(WIN32_CS_COPY_ARGS_EXCEPT_PKGS_SUT) WIN32_BUILD_LEVEL="$(WIN32_BUILD_LEVEL)"
|
$(MAKE) win32-base PKGS="" $(WIN32_CS_COPY_ARGS_EXCEPT_PKGS_SUT) WIN32_BUILD_LEVEL="$(WIN32_BUILD_LEVEL)"
|
||||||
$(MAKE) win32-just-cs RACKET=$(WIN32_PLAIN_RACKET) $(WIN32_CS_COPY_ARGS_BOOT)
|
$(MAKE) win32-just-cs RACKET=$(WIN32_PLAIN_RACKET) $(WIN32_CS_COPY_ARGS_BOOT)
|
||||||
|
|
||||||
CSBUILD_ARGUMENTS = --scheme-dir "$(SCHEME_SRC)" \
|
CSBUILD_ARGUMENTS = --scheme-dir "$(SCHEME_SRC)" --pull \
|
||||||
--racketcs-suffix "$(RACKETCS_SUFFIX)" \
|
--racketcs-suffix "$(RACKETCS_SUFFIX)" \
|
||||||
--boot-mode "$(SETUP_BOOT_MODE)" \
|
--boot-mode "$(SETUP_BOOT_MODE)" \
|
||||||
--extra-repos-base "$(EXTRA_REPOS_BASE)" \
|
--extra-repos-base "$(EXTRA_REPOS_BASE)" \
|
||||||
|
|
|
@ -19,7 +19,7 @@ RUMBLE_UNSAFE_COMP = --unsafe
|
||||||
COMPILE_FILE = $(SCHEME) --script compile-file.ss $(UNSAFE_COMP) $(COMPRESS_COMP) $(DEBUG_COMP) --dest "$(BUILDDIR)"
|
COMPILE_FILE = $(SCHEME) --script compile-file.ss $(UNSAFE_COMP) $(COMPRESS_COMP) $(DEBUG_COMP) --dest "$(BUILDDIR)"
|
||||||
COMPILE_FILE_DEPS = compile-file.ss include.ss place-register.ss
|
COMPILE_FILE_DEPS = compile-file.ss include.ss place-register.ss
|
||||||
|
|
||||||
RACKET_SETUP_ARGS = ../../bin/racket ../collects ../etc 0 true false
|
RACKET_SETUP_ARGS = ../../bin/racket ../collects ../etc 0 true false 0 ""
|
||||||
|
|
||||||
PRIMITIVES_TABLES = primitive/kernel.ss primitive/unsafe.ss primitive/flfxnum.ss \
|
PRIMITIVES_TABLES = primitive/kernel.ss primitive/unsafe.ss primitive/flfxnum.ss \
|
||||||
primitive/paramz.ss primitive/extfl.ss primitive/network.ss \
|
primitive/paramz.ss primitive/extfl.ss primitive/network.ss \
|
||||||
|
|
|
@ -88,7 +88,8 @@ void racket_boot(int argc, char **argv, char *self,
|
||||||
char *boot_exe, long segment_offset,
|
char *boot_exe, long segment_offset,
|
||||||
char *coldir, char *configdir,
|
char *coldir, char *configdir,
|
||||||
int pos1, int pos2, int pos3,
|
int pos1, int pos2, int pos3,
|
||||||
int cs_compiled_subdir, int is_gui)
|
int cs_compiled_subdir, int is_gui,
|
||||||
|
int wm_is_gracket, const char *gracket_guid)
|
||||||
/* exe argument already stripped from argv */
|
/* exe argument already stripped from argv */
|
||||||
{
|
{
|
||||||
#if !defined(RACKET_USE_FRAMEWORK) || !defined(RACKET_AS_BOOT)
|
#if !defined(RACKET_USE_FRAMEWORK) || !defined(RACKET_AS_BOOT)
|
||||||
|
@ -134,11 +135,14 @@ void racket_boot(int argc, char **argv, char *self,
|
||||||
{
|
{
|
||||||
ptr l = Snil;
|
ptr l = Snil;
|
||||||
int i;
|
int i;
|
||||||
char segment_offset_s[32];
|
char segment_offset_s[32], wm_is_gracket_s[32];
|
||||||
|
|
||||||
for (i = argc; i--; ) {
|
for (i = argc; i--; ) {
|
||||||
l = Scons(Sbytevector(argv[i]), l);
|
l = Scons(Sbytevector(argv[i]), l);
|
||||||
}
|
}
|
||||||
|
l = Scons(Sbytevector(gracket_guid), l);
|
||||||
|
sprintf(wm_is_gracket_s, "%ld", wm_is_gracket);
|
||||||
|
l = Scons(Sbytevector(wm_is_gracket_s), l);
|
||||||
l = Scons(Sbytevector(is_gui ? "true" : "false"), l);
|
l = Scons(Sbytevector(is_gui ? "true" : "false"), l);
|
||||||
l = Scons(Sbytevector(cs_compiled_subdir ? "true" : "false"), l);
|
l = Scons(Sbytevector(cs_compiled_subdir ? "true" : "false"), l);
|
||||||
sprintf(segment_offset_s, "%ld", segment_offset);
|
sprintf(segment_offset_s, "%ld", segment_offset);
|
||||||
|
|
|
@ -2,10 +2,12 @@ BOOT_EXTERN void racket_boot(int argc, char **argv, char *self,
|
||||||
char *boot_exe, long segment_offset,
|
char *boot_exe, long segment_offset,
|
||||||
char *coldir, char *configdir,
|
char *coldir, char *configdir,
|
||||||
int pos1, int pos2, int pos3,
|
int pos1, int pos2, int pos3,
|
||||||
int cs_compiled_subdir, int is_gui);
|
int cs_compiled_subdir, int is_gui,
|
||||||
|
int wm_is_gracket, const char *gracket_guid);
|
||||||
|
|
||||||
typedef void (*racket_boot_t)(int argc, char **argv, char *self,
|
typedef void (*racket_boot_t)(int argc, char **argv, char *self,
|
||||||
char* boot_exe, long segment_offset,
|
char* boot_exe, long segment_offset,
|
||||||
char *coldir, char *configdir,
|
char *coldir, char *configdir,
|
||||||
int pos1, int pos2, int pos3,
|
int pos1, int pos2, int pos3,
|
||||||
int cs_compiled_subdir, int is_gui);
|
int cs_compiled_subdir, int is_gui,
|
||||||
|
int wm_is_gracket, const char *gracket_guid);
|
||||||
|
|
|
@ -9,6 +9,17 @@ static void pre_filter_cmdline_arguments(int *argc, char ***argv);
|
||||||
# ifndef INITIAL_COLLECTS_DIRECTORY
|
# ifndef INITIAL_COLLECTS_DIRECTORY
|
||||||
# define INITIAL_COLLECTS_DIRECTORY "../collects"
|
# define INITIAL_COLLECTS_DIRECTORY "../collects"
|
||||||
# endif
|
# endif
|
||||||
|
# ifndef INITIAL_CONFIG_DIRECTORY
|
||||||
|
# define INITIAL_CONFIG_DIRECTORY "../etc"
|
||||||
|
# endif
|
||||||
|
|
||||||
|
/* Hack: overwrite "y" with "n" in binary to disable checking for another
|
||||||
|
instance of the same app. */
|
||||||
|
char *check_for_another = "yes, please check for another";
|
||||||
|
|
||||||
|
# include <Windows.h>
|
||||||
|
# include "../start/win_single.inc"
|
||||||
|
# define CHECK_SINGLE_INSTANCE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "main.c"
|
#include "main.c"
|
||||||
|
|
|
@ -125,9 +125,8 @@ static long find_boot_section(char *me)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
static char *path_to_utf8(wchar_t *p)
|
static char *string_to_utf8(wchar_t *p)
|
||||||
{
|
{
|
||||||
char *r;
|
char *r;
|
||||||
int len;
|
int len;
|
||||||
|
@ -141,7 +140,7 @@ static char *path_to_utf8(wchar_t *p)
|
||||||
|
|
||||||
static char *get_self_path()
|
static char *get_self_path()
|
||||||
{
|
{
|
||||||
return path_to_utf8(get_self_executable_path());
|
return string_to_utf8(get_self_executable_path());
|
||||||
}
|
}
|
||||||
|
|
||||||
static int scheme_utf8_encode(unsigned int *path, int zero_offset, int len,
|
static int scheme_utf8_encode(unsigned int *path, int zero_offset, int len,
|
||||||
|
@ -149,6 +148,8 @@ static int scheme_utf8_encode(unsigned int *path, int zero_offset, int len,
|
||||||
{
|
{
|
||||||
return WideCharToMultiByte(CP_UTF8, 0, (wchar_t *)path, len, dest, dest_len, NULL, NULL);
|
return WideCharToMultiByte(CP_UTF8, 0, (wchar_t *)path, len, dest, dest_len, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# include "../start/parse_cmdl.inc"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NO_GET_SEGMENT_OFFSET
|
#ifdef NO_GET_SEGMENT_OFFSET
|
||||||
|
@ -162,7 +163,9 @@ static long get_segment_offset()
|
||||||
# define do_pre_filter_cmdline_arguments(argc, argv) /* empty */
|
# define do_pre_filter_cmdline_arguments(argc, argv) /* empty */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
static int bytes_main(int argc, char **argv,
|
||||||
|
/* for Windows GUI mode */
|
||||||
|
int wm_is_gracket, const char *gracket_guid)
|
||||||
{
|
{
|
||||||
char *self, *boot_exe, *prog = argv[0], *sprog = NULL;
|
char *self, *boot_exe, *prog = argv[0], *sprog = NULL;
|
||||||
int pos1, pos2, pos3;
|
int pos1, pos2, pos3;
|
||||||
|
@ -176,8 +179,10 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
do_pre_filter_cmdline_arguments(&argc, &argv);
|
do_pre_filter_cmdline_arguments(&argc, &argv);
|
||||||
|
|
||||||
argc--;
|
if (argc) {
|
||||||
argv++;
|
argc--;
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
|
||||||
extract_built_in_arguments(&prog, &sprog, &argc, &argv);
|
extract_built_in_arguments(&prog, &sprog, &argc, &argv);
|
||||||
segment_offset = get_segment_offset();
|
segment_offset = get_segment_offset();
|
||||||
|
@ -187,7 +192,7 @@ int main(int argc, char **argv)
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
# define racket_boot racket_boot_p
|
# define racket_boot racket_boot_p
|
||||||
dll_path = load_delayed_dll_x(NULL, "libracketcsxxxxxxx.dll", &dll);
|
dll_path = load_delayed_dll_x(NULL, "libracketcsxxxxxxx.dll", &dll);
|
||||||
boot_exe = path_to_utf8(dll_path);
|
boot_exe = string_to_utf8(dll_path);
|
||||||
racket_boot_p = (racket_boot_t)GetProcAddress(dll, "racket_boot");
|
racket_boot_p = (racket_boot_t)GetProcAddress(dll, "racket_boot");
|
||||||
#else
|
#else
|
||||||
boot_exe = self;
|
boot_exe = self;
|
||||||
|
@ -213,7 +218,44 @@ int main(int argc, char **argv)
|
||||||
boot_exe, segment_offset,
|
boot_exe, segment_offset,
|
||||||
extract_coldir(), extract_configdir(),
|
extract_coldir(), extract_configdir(),
|
||||||
pos1, pos2, pos3,
|
pos1, pos2, pos3,
|
||||||
CS_COMPILED_SUBDIR, RACKET_IS_GUI);
|
CS_COMPILED_SUBDIR, RACKET_IS_GUI,
|
||||||
|
wm_is_gracket, gracket_guid);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(WIN32) && defined(CHECK_SINGLE_INSTANCE)
|
||||||
|
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR ignored, int nCmdShow)
|
||||||
|
{
|
||||||
|
int argc;
|
||||||
|
char **argv;
|
||||||
|
char *normalized_path;
|
||||||
|
int wm = 0;
|
||||||
|
const char *guid = "";
|
||||||
|
|
||||||
|
argv = cmdline_to_argv(&argc, &normalized_path);
|
||||||
|
|
||||||
|
if (CheckSingleInstance(normalized_path, argv))
|
||||||
|
return 0;
|
||||||
|
wm = wm_is_gracket;
|
||||||
|
guid = GRACKET_GUID;
|
||||||
|
|
||||||
|
return bytes_main(argc, argv, wm, guid);
|
||||||
|
}
|
||||||
|
#elif defined(WIN32)
|
||||||
|
int wmain(int argc, wchar_t **wargv)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
char **argv = malloc(argc * sizeof(char*));
|
||||||
|
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
argv[i] = string_to_utf8(wargv[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return bytes_main(argc, argv, 0, "");
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
return bytes_main(argc, argv, 0, "");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -55,9 +55,14 @@
|
||||||
s))
|
s))
|
||||||
the-command-line-arguments/maybe-bytes))
|
the-command-line-arguments/maybe-bytes))
|
||||||
|
|
||||||
|
(define builtin-argc 8)
|
||||||
(seq
|
(seq
|
||||||
(unless (>= (length the-command-line-arguments) 6)
|
(unless (>= (length the-command-line-arguments) builtin-argc)
|
||||||
(error 'racket "expected `self`, `collects`, and `libs` paths plus `segment-offset`, `cs-compiled-subdir?`, and `is-gui?` to start"))
|
(error 'racket (string-append
|
||||||
|
"expected `self`, `collects`, and `libs` paths"
|
||||||
|
" plus `segment-offset`, `cs-compiled-subdir?`, `is-gui?`,"
|
||||||
|
" `wm-is-gracket`, and `gracket-guid`"
|
||||||
|
" to start")))
|
||||||
(set-exec-file! (path->complete-path (car the-command-line-arguments))))
|
(set-exec-file! (path->complete-path (car the-command-line-arguments))))
|
||||||
(define init-collects-dir (let ([s (cadr the-command-line-arguments)])
|
(define init-collects-dir (let ([s (cadr the-command-line-arguments)])
|
||||||
(if (equal? s "") 'disable (string->path s))))
|
(if (equal? s "") 'disable (string->path s))))
|
||||||
|
@ -66,10 +71,18 @@
|
||||||
(define segment-offset (#%string->number (list-ref the-command-line-arguments 3)))
|
(define segment-offset (#%string->number (list-ref the-command-line-arguments 3)))
|
||||||
(define cs-compiled-subdir? (string=? "true" (list-ref the-command-line-arguments 4)))
|
(define cs-compiled-subdir? (string=? "true" (list-ref the-command-line-arguments 4)))
|
||||||
(define gracket? (string=? "true" (list-ref the-command-line-arguments 5)))
|
(define gracket? (string=? "true" (list-ref the-command-line-arguments 5)))
|
||||||
|
(define wm-is-gracket (string->number (list-ref the-command-line-arguments 6)))
|
||||||
|
(define gracket-guid (list-ref the-command-line-arguments 7))
|
||||||
|
|
||||||
(seq
|
(seq
|
||||||
(when (foreign-entry? "racket_exit")
|
(when (foreign-entry? "racket_exit")
|
||||||
(#%exit-handler (foreign-procedure "racket_exit" (int) void))))
|
(#%exit-handler (foreign-procedure "racket_exit" (int) void)))
|
||||||
|
|
||||||
|
;; For Windows:
|
||||||
|
(unsafe-register-process-global (string->bytes/utf-8 "PLT_WM_IS_GRACKET")
|
||||||
|
(ptr-add #f wm-is-gracket))
|
||||||
|
(unsafe-register-process-global (string->bytes/utf-8 "PLT_GRACKET_GUID")
|
||||||
|
(bytes-append (string->bytes/utf-8 gracket-guid) #vu8(0))))
|
||||||
|
|
||||||
(define compiled-file-paths
|
(define compiled-file-paths
|
||||||
(list (string->path (cond
|
(list (string->path (cond
|
||||||
|
@ -227,7 +240,7 @@
|
||||||
(define remaining-command-line-arguments '#())
|
(define remaining-command-line-arguments '#())
|
||||||
|
|
||||||
(seq
|
(seq
|
||||||
(let flags-loop ([args (list-tail the-command-line-arguments 6)]
|
(let flags-loop ([args (list-tail the-command-line-arguments builtin-argc)]
|
||||||
[saw (hasheq)])
|
[saw (hasheq)])
|
||||||
;; An element of `args` can become `(cons _arg _within-arg)`
|
;; An element of `args` can become `(cons _arg _within-arg)`
|
||||||
;; due to splitting multiple flags with a single "-"
|
;; due to splitting multiple flags with a single "-"
|
||||||
|
|
|
@ -412,175 +412,7 @@ static void MrEdExit(int v)
|
||||||
START_XFORM_SKIP;
|
START_XFORM_SKIP;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* ---------------------------------------- */
|
# include "../start/win_single.inc"
|
||||||
/* single-instance detection */
|
|
||||||
/* ---------------------------------------- */
|
|
||||||
|
|
||||||
static char *CreateUniqueName()
|
|
||||||
{
|
|
||||||
char desktop[MAX_PATH], session[32], *together;
|
|
||||||
int dlen, slen;
|
|
||||||
|
|
||||||
{
|
|
||||||
// Name should be desktop unique, so add current desktop name
|
|
||||||
HDESK hDesk;
|
|
||||||
ULONG cchDesk = MAX_PATH - 1;
|
|
||||||
|
|
||||||
hDesk = GetThreadDesktop(GetCurrentThreadId());
|
|
||||||
|
|
||||||
if (!GetUserObjectInformation( hDesk, UOI_NAME, desktop, cchDesk, &cchDesk))
|
|
||||||
desktop[0] = 0;
|
|
||||||
else
|
|
||||||
desktop[MAX_PATH - 1] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Name should be session unique, so add current session id
|
|
||||||
HANDLE hToken = NULL;
|
|
||||||
// Try to open the token (fails on Win9x) and check necessary buffer size
|
|
||||||
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
|
|
||||||
DWORD cbBytes = 0;
|
|
||||||
|
|
||||||
if(!GetTokenInformation( hToken, TokenStatistics, NULL, cbBytes, &cbBytes )
|
|
||||||
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
|
||||||
PTOKEN_STATISTICS pTS;
|
|
||||||
|
|
||||||
pTS = (PTOKEN_STATISTICS)malloc(cbBytes);
|
|
||||||
|
|
||||||
if(GetTokenInformation(hToken, TokenStatistics, (LPVOID)pTS, cbBytes, &cbBytes)) {
|
|
||||||
sprintf(session, "-%08x%08x-",
|
|
||||||
pTS->AuthenticationId.HighPart,
|
|
||||||
pTS->AuthenticationId.LowPart);
|
|
||||||
} else
|
|
||||||
session[0] = 0;
|
|
||||||
free(pTS);
|
|
||||||
} else {
|
|
||||||
session[0] = 0;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
session[0] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dlen = strlen(desktop);
|
|
||||||
slen = strlen(session);
|
|
||||||
together = (char *)malloc(slen + dlen + 1);
|
|
||||||
memcpy(together, desktop, dlen);
|
|
||||||
memcpy(together + dlen, session, slen);
|
|
||||||
together[dlen + slen] = 0;
|
|
||||||
|
|
||||||
return together;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GRACKET_GUID "B2261834-D535-44dd-8511-A26FC8F97DD0"
|
|
||||||
|
|
||||||
static int wm_is_gracket;
|
|
||||||
|
|
||||||
static BOOL CALLBACK CheckWindow(HWND wnd, LPARAM param)
|
|
||||||
{
|
|
||||||
int i, len, gl;
|
|
||||||
DWORD w;
|
|
||||||
char **argv, *v;
|
|
||||||
COPYDATASTRUCT cd;
|
|
||||||
DWORD_PTR result;
|
|
||||||
LRESULT ok;
|
|
||||||
|
|
||||||
ok = SendMessageTimeout(wnd, wm_is_gracket,
|
|
||||||
0, 0,
|
|
||||||
SMTO_BLOCK |
|
|
||||||
SMTO_ABORTIFHUNG,
|
|
||||||
200,
|
|
||||||
&result);
|
|
||||||
|
|
||||||
printf("try %p result %d\n", wnd, result);
|
|
||||||
|
|
||||||
if (ok == 0)
|
|
||||||
return TRUE; /* ignore and continue */
|
|
||||||
if ((intptr_t)result == 79) {
|
|
||||||
/* found it */
|
|
||||||
} else
|
|
||||||
return TRUE; /* continue search */
|
|
||||||
|
|
||||||
/* wnd is owned by another instance of this application */
|
|
||||||
|
|
||||||
SetForegroundWindow(wnd);
|
|
||||||
if (IsIconic(wnd))
|
|
||||||
ShowWindow(wnd, SW_RESTORE);
|
|
||||||
|
|
||||||
argv = (char **)param;
|
|
||||||
|
|
||||||
len = gl = strlen(GRACKET_GUID);
|
|
||||||
len += 4 + sizeof(DWORD);
|
|
||||||
for (i = 1; argv[i]; i++) {
|
|
||||||
len += sizeof(DWORD) + strlen(argv[i]);
|
|
||||||
}
|
|
||||||
w = i - 1;
|
|
||||||
|
|
||||||
v = (char *)malloc(len);
|
|
||||||
memcpy(v, GRACKET_GUID, gl);
|
|
||||||
memcpy(v + gl, "OPEN", 4);
|
|
||||||
memcpy(v + gl + 4, &w, sizeof(DWORD));
|
|
||||||
len = gl + 4 + sizeof(DWORD);
|
|
||||||
for (i = 1; argv[i]; i++) {
|
|
||||||
w = strlen(argv[i]);
|
|
||||||
memcpy(v + len, &w, sizeof(DWORD));
|
|
||||||
len += sizeof(DWORD);
|
|
||||||
memcpy(v + len, argv[i], w);
|
|
||||||
len += w;
|
|
||||||
}
|
|
||||||
|
|
||||||
cd.dwData = 79;
|
|
||||||
cd.cbData = len;
|
|
||||||
cd.lpData = v;
|
|
||||||
|
|
||||||
SendMessage(wnd, WM_COPYDATA, (WPARAM)wnd, (LPARAM)&cd);
|
|
||||||
|
|
||||||
free(v);
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int CheckSingleInstance(char *normalized_path, char **argv)
|
|
||||||
{
|
|
||||||
/* Check for an existing instance: */
|
|
||||||
if (check_for_another[0] != 'n') {
|
|
||||||
int alreadyrunning;
|
|
||||||
HANDLE mutex;
|
|
||||||
int j, l, i;
|
|
||||||
char *a, *b;
|
|
||||||
|
|
||||||
/* This mutex creation synchronizes multiple instances of
|
|
||||||
the application that may have been started. */
|
|
||||||
j = strlen(normalized_path);
|
|
||||||
|
|
||||||
b = CreateUniqueName();
|
|
||||||
l = strlen(b);
|
|
||||||
a = (char *)malloc(j + l + 50);
|
|
||||||
memcpy(a, normalized_path, j);
|
|
||||||
for (i = 0; i < j; i++) {
|
|
||||||
/* backslashes are not allowed in mutex names */
|
|
||||||
if (a[i] == '\\') a[i] = '/';
|
|
||||||
}
|
|
||||||
memcpy(a + j, b, l);
|
|
||||||
memcpy(a + j + l, "GRacket-" GRACKET_GUID, strlen(GRACKET_GUID) + 9);
|
|
||||||
mutex = CreateMutex(NULL, FALSE, a);
|
|
||||||
alreadyrunning = (GetLastError() == ERROR_ALREADY_EXISTS ||
|
|
||||||
GetLastError() == ERROR_ACCESS_DENIED);
|
|
||||||
/* The call fails with ERROR_ACCESS_DENIED if the Mutex was
|
|
||||||
created in a different users session because of passing
|
|
||||||
NULL for the SECURITY_ATTRIBUTES on Mutex creation. */
|
|
||||||
wm_is_gracket = RegisterWindowMessage(a);
|
|
||||||
free(a);
|
|
||||||
|
|
||||||
if (alreadyrunning) {
|
|
||||||
/* If another instance has been started, try to find it. */
|
|
||||||
if (!EnumWindows((WNDENUMPROC)CheckWindow, (LPARAM)argv)) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void pre_filter_cmdline_arguments(int *argc, char ***argv)
|
static void pre_filter_cmdline_arguments(int *argc, char ***argv)
|
||||||
{
|
{
|
||||||
|
|
|
@ -123,7 +123,7 @@ int IsFlag(LPCTSTR cmd, LPCTSTR flag)
|
||||||
|
|
||||||
#define ASSUME_ASCII_COMMAND_LINE
|
#define ASSUME_ASCII_COMMAND_LINE
|
||||||
#define GC_CAN_IGNORE
|
#define GC_CAN_IGNORE
|
||||||
#include "../racket/parse_cmdl.inc"
|
#include "../start/parse_cmdl.inc"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
|
|
@ -272,8 +272,8 @@ DEF_CONFIG_DIR = -DINITIAL_CONFIG_DIRECTORY='"'"`cd $(srcdir)/../..; @PWD@`/etc"
|
||||||
DEF_C_DIRS = $(DEF_COLLECTS_DIR) $(DEF_CONFIG_DIR)
|
DEF_C_DIRS = $(DEF_COLLECTS_DIR) $(DEF_CONFIG_DIR)
|
||||||
|
|
||||||
MAIN_HEADER_DEPS = $(srcdir)/include/scheme.h $(srcdir)/include/schthread.h $(srcdir)/sconfig.h \
|
MAIN_HEADER_DEPS = $(srcdir)/include/scheme.h $(srcdir)/include/schthread.h $(srcdir)/sconfig.h \
|
||||||
$(srcdir)/src/stypes.h $(srcdir)/cmdline.inc $(srcdir)/parse_cmdl.inc \
|
$(srcdir)/src/stypes.h $(srcdir)/cmdline.inc $(srcdir)/../start/parse_cmdl.inc \
|
||||||
$(srcdir)/../start/config.inc $(srcdir)/../start/delayed.inc $(srcdir)/parse_cmdl.inc \
|
$(srcdir)/../start/config.inc $(srcdir)/../start/delayed.inc \
|
||||||
$(srcdir)/../start/embedded_dll.inc
|
$(srcdir)/../start/embedded_dll.inc
|
||||||
|
|
||||||
main.@LTO@: $(srcdir)/main.c $(MAIN_HEADER_DEPS)
|
main.@LTO@: $(srcdir)/main.c $(MAIN_HEADER_DEPS)
|
||||||
|
|
|
@ -306,7 +306,7 @@ START_XFORM_SKIP;
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(WINMAIN_ALREADY)
|
#if defined(__MINGW32__) || defined(WINMAIN_ALREADY)
|
||||||
# include "parse_cmdl.inc"
|
# include "../start/parse_cmdl.inc"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef DOS_FILE_SYSTEM
|
#ifdef DOS_FILE_SYSTEM
|
||||||
|
|
|
@ -86,6 +86,9 @@ static wchar_t *load_delayed_dll_x(HINSTANCE me, const char *lib, HMODULE *_load
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Should not get here */
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_delayed_dll(HINSTANCE me, const char *lib)
|
static void load_delayed_dll(HINSTANCE me, const char *lib)
|
||||||
|
|
|
@ -38,7 +38,7 @@ static void parse_embedded_dlls()
|
||||||
{
|
{
|
||||||
long rsrc_pos;
|
long rsrc_pos;
|
||||||
|
|
||||||
rsrc_pos = find_resource_offset(258);
|
rsrc_pos = find_resource_offset(get_self_executable_path(), 258);
|
||||||
if (rsrc_pos) {
|
if (rsrc_pos) {
|
||||||
HANDLE fd = open_self();
|
HANDLE fd = open_self();
|
||||||
|
|
||||||
|
|
169
racket/src/start/win_single.inc
Normal file
169
racket/src/start/win_single.inc
Normal file
|
@ -0,0 +1,169 @@
|
||||||
|
/* ---------------------------------------- */
|
||||||
|
/* single-instance detection */
|
||||||
|
/* ---------------------------------------- */
|
||||||
|
|
||||||
|
static char *CreateUniqueName()
|
||||||
|
{
|
||||||
|
char desktop[MAX_PATH], session[32], *together;
|
||||||
|
int dlen, slen;
|
||||||
|
|
||||||
|
{
|
||||||
|
// Name should be desktop unique, so add current desktop name
|
||||||
|
HDESK hDesk;
|
||||||
|
ULONG cchDesk = MAX_PATH - 1;
|
||||||
|
|
||||||
|
hDesk = GetThreadDesktop(GetCurrentThreadId());
|
||||||
|
|
||||||
|
if (!GetUserObjectInformation( hDesk, UOI_NAME, desktop, cchDesk, &cchDesk))
|
||||||
|
desktop[0] = 0;
|
||||||
|
else
|
||||||
|
desktop[MAX_PATH - 1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Name should be session unique, so add current session id
|
||||||
|
HANDLE hToken = NULL;
|
||||||
|
// Try to open the token (fails on Win9x) and check necessary buffer size
|
||||||
|
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
|
||||||
|
DWORD cbBytes = 0;
|
||||||
|
|
||||||
|
if(!GetTokenInformation( hToken, TokenStatistics, NULL, cbBytes, &cbBytes )
|
||||||
|
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
|
||||||
|
PTOKEN_STATISTICS pTS;
|
||||||
|
|
||||||
|
pTS = (PTOKEN_STATISTICS)malloc(cbBytes);
|
||||||
|
|
||||||
|
if(GetTokenInformation(hToken, TokenStatistics, (LPVOID)pTS, cbBytes, &cbBytes)) {
|
||||||
|
sprintf(session, "-%08x%08x-",
|
||||||
|
pTS->AuthenticationId.HighPart,
|
||||||
|
pTS->AuthenticationId.LowPart);
|
||||||
|
} else
|
||||||
|
session[0] = 0;
|
||||||
|
free(pTS);
|
||||||
|
} else {
|
||||||
|
session[0] = 0;
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
session[0] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
dlen = strlen(desktop);
|
||||||
|
slen = strlen(session);
|
||||||
|
together = (char *)malloc(slen + dlen + 1);
|
||||||
|
memcpy(together, desktop, dlen);
|
||||||
|
memcpy(together + dlen, session, slen);
|
||||||
|
together[dlen + slen] = 0;
|
||||||
|
|
||||||
|
return together;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GRACKET_GUID "B2261834-D535-44dd-8511-A26FC8F97DD0"
|
||||||
|
|
||||||
|
static int wm_is_gracket;
|
||||||
|
|
||||||
|
static BOOL CALLBACK CheckWindow(HWND wnd, LPARAM param)
|
||||||
|
{
|
||||||
|
int i, len, gl;
|
||||||
|
DWORD w;
|
||||||
|
char **argv, *v;
|
||||||
|
COPYDATASTRUCT cd;
|
||||||
|
DWORD_PTR result;
|
||||||
|
LRESULT ok;
|
||||||
|
|
||||||
|
ok = SendMessageTimeout(wnd, wm_is_gracket,
|
||||||
|
0, 0,
|
||||||
|
SMTO_BLOCK |
|
||||||
|
SMTO_ABORTIFHUNG,
|
||||||
|
200,
|
||||||
|
&result);
|
||||||
|
|
||||||
|
printf("try %p result %d\n", wnd, result);
|
||||||
|
|
||||||
|
if (ok == 0)
|
||||||
|
return TRUE; /* ignore and continue */
|
||||||
|
if ((intptr_t)result == 79) {
|
||||||
|
/* found it */
|
||||||
|
} else
|
||||||
|
return TRUE; /* continue search */
|
||||||
|
|
||||||
|
/* wnd is owned by another instance of this application */
|
||||||
|
|
||||||
|
SetForegroundWindow(wnd);
|
||||||
|
if (IsIconic(wnd))
|
||||||
|
ShowWindow(wnd, SW_RESTORE);
|
||||||
|
|
||||||
|
argv = (char **)param;
|
||||||
|
|
||||||
|
len = gl = strlen(GRACKET_GUID);
|
||||||
|
len += 4 + sizeof(DWORD);
|
||||||
|
for (i = 1; argv[i]; i++) {
|
||||||
|
len += sizeof(DWORD) + strlen(argv[i]);
|
||||||
|
}
|
||||||
|
w = i - 1;
|
||||||
|
|
||||||
|
v = (char *)malloc(len);
|
||||||
|
memcpy(v, GRACKET_GUID, gl);
|
||||||
|
memcpy(v + gl, "OPEN", 4);
|
||||||
|
memcpy(v + gl + 4, &w, sizeof(DWORD));
|
||||||
|
len = gl + 4 + sizeof(DWORD);
|
||||||
|
for (i = 1; argv[i]; i++) {
|
||||||
|
w = strlen(argv[i]);
|
||||||
|
memcpy(v + len, &w, sizeof(DWORD));
|
||||||
|
len += sizeof(DWORD);
|
||||||
|
memcpy(v + len, argv[i], w);
|
||||||
|
len += w;
|
||||||
|
}
|
||||||
|
|
||||||
|
cd.dwData = 79;
|
||||||
|
cd.cbData = len;
|
||||||
|
cd.lpData = v;
|
||||||
|
|
||||||
|
SendMessage(wnd, WM_COPYDATA, (WPARAM)wnd, (LPARAM)&cd);
|
||||||
|
|
||||||
|
free(v);
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CheckSingleInstance(char *normalized_path, char **argv)
|
||||||
|
{
|
||||||
|
/* Check for an existing instance: */
|
||||||
|
if (check_for_another[0] != 'n') {
|
||||||
|
int alreadyrunning;
|
||||||
|
HANDLE mutex;
|
||||||
|
int j, l, i;
|
||||||
|
char *a, *b;
|
||||||
|
|
||||||
|
/* This mutex creation synchronizes multiple instances of
|
||||||
|
the application that may have been started. */
|
||||||
|
j = strlen(normalized_path);
|
||||||
|
|
||||||
|
b = CreateUniqueName();
|
||||||
|
l = strlen(b);
|
||||||
|
a = (char *)malloc(j + l + 50);
|
||||||
|
memcpy(a, normalized_path, j);
|
||||||
|
for (i = 0; i < j; i++) {
|
||||||
|
/* backslashes are not allowed in mutex names */
|
||||||
|
if (a[i] == '\\') a[i] = '/';
|
||||||
|
}
|
||||||
|
memcpy(a + j, b, l);
|
||||||
|
memcpy(a + j + l, "GRacket-" GRACKET_GUID, strlen(GRACKET_GUID) + 9);
|
||||||
|
mutex = CreateMutex(NULL, FALSE, a);
|
||||||
|
alreadyrunning = (GetLastError() == ERROR_ALREADY_EXISTS ||
|
||||||
|
GetLastError() == ERROR_ACCESS_DENIED);
|
||||||
|
/* The call fails with ERROR_ACCESS_DENIED if the Mutex was
|
||||||
|
created in a different users session because of passing
|
||||||
|
NULL for the SECURITY_ATTRIBUTES on Mutex creation. */
|
||||||
|
wm_is_gracket = RegisterWindowMessage(a);
|
||||||
|
free(a);
|
||||||
|
|
||||||
|
if (alreadyrunning) {
|
||||||
|
/* If another instance has been started, try to find it. */
|
||||||
|
if (!EnumWindows((WNDENUMPROC)CheckWindow, (LPARAM)argv)) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -14,6 +14,11 @@ DEST = ..\..\build\raw_racketcs.exe
|
||||||
GDEST = ..\..\build\raw_gracketcs.exe
|
GDEST = ..\..\build\raw_gracketcs.exe
|
||||||
CSDIR = ..\..\cs\c
|
CSDIR = ..\..\cs\c
|
||||||
|
|
||||||
|
MAIN_DEPS = ..\..\start\config.inc \
|
||||||
|
..\..\start\parse_cmdl.inc \
|
||||||
|
..\..\start\delayed.inc \
|
||||||
|
..\..\start\win_single.inc
|
||||||
|
|
||||||
FLAGS = /DWIN32
|
FLAGS = /DWIN32
|
||||||
COMP_SUBDIR = /DCS_COMPILED_SUBDIR=1
|
COMP_SUBDIR = /DCS_COMPILED_SUBDIR=1
|
||||||
|
|
||||||
|
@ -25,14 +30,14 @@ $(DEST_DLL): $(CSDIR)\boot.c libracket.res $(RKTIO_LIB)
|
||||||
libracket.res: libracket.rc
|
libracket.res: libracket.rc
|
||||||
rc /l 0x409 /folibracket.res libracket.rc
|
rc /l 0x409 /folibracket.res libracket.rc
|
||||||
|
|
||||||
$(DEST): $(CSDIR)\main.c $(DEST_DLL) racket.res
|
$(DEST): $(CSDIR)\main.c $(MAIN_DEPS) $(DEST_DLL) racket.res
|
||||||
cl /Fe$(DEST) /Ox /MT $(COMP_SUBDIR) $(FLAGS) $(INCS) $(CSDIR)\main.c racket.res $(WIN32_LIBS)
|
cl /Fe$(DEST) /Ox /MT $(COMP_SUBDIR) $(FLAGS) $(INCS) $(CSDIR)\main.c racket.res $(WIN32_LIBS)
|
||||||
|
|
||||||
racket.res: ../racket/racket.rc ../racket/racket.ico
|
racket.res: ../racket/racket.rc ../racket/racket.ico
|
||||||
rc /l 0x409 /foracket.res ../racket/racket.rc
|
rc /l 0x409 /foracket.res ../racket/racket.rc
|
||||||
|
|
||||||
$(GDEST): $(CSDIR)\grmain.c $(DEST_DLL) gracket.res
|
$(GDEST): $(CSDIR)\grmain.c $(CSDIR)\main.c $(MAIN_DEPS) $(DEST_DLL) gracket.res
|
||||||
cl /Fe$(GDEST) /Ox /MT $(COMP_SUBDIR) $(FLAGS) $(INCS) $(CSDIR)\grmain.c gracket.res $(WIN32_LIBS) /subsystem:windows
|
cl /Fe$(GDEST) /Ox /MT $(COMP_SUBDIR) $(FLAGS) $(INCS) $(CSDIR)\grmain.c gracket.res $(WIN32_LIBS)
|
||||||
|
|
||||||
gracket.res: ../gracket/gracket.rc ../gracket/gracket.ico
|
gracket.res: ../gracket/gracket.rc ../gracket/gracket.ico
|
||||||
rc /l 0x409 /fogracket.res ../gracket/gracket.rc
|
rc /l 0x409 /fogracket.res ../gracket/gracket.rc
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
(define scheme-dir-provided? #f)
|
(define scheme-dir-provided? #f)
|
||||||
(define abs-scheme-dir (build-path here 'up "build" "ChezScheme"))
|
(define abs-scheme-dir (build-path here 'up "build" "ChezScheme"))
|
||||||
|
(define pull? #f)
|
||||||
(define machine (if (= 32 (system-type 'word))
|
(define machine (if (= 32 (system-type 'word))
|
||||||
"ti3nt"
|
"ti3nt"
|
||||||
"ta6nt"))
|
"ta6nt"))
|
||||||
|
@ -25,6 +26,8 @@
|
||||||
(unless (equal? dir "")
|
(unless (equal? dir "")
|
||||||
(set! scheme-dir-provided? #t)
|
(set! scheme-dir-provided? #t)
|
||||||
(set! abs-scheme-dir (path->complete-path dir)))]
|
(set! abs-scheme-dir (path->complete-path dir)))]
|
||||||
|
[("--pull") "Use `git pull` on auto-cloned Chez Scheme repo"
|
||||||
|
(set! pull? #t)]
|
||||||
[("--racketcs-suffix") str "Select the suffix for RacketCS"
|
[("--racketcs-suffix") str "Select the suffix for RacketCS"
|
||||||
(set! cs-suffix (string-upcase str))]
|
(set! cs-suffix (string-upcase str))]
|
||||||
[("--boot-mode") mode "Select the mode for Racket bootstrapping"
|
[("--boot-mode") mode "Select the mode for Racket bootstrapping"
|
||||||
|
@ -87,9 +90,10 @@
|
||||||
scheme-dir
|
scheme-dir
|
||||||
git-clone-args)]))
|
git-clone-args)]))
|
||||||
|
|
||||||
(unless scheme-dir-provided?
|
(when pull?
|
||||||
(parameterize ([current-directory scheme-dir])
|
(unless scheme-dir-provided?
|
||||||
(system*! "git" "pull")))
|
(parameterize ([current-directory scheme-dir])
|
||||||
|
(system*! "git" "pull"))))
|
||||||
|
|
||||||
(unless (file-exists? (build-path scheme-dir "zlib" "Makefile"))
|
(unless (file-exists? (build-path scheme-dir "zlib" "Makefile"))
|
||||||
(parameterize ([current-directory scheme-dir])
|
(parameterize ([current-directory scheme-dir])
|
||||||
|
|
Loading…
Reference in New Issue
Block a user