[comp.sys.mac.programmer] Journal DRVR in Think C -- HELP

sharp@cs-sun-fsa.cpsc.ucalgary.ca (Maurice Sharp) (02/09/91)

Hiya,

    I am trying to implement a cdev/DRVR combination that uses the
Event Manager Journaling mechanism. The vehicle of implementation is
Think C.

    The cdev is fairly straightforward (it already exists). But the
DRVR is another matter. I get exceedingly strange behaviour when it is
active. The aim is to write out a text file of certain events. I am
using the high level file manager calls (FSOpen, FSWrite).

    As it stands, I only get one call worth of text written, and that
is inccorect as well. What is worse, occasionaly the System expands to
fill all the available memory.

    Are there any hints/tips/sample source ? This code is exceedingly
important to my thesis work. Please help. If you know ThinkC, the
source files for the driver are attached below.

	maurice

Maurice Sharp MSc. Student (403) 220 7690
University of Calgary Computer Science Department
2500 University Drive N.W.	      sharp@cpsc.UCalgary.CA
Calgary, Alberta, T2N 1N4	      GEnie M.SHARP5

There are two files below: JournalDrvr.h and JournalDrvr.c
---------------------- cut here for Journal Driver.h --------------------------
/*
	FILE: journal driver.h
	
	The include stuff for the journal drive.

*/


/* global data for the driver */

typedef struct {
	Boolean	modCommand ;
	Boolean	modOption ;
	Boolean modControl ;
	Boolean otherKeys ;
	Boolean mouseUp ;
	Boolean mouseDown ;
	Boolean mouseMove ;
	Boolean timeStamp ;
	
	OSType	fileCreator ;
	int		fileRefNum ;
	

} DeviceData, *P_DeviceData ;

#define FILE_TYPE	'TEXT'


/* command constants */

#define	CMD_OPEN	0
#define CMD_PRIME	1
#define CMD_CONTROL	2
#define CMD_STATUS	3
#define CMD_CLOSE	4

/* Control message constants. JRNL - Journaling mechanism  CDEV - from my cdev */

#define	JRNL_PLAY_CNTRL		16
#define JRNL_RECORD_CNTRL	17

#define	CDEV_FILE_INFO		18	/* file to save journal information to */
#define	CDEV_CONFIG_INFO	19	/* what events to save and timestamp info */

/* Sub types of JRNL control messages */

#define JRNL_TICK_COUNT		0	/* call to TickCount() */
#define JRNL_GET_MOUSE		1	/* call to GetMouse() */
#define JRNL_BUTTON			2	/* call to Button() */
#define JRNL_GET_KEYS		3	/* call to GetKeys() */
#define JRNL_EVENT			4	/* call to GetNextEvent() or WaitNextEvent() */


/* System globals that we need to access */

#define JournalFlag	0x08DE	/* word */
#define JournalRef	0x08E8	/* word */
#define JRNL_PLAY	-1		/* constant to put in JournalFlag */
#define JRNL_RECORD	1		/* constant to put in JournalFlag */

/* Function Prototypes */

void	DoOpen(cntrlParam *paramBlock) ;
void	DoClose(void) ;
void	DoControl(cntrlParam *paramBlock) ;
void	DoJournalRecord(cntrlParam *paramBlock) ;


/* table of event types and equivelant strings */

Str255	gEventNames[16] = {
"\pnull",
"\pmouseDown",
"\pmouseUp",
"\pkeyDown",
"\keyUp",
"\pautoKey",
"\pupdate",
"\pdisk",
"\pactivate",
"\p",
"\pnetwork",
"\pdriver",
"\papp1",
"\papp2",
"\papp3",
"\papp4"} ;

#define CR		0x015

char	gCR = CR ;

---------------------- cut here for Journal Driver.c --------------------------
/*
	FILE: journal driver.c
	
	This is the main C code for the journal device driver.
	
	The purpose of this driver is to enable the journaling
	mechanism of the Event Manager. This code will start
	recording events to a file.
	
	The driver will be activated from the accompanying cdev.
	The cdev is used to specify where the journal should be
	recorded, what types of things to record, and if a time
	stamp is needed.

*/


#include "journal driver.h"


/* Global data */

Boolean		already_open = FALSE ;
DeviceData	gGlobalData ;



/* main

   This is defined in the Think C manual p. 78
   
   paramBlock is a pointer to an I/O parameter block (passed in A0)
   devCtlEnt is a pointer to the device control entry (passed in A1)
   n is the entry point of the call, that is the routine to invoke
*/


main (cntrlParam *paramBlock, DCtlPtr devCtlEnt, int command)
{

	switch(command) {
		case CMD_OPEN:
				paramBlock->ioRefNum = devCtlEnt->dCtlRefNum ;
				DoOpen(paramBlock) ;
				break ;
				
		case CMD_PRIME:
				break ;
				
		case CMD_CONTROL:
				DoControl(paramBlock) ;
				break ;
				
		case CMD_STATUS:
				break ;
				
		case CMD_CLOSE:
				DoClose() ;
				break ;
	}
	return(noErr) ;
}

/*
	DoOpen
	
*/



void DoOpen(cntrlParam *paramBlock)
{
	int 	refNum ;
	OSErr	err ;
	int		volNum ;
	long	dirID ;
	Str255	volStr ;
	
	if (already_open)
		return ;

	already_open = TRUE ;
	
	/* setup system globals so that Event Manager calls this driver */
	
	refNum = paramBlock->ioRefNum ;
	
	paramBlock->ioResult = noErr ;
	
	gGlobalData.fileCreator = 'MSWD' ;
	err = GetVol(volStr, &volNum) ;
	err = Create("\pJournal File", volNum, gGlobalData.fileCreator, FILE_TYPE) ;
	err = FSOpen("\pJournal File", volNum, &(gGlobalData.fileRefNum)) ; 

	asm {
		move.w	#JRNL_RECORD, JournalFlag
		move.w	refNum, JournalRef
	}
}

/*
	DoClose
*/


void DoClose(void)
{
	OSErr err ;
	
	asm {
		move.w	#0, JournalFlag
	}
	err = FSClose(gGlobalData.fileRefNum) ;
}


/*
	DoControl
*/

void DoControl(cntrlParam *paramBlock)
{
	Str255	myStr = "\pControl Message" ;
	Str255	yikes = "\poh shit" ;
	OSErr 	err ;
	long	len ;
	
	len = myStr[0] ;
	err = FSWrite(gGlobalData.fileRefNum, &len, myStr) ;
	if (len != myStr[0]) {
		len = 7 ;
		err = FSWrite(gGlobalData.fileRefNum, &len, yikes) ;
	}
	len = 1;
	err = FSWrite(gGlobalData.fileRefNum, &len, &gCR);
	
	switch (paramBlock->csCode) {
		case JRNL_PLAY_CNTRL:
			break ;
			
		case JRNL_RECORD_CNTRL:
			DoJournalRecord(paramBlock) ;
			break ;
			
		case CDEV_FILE_INFO:	/* open the specified file to write info to */
			break ;
		
		case CDEV_CONFIG_INFO:
			break ;

	}
}

void DoJournalRecord(cntrlParam *paramBlock)
{
	int 		callType ;
	EventRecord	*eventPtr ;
	long		count ;
	OSErr		err ;
	
	callType = (int) (paramBlock->csParam[4]) ;
	
	switch(callType) {
		case JRNL_TICK_COUNT:
			break ;
			
		case JRNL_GET_MOUSE:
			break ;
			
		case JRNL_BUTTON:
			break ;
			
		case JRNL_GET_KEYS:
			break ;
			
		case JRNL_EVENT:
			eventPtr = (*(EventRecord **) paramBlock->csParam) ;
			if (eventPtr->what != nullEvent) {
				count = (long) gEventNames[eventPtr->what][0] ;
				err = FSWrite(gGlobalData.fileRefNum, &count,
							  gEventNames[eventPtr->what][1]) ;
				count = 1 ;
				err = FSWrite(gGlobalData.fileRefNum, &count, &gCR) ;
			}
			break ;
			
	}
}


-- 
Maurice Sharp MSc. Student (403) 220 7690
University of Calgary Computer Science Department
2500 University Drive N.W.	      sharp@cpsc.UCalgary.CA
Calgary, Alberta, T2N 1N4	      GEnie M.SHARP5