#if 0

/*
	File:		Un/mount.c

	Contains:	This sample demonstrates how to handle disk-inserted events in a modal dialog.
				Along the way, it demonstrates how to field a disk-inserted event without allowing
				the system to automagically mount the volumes on the disk. (The code mounts the disk
				explicitly, but your program doesn't need to.)

	Written by: Pete Gontier

	Copyright:	Copyright © 1997-1999 by Apple Computer, Inc., All Rights Reserved.

				You may incorporate this Apple sample source code into your program(s) without
				restriction. This Apple sample source code has been provided "AS IS" and the
				responsibility for its operation is yours. You are not permitted to redistribute
				this Apple sample source code as "Apple sample source code" after having made
				changes. If you're going to re-distribute the source, we require that you make
				it clear in the source that the code was descended from Apple sample source
				code, but that you've made changes.

	Change History (most recent first):
				7/1/1999	Karl Groethe		 Updated for Metrowerks Codewarror Pro 2.1
				

*/
#define OLDROUTINELOCATIONS		0
#define OLDROUTINENAMES			0
#define SystemSevenOrLater		1

#ifndef __DISKS__
#	include <Disks.h>
#endif

#ifndef __DEVICES__
#	include <Devices.h>
#endif

#ifndef __FILES__
#	include <Files.h>
#endif

#ifndef __DISKINIT__
#	include <DiskInit.h>
#endif

#ifndef __FONTS__
#	include <Fonts.h>
#endif

#ifndef __DIALOGS__
#	include <Dialogs.h>
#endif


#include <sound.h>

enum
{
	kResID_Dialog_MountUnmount = 128,
	kResID_Dialog_Main
};

enum
{
	kDialogItem_MountUnmount_None,
	kDialogItem_MountUnmount_Button_Done,
	kDialogItem_MountUnmount_StaticText_Waiting,
	kDialogItem_MountUnmount_StaticText_VolName,
	kDialogItem_MountUnmount_Button_Eject,
	kDialogItem_MountUnmount_StaticText_HaveDisk
};

static pascal OSErr InitMac (void)
{
	MaxApplZone ( );
	InitGraf (&(qd.thePort));
	InitFonts ( );
	InitWindows ( );
	InitMenus ( );
	TEInit ( );
	InitDialogs (nil);

	return noErr;
}

static pascal void SetWatchCursor (void)
{
	SetCursor (*GetCursor (watchCursor));
}

static pascal void ReconfigureInterfaceAfterMount (DialogRef dialog, Str27 volName)
{
	short	iType;
	Handle	iHandle;
	Rect	iRect;

	GetDialogItem (dialog,kDialogItem_MountUnmount_StaticText_VolName,
		&iType, &iHandle, &iRect);
	SetDialogItemText (iHandle,volName);

	GetDialogItem (dialog,kDialogItem_MountUnmount_Button_Eject,
		&iType, &iHandle, &iRect);
	HiliteControl ((ControlHandle) iHandle, 0);

	HideDialogItem (dialog,kDialogItem_MountUnmount_StaticText_Waiting);
	ShowDialogItem (dialog,kDialogItem_MountUnmount_StaticText_HaveDisk);
}

static pascal Boolean DriveIsFloppy (short driveNum)
{
	// this function isn't perfect but it isn't the purpose of this sample;
	// a real program would qualify volumes much better

	return driveNum == 1 || driveNum == 2;
}

static pascal OSErr AfterMount (OSErr mountErr, short driveNum, DialogRef dialog)
{
	OSErr err = noErr;

	// if mount failed, try to format and retry mount

	if (mountErr)
	{
		Point dibmWhere = { -1,-1 };
		long fakeEventMessage = (((UInt32) mountErr) << 16) | driveNum;
		err = DIBadMount (dibmWhere, fakeEventMessage);
	}

	// regardless of whether we had to reformat the disk,
	// if we successfully mounted it...

	if (!err && DriveIsFloppy (driveNum))
	{
		OSErr err2;

		// get the volume's name and poke it into the dialog

		Str27	volName;
		short	vRefNum;
		long	freeBytes;

		err = GetVInfo (driveNum, volName, &vRefNum, &freeBytes);

		if (err)
		{
			SysBeep (10);
			SetWRefCon (dialog, 0);
		}
		else
		{
			ReconfigureInterfaceAfterMount (dialog,volName);
			SetWRefCon (dialog, driveNum);
		}

		// get rid of the newly-mounted volume (but don't eject its disk)

		err2 = UnmountVol (nil, driveNum);
		if (!err2) err = err2;
	}

	return err;
}

