diff options
| author | Keith Packard <keithp@keithp.com> | 2015-03-29 12:08:42 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2015-03-29 12:08:42 -0700 | 
| commit | fe76229618643f0af7eae965e7a8fc6c70410d27 (patch) | |
| tree | 4110da17fc2afb64aafba1591ae260db2996358a | |
| parent | b1b69c8b73cbffb56c688f6a968d144b642cdff2 (diff) | |
icon: Convert windows stub into launcher program
Instead of an empty windows stub that exists only to hold icons, add
useful code that allows it to find and run the related java
application. This also adds more resources to that application to
provide more information to Windows too.
Signed-off-by: Keith Packard <keithp@keithp.com>
| -rw-r--r-- | icon/Makefile.am | 11 | ||||
| -rwxr-xr-x | icon/make-rc | 53 | ||||
| -rw-r--r-- | icon/windows-stub.c | 203 | 
3 files changed, 263 insertions, 4 deletions
| diff --git a/icon/Makefile.am b/icon/Makefile.am index c08e9236..af238ac4 100644 --- a/icon/Makefile.am +++ b/icon/Makefile.am @@ -150,14 +150,21 @@ SUFFIXES=.svg .build .icns .ico .rc .o .exe  	icotool -c -o $@ $(shell for i in $(WIN_RES); do echo $*-$$i.png; done)  .ico.rc: -	echo '101 ICON "$*.ico"' > $@ +	./make-rc "$*" $(VERSION) > $@  MINGCC32=i686-w64-mingw32-gcc  MINGWINDRES=i686-w64-mingw32-windres +MINGFLAGS=-Wall -DWINDOWS -mwindows +MINGLIBS=-lshlwapi  .rc.o:  	$(MINGWINDRES) $*.rc $@  .o.exe: -	$(MINGCC32) -o $@ windows-stub.c $*.o +	$(MINGCC32) -o $@ $(MINGFLAGS) windows-stub.o $*.o $(MINGLIBS) + +$(EXE_FILES): windows-stub.o make-rc + +windows-stub.o: windows-stub.c +	$(MINGCC32) -c $(MINGFLAGS) windows-stub.c diff --git a/icon/make-rc b/icon/make-rc new file mode 100755 index 00000000..de647278 --- /dev/null +++ b/icon/make-rc @@ -0,0 +1,53 @@ +#!/bin/sh + +COMPANY="Altus Metrum, LLC" +PRODUCT="Altus Metrum" + +case "$1" in +    *altosui*) +	PRODUCT="AltosUI" +	;; +    *telegps*) +	PRODUCT="TeleGPS" +	;; +    *micropeak*) +	PRODUCT="MicroPeak" +	;; +esac + +VERSION="$2" +VERSION_COMMA=`echo "$VERSION" | sed 's/\./,/g'` +INTERNAL_NAME=`basename $1` +EXE_NAME="$INTERNAL_NAME".exe +YEAR=`date +%Y` + +cat <<EOF +101 ICON "$1.ico" +1 VERSIONINFO +FILEVERSION $VERSION_COMMA +PRODUCTVERSION $VERSION_COMMA +FILEFLAGSMASK 0 +FILEOS 0x40004 +FILETYPE 1 +{ + BLOCK "StringFileInfo" + { +  BLOCK "040904E4" +  { +   VALUE "Comments", "$COMPANY $PRODUCT" +   VALUE "CompanyName", "$COMPANY" +   VALUE "FileDescription", "$PRODUCT" +   VALUE "FileVersion", "$VERSION" +   VALUE "InternalName", "$INTERNAL_NAME" +   VALUE "LegalCopyright", "Copyright $YEAR, $COMPANY" +   VALUE "OriginalFilename", "$EXE_NAME" +   VALUE "ProductName", "$PRODUCT" +   VALUE "ProductVersion", "$VERSION" +  } + } + BLOCK "VarFileInfo" + { +  VALUE "Translation", 0x409, 1252 + } +} +EOF diff --git a/icon/windows-stub.c b/icon/windows-stub.c index 8df3e0aa..e075a02d 100644 --- a/icon/windows-stub.c +++ b/icon/windows-stub.c @@ -1,2 +1,201 @@ -__stdcall -WinMain(int a, int b, int c, int d) { return 0; } +/* + * Copyright © 2015 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +/* A windows stub program to launch a java program with suitable parameters + * + * Given that the name of this exe is altusmetrum-foo.exe living in directory bar, and + * that it was run with 'args' extra command line parameters, run: + * + *	javaw.exe -Djava.library.path="bar" -jar "bar/foo-fat.jar" args + */ + +#define _UNICODE +#define UNICODE +#include <stdlib.h> +#include <windows.h> +#include <setupapi.h> +#include <stdio.h> +#include <stdarg.h> +#include <shlwapi.h> + +/* Concatenate a list of strings together + */ +static LPTSTR +wcsbuild(LPTSTR first, ...) +{ +	va_list	args; +	int	len; +	LPTSTR	buf; +	LPTSTR	arg; + +	buf = wcsdup(first); +	va_start(args, first); +	while ((arg = va_arg(args, LPTSTR)) != NULL) { +		len = wcslen(buf) + wcslen(arg) + 1; +		buf = realloc(buf, len * sizeof (wchar_t)); +		wcscat(buf, arg); +	} +	va_end(args); +	return buf; +} + +/* Quote a single string, taking care to escape embedded quote and + * backslashes within + */ +static LPTSTR +quote_arg(LPTSTR arg) +{ +	LPTSTR	result; +	LPTSTR	in, out; +	int	out_len = 3;	/* quotes and terminating null */ + +	/* Find quote and backslashes */ +	for (in = arg; *in; in++) { +		switch (*in) { +		case '"': +		case '\\': +			out_len += 2; +			break; +		default: +			out_len++; +			break; +		} +	} + +	result = malloc ((out_len + 1) * sizeof (wchar_t)); +	out = result; +	*out++ = '"'; +	for (in = arg; *in; in++) { +		switch (*in) { +		case '"': +		case '\\': +			*out++ = '\\'; +			break; +		} +		*out++ = *in; +	} +	*out++ = '"'; +	*out++ = '\0'; +	return result; +} + +/* Construct a single string from a list of arguments + */ +static LPTSTR +quote_args(LPTSTR *argv, int argc) +{ +	LPTSTR	result = NULL, arg; +	int	i; + +	result = malloc(1 * sizeof (wchar_t)); +	result[0] = '\0'; +	for (i = 0; i < argc; i++) { +		arg = quote_arg(argv[i]); +		result = realloc(result, (wcslen(result) + 1 + wcslen(arg) + 1) * sizeof (wchar_t)); +		wcscat(result, L" "); +		wcscat(result, arg); +		free(arg); +	} +	return result; +} + +/* Return the directory portion of the provided file + */ +static LPTSTR +get_dir(LPTSTR file) +{ +	DWORD	len = GetFullPathName(file, 0, NULL, NULL); +	LPTSTR	full = malloc (len * sizeof (wchar_t)); +	GetFullPathName(file, len, full, NULL); +	PathRemoveFileSpec(full); +	return full; +} + +/* Convert a .exe name into a -fat.jar name, starting + * by computing the complete path name of the source filename + */ +static LPTSTR +make_jar(LPTSTR file) +{ +	DWORD	len = GetFullPathName(file, 0, NULL, NULL); +	LPTSTR	full = malloc (len * sizeof (wchar_t)); +	LPTSTR	base_part; +	LPTSTR	jar; +	LPTSTR	dot; +	GetFullPathName(file, len, full, &base_part); +	static const wchar_t head[] = L"altusmetrum-"; + +	if (wcsncmp(base_part, head, wcslen(head)) == 0) +		base_part += wcslen(head); +	dot = wcsrchr(base_part, '.'); +	if (dot) +		*dot = '\0'; +	jar = wcsdup(base_part); +	PathRemoveFileSpec(full); +	return wcsbuild(full, L"\\", jar, L"-fat.jar", NULL); +} + +/* Build the complete command line from the pieces + */ +static LPTSTR +make_cmd(LPTSTR dir, LPTSTR jar, LPTSTR quote_args) +{ +	LPTSTR	quote_dir = quote_arg(dir); +	LPTSTR	quote_jar = quote_arg(jar); +	LPTSTR	cmd; + +	cmd = wcsbuild(L"javaw.exe -Djava.library.path=", quote_dir, L" -jar ", quote_jar, quote_args, NULL); +	free(quote_jar); +	free(jar); +	free(quote_dir); +	return cmd; +} + +int WINAPI +WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmd_line_a, int cmd_show) +{ +	STARTUPINFO		startup_info; +	PROCESS_INFORMATION	process_information; +	BOOL			result; +	wchar_t			*command_line; +	int			argc; +	LPTSTR			*argv = CommandLineToArgvW(GetCommandLine(), &argc); +	LPTSTR			my_dir; +	LPTSTR			my_jar; +	LPTSTR			args = quote_args(argv + 1, argc - 1); + +	my_dir = get_dir(argv[0]); +	my_jar = make_jar(argv[0]); +	command_line = make_cmd(my_dir, my_jar, args); +	memset(&startup_info, '\0', sizeof startup_info); +	startup_info.cb = sizeof startup_info; +	result = CreateProcess(NULL, +			       command_line, +			       NULL, +			       NULL, +			       FALSE, +			       CREATE_NO_WINDOW, +			       NULL, +			       NULL, +			       &startup_info, +			       &process_information); +	if (result) { +		CloseHandle(process_information.hProcess); +		CloseHandle(process_information.hThread); +	} +	exit(0); +} | 
