/*
 *		SETCONSOLEFONT.C
 *
 *		by Eddy Carroll, August 1994
 *
 *		A simple CLI program that sets the font for the current console
 *		window to that specified.
 */

#define VERSION_STRING		"$VER: SetConFont 1.0 (30.8.94)"

#define __USE_SYSBASE 1

#include <exec/types.h>
#include <devices/conunit.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <graphics/gfxbase.h>
#include <intuition/intuition.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/diskfont.h>
#include <proto/graphics.h>

#include <stdlib.h>
#include <string.h>

struct ExecBase		*SysBase;
struct DosLibrary	*DOSBase;
struct GfxBase		*GfxBase;
struct Library		*DiskfontBase;

static void SetConsoleFont(char *fontname, int fontsize);

/*
 *		To keep the filesize small, we bypass SAS's startup code in
 *		favour of our own. This means we need to open ALL libraries
 *		ourself. We must also ensure main is the very first function
 *		in the file (no const strings or other functions), and use
 *		the __saveds and __interrupt keywords to make sure we can
 *		access our global data.
 */
int __saveds main(void)
{
	struct RDArgs *rda;
	LONG param[2];
	int retval = 0;

	SysBase = *(struct ExecBase **)(4L);
	DOSBase = (void *)OpenLibrary("dos.library", 37);
	if (!DOSBase)
		return (10);
	
	GfxBase = (void *)OpenLibrary("graphics.library", 0);
	if (!GfxBase) {
		CloseLibrary(DOSBase);
		return (10);
	}
	rda = ReadArgs("Fontname/A,Fontsize/A/N", param, NULL);
	if (rda) {
		int  fontsize = *(LONG *)param[1];
		char *p = VERSION_STRING;	/* Slip in version string somewhere */
		char fontname[80];

		strcpy(fontname, (char *)param[0]);
		for (p = fontname; *p && *p != '.'; p++)
			;
		strcpy(p, ".font");
		DiskfontBase = OpenLibrary("diskfont.library", 36);
		if (DiskfontBase) {
			SetConsoleFont(fontname, fontsize);
			CloseLibrary(DiskfontBase);
		} else {
			Printf("Can't open diskfont.library v36\n");
		}
		FreeArgs(rda);
	} else {
		PrintFault(IoErr(), "Error parsing command line");
		retval = 10;
	}
	CloseLibrary(GfxBase);
	CloseLibrary(DOSBase);
	return (retval);
}

/*
 *		SetConsoleFont(fontname, fontsize)
 *
 *		Opens the specified font and installs it into the current
 *		console window, if possible.
 */
static void SetConsoleFont(char *fontname, int fontsize)
{
	struct TextAttr fontattr;
	struct TextFont *newfont;
	struct MsgPort *console;
	struct ConUnit *cu;
	struct InfoData __aligned info;
	struct Window *win;

	fontattr.ta_Name  = fontname;
	fontattr.ta_YSize = fontsize;
	fontattr.ta_Style = 0;
	fontattr.ta_Flags = 0;

	console = GetConsoleTask();
	if (!console) {
		Printf("This CLI has no associated console device.\n");
		return;
	}
	if (!DoPkt(console, ACTION_DISK_INFO, ((ULONG)(&info)) >> 2, 0, 0, 0, 0)) {
		Printf("This CLI has no console window.\n");
		return;
	}
	if (!info.id_VolumeNode || !info.id_InUse) {
		Printf("This CLI doesn't support font changing.\n");
		return;
	}
	win = (struct Window *)info.id_VolumeNode;
	cu  = (struct ConUnit *)((struct IOStdReq *)info.id_InUse)->io_Unit;

	newfont = OpenDiskFont(&fontattr);
	if (!newfont) {
		Printf("Can't open font %s, size %ld\n", fontname, fontsize);
		return;
	}
	/*
	 *		Hurray! We've got our new font, so install it in the
	 *		console structure
	 */
	Forbid();
	/*
	 *		The console unit opens the system default device itself when
	 *		it initialises. Any other fonts must have been opened by us.
	 *		Thus, we only free the old font if it's not the system font.
	 *		(CON: will always close the font it originally opened, even
	 *		if we've changed to a different font in the meantime).
	 */
	if (cu->cu_Font != GfxBase->DefaultFont)
		CloseFont(cu->cu_Font);	

	cu->cu_Font = newfont;
	SetFont(win->RPort, newfont);
	Write(Output(), "\033c", 2);		/* Reset console window */
	Permit();
}