static pascal Boolean GetNextEventModalFilterProc
	(DialogRef dialog, EventRecord *event, short *itemHit)
{
	Boolean result = StdFilterProc (dialog,event,itemHit);

	if (event->what == nullEvent)
	{
		EventRecord diskInsertedEvent;

		// is there an unrequited disk-inserted event in the queue?

		if (OSEventAvail (diskMask, &diskInsertedEvent))
		{
			// it takes a while to mount a disk

			SetWatchCursor ( );

			// let the system mount the disk

			if (GetNextEvent (diskMask, &diskInsertedEvent))
			{
				OSErr	err			= diskInsertedEvent.message >> 16;
				short	driveNum	= diskInsertedEvent.message;

				err = AfterMount (err,driveNum,dialog);
				if (err) SysBeep (10);
			}
		}
	}

	return result;
}

static pascal Boolean GetOSEventModalFilterProc
	(DialogRef dialog, EventRecord *event, short *itemHit)
{
	Boolean result = StdFilterProc (dialog,event,itemHit);

	if (event->what == nullEvent)
	{
		EventRecord diskInsertedEvent;

		// pull disk-inserted events from the queue before
		// system mounts associated volume

		if (GetOSEvent (diskMask, &diskInsertedEvent))
		{
			ParamBlockRec	pbr;
			short			driveNum = diskInsertedEvent.message;

			// mounting takes a while

			SetWatchCursor ( );

			// [attempt to mount the volume ourselves] and [react accordingly]

			pbr.volumeParam.ioVRefNum = driveNum;
			if (AfterMount (PBMountVol (&pbr), driveNum, dialog))
				SysBeep (10);
		}
	}

	return result;
}

static pascal void DisableEjectButton (DialogRef dlgRef)
{
	short	iType;
	Handle	iHandle;
	Rect	iRect;

	GetDialogItem (dlgRef,kDialogItem_MountUnmount_Button_Eject,
		&iType,&iHandle,&iRect);
	HiliteControl ((ControlHandle) iHandle, 255);
}

static pascal void ReconfigureInterfaceAfterEject (DialogRef dlgRef)
{
	short	iType;
	Handle	iHandle;
	Rect	iRect;

	GetDialogItem (dlgRef,kDialogItem_MountUnmount_StaticText_VolName,
		&iType, &iHandle, &iRect);
	SetDialogItemText (iHandle,"\p");
	ShowDialogItem (dlgRef,kDialogItem_MountUnmount_StaticText_Waiting);
	HideDialogItem (dlgRef,kDialogItem_MountUnmount_StaticText_HaveDisk);
	DisableEjectButton (dlgRef);
}

static pascal OSErr EjectIfAny (DialogRef dlgRef)
{
	OSErr err = noErr;

	short driveNum = GetWRefCon (dlgRef);

	if (driveNum)
	{
		SetWatchCursor ( );

		if (!(err = Eject (nil, driveNum)))
			SetWRefCon (dlgRef,0);
	}

	return err;
}


static pascal void MountUnmount (ModalFilterProcPtr mfpp)
{
	ModalFilterUPP modalFilterUPP = NewModalFilterProc (mfpp);
	if (modalFilterUPP)
	{
		DialogRef dlgRef = GetNewDialog (kResID_Dialog_MountUnmount,nil,(WindowRef)-1);
		if (dlgRef)
		{
			short itemHit;

			SetDialogDefaultItem (dlgRef,ok);
			SetDialogTracksCursor (dlgRef,true);
			DisableEjectButton (dlgRef);
			ShowWindow (dlgRef);

			do
			{
				ModalDialog (modalFilterUPP,&itemHit);

				if (itemHit == kDialogItem_MountUnmount_Button_Eject)
				{
					if (EjectIfAny (dlgRef))
						{ SysBeep (10); break; }
					else
						ReconfigureInterfaceAfterEject (dlgRef);
				}
			}
			while (kDialogItem_MountUnmount_Button_Done != itemHit);

			if (EjectIfAny (dlgRef)) SysBeep (10);
			DisposeDialog (dlgRef);
		}

		DisposeRoutineDescriptor (modalFilterUPP);
	}
}

void main (void)
{
	if (InitMac ( ))
		SysBeep (10);
	else
	{
		DialogRef dlgRef = GetNewDialog(kResID_Dialog_Main,nil,(WindowRef)-1);
		if (dlgRef)
		{
			ModalFilterUPP modalFilterUPP;

			if (GetStdFilterProc (&modalFilterUPP))
				SysBeep (10);
			else
			{
				enum
				{
					kDialogItem_None,
					kDialogItem_Button_Quit,
					kDialogItem_Button_GetNextEvent,
					kDialogItem_Button_GetOSEvent
				};

				short itemHit;

				SetDialogDefaultItem (dlgRef,kDialogItem_Button_Quit);
				SetDialogTracksCursor (dlgRef,true);

				do
				{
					ModalDialog (modalFilterUPP,&itemHit);

					switch (itemHit)
					{
						case kDialogItem_Button_GetNextEvent	:

							MountUnmount (GetNextEventModalFilterProc);
							break;

						case kDialogItem_Button_GetOSEvent		:

							MountUnmount (GetOSEventModalFilterProc);
							break;
					}
				}
				while (itemHit != kDialogItem_Button_Quit);
			}
			DisposeDialog (dlgRef);
		}
	}
}

#endif