Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
GestaltTalk/GestaltTalkCommands.c
/* |
GestaltTalkCommands |
------------------- |
By Brigham Stevens |
Apple Computer DTS |
*/ |
#include <GestaltTalk.h> |
/* initialize everything - call first */ |
static OSErr GestaltTalkInit(GestaltTalkPB *gpb); |
/* returns the number of bytes in buffer */ |
static OSErr GestaltTalkStatus(GestaltTalkPB *gpb); |
/* read some bytes from the buffer */ |
static OSErr GestaltTalkRead(GestaltTalkPB *gpb); |
/* write some bytes to the buffer */ |
static OSErr GestaltTalkWrite(GestaltTalkPB *gpb); |
/* If an application registers, then an init can wake it up at the 'right times' */ |
static OSErr GestaltTalkRegister(GestaltTalkPB *gpb); |
/* call before your app quits so the init will not try to wake you */ |
static OSErr GestaltTalkUnregister(GestaltTalkPB *gpb); |
/* Used to get the PSN of the registerd application (pointer to it in data) */ |
static OSErr GestaltTalkGetRegisteredApp(GestaltTalkPB *gpb); |
/* This function gets the address of the gestalt talk buffer and stores |
the returned pointer in gtData |
Then future GestaltTalk calls will be faster becuase they will not |
use Gestalt to get the address of the buffer */ |
static OSErr GestaltTalkUserInit(GestaltTalkPB *gpb); |
/* |
This function gets the address of the gestalt talk buffer |
*/ |
static OSErr GetGestaltTalkBuffer(gtp *g); |
#ifdef BUILD_INIT |
pascal OSErr GestaltTalkGestalt(long selector, long *response); |
#endif |
/* |
This is the main entry point to GestaltTalk |
All of the other routines should be access by filling |
out the gestaltTalk parameter block and calling this |
*/ |
OSErr GestaltTalk(GestaltTalkPB *gpb) |
{ |
OSErr err = 0; |
switch(gpb->command) { |
#ifdef BUILD_INIT |
case ginit: err = GestaltTalkInit(gpb); |
break; |
#endif |
case gstatus: err = GestaltTalkStatus(gpb); |
break; |
case gread: err = GestaltTalkRead(gpb); |
break; |
case gwrite: err = GestaltTalkWrite(gpb); |
break; |
case gregister: err = GestaltTalkRegister(gpb); |
break; |
case gunregister: err = GestaltTalkUnregister(gpb); |
break; |
case ggetapp: err = GestaltTalkGetRegisteredApp(gpb); |
break; |
case guserinit: err = GestaltTalkUserInit(gpb); |
break; |
default: return paramErr; |
} |
return err; |
} |
#ifdef BUILD_INIT |
static OSErr GestaltTalkInit(GestaltTalkPB *gpb) |
{ |
gtp g; |
OSErr err = 0; |
err = GetGestaltTalkBuffer(&g); |
if(err) { |
DebugStr("\p GestaltTalkInit - GetGestaltTalkBuffer failed."); |
goto bail; |
} |
g->dataBuffer = NewPtrSysClear(bufferSize); |
if(!g->dataBuffer) { |
err = MemError(); |
DebugStr("\p GestaltTalkInit - NewPtrSysClear failed."); |
goto bail; |
} |
g->buffCount = 0; |
bail: |
return err; |
} |
#endif |
/* |
gets the number of bytes in the buffer in datalength |
*/ |
OSErr GestaltTalkStatus(GestaltTalkPB *gpb) |
{ |
short err = 0; |
gtp g; |
if(gpb->gtData) |
g = gpb->gtData; |
else { |
err = GetGestaltTalkBuffer(&g); |
if(err) goto bail; |
} |
gpb->datalength = g->buffCount; |
bail: |
return err; |
} |
OSErr GestaltTalkRead(GestaltTalkPB *gpb) |
{ |
short err = 0; |
gtp g; |
if(gpb->gtData) |
g = gpb->gtData; |
else { |
err = GetGestaltTalkBuffer(&g); |
if(err) goto bail; |
} |
if(!g->buffCount) { |
gpb->datalength = 0; |
goto bail; |
} |
if(gpb->datalength < g->buffCount) { |
err = readErr; |
BlockMove(g->dataBuffer, gpb->data, gpb->datalength); |
} else if (gpb->datalength > g->buffCount) |
err = eofErr; |
BlockMove(g->dataBuffer, gpb->data, g->buffCount); |
gpb->datalength = g->buffCount; |
/* right now this only supports one entry */ |
/* next version supports multiple entries */ |
g->buffCount = 0; |
bail: |
return err; |
} |
OSErr GestaltTalkWrite(GestaltTalkPB *gpb) |
{ |
short err = 0; |
gtp g; |
if(gpb->gtData) |
g = gpb->gtData; |
else { |
err = GetGestaltTalkBuffer(&g); |
if(err) goto bail; |
} |
if(!gpb->datalength) { |
err = paramErr; |
goto bail; |
} |
if(gpb->datalength > bufferSize) { |
err = writErr; |
BlockMove(gpb->data,g->dataBuffer,bufferSize); |
g->buffCount = bufferSize; |
gpb->datalength = bufferSize; |
} else { |
BlockMove(gpb->data,g->dataBuffer,gpb->datalength); |
g->buffCount = gpb->datalength; |
} |
bail: |
return err; |
} |
/* |
If an appliation registers it's PSN with GestaltTalk |
then the PoliteNotification init will wake up the application |
so it can fetch the notification message from the buffers. |
*/ |
/* can be called from an interrtupt */ |
OSErr GestaltTalkRegister(GestaltTalkPB *gpb) |
{ |
short err = 0; |
gtp g; |
if(gpb->gtData) |
g = gpb->gtData; |
else { |
err = GetGestaltTalkBuffer(&g); |
if(err) goto bail; |
} |
g->appPSN = *(ProcessSerialNumber*)gpb->data; |
g->appRegistered = 0x01; |
bail: |
return err; |
} |
/* can be called from an interrtupt */ |
OSErr GestaltTalkUnregister(GestaltTalkPB *gpb) |
{ |
short err = 0; |
gtp g; |
if(gpb->gtData) |
g = gpb->gtData; |
else { |
err = GetGestaltTalkBuffer(&g); |
if(err) goto bail; |
} |
g->appRegistered = false; |
bail: |
return err; |
} |
OSErr GestaltTalkGetRegisteredApp(GestaltTalkPB *gpb) |
{ |
short err = 0; |
gtp g; |
if(gpb->gtData) |
g = gpb->gtData; |
else { |
err = GetGestaltTalkBuffer(&g); |
if(err) goto bail; |
} |
if(!g->appRegistered) { |
err = paramErr; |
goto bail; |
} |
gpb->data = &g->appPSN; |
gpb->datalength = sizeof(ProcessSerialNumber); |
bail: |
return err; |
} |
/* |
This procedure returns the address of the GTalk buffer |
*/ |
static OSErr GestaltTalkUserInit(GestaltTalkPB *gpb) |
{ |
short err = 0; |
gtp g; |
err = GetGestaltTalkBuffer(&g); |
gpb->gtData = g; |
bail: |
return err; |
} |
OSErr GetGestaltTalkBuffer(gtp *g) |
{ |
OSErr err = 0; |
#ifdef BUILD_INIT |
return GestaltTalkGestalt(gestaltTalkSelector, (long*)g); |
#endif |
#ifdef BUILD_USER |
asm { |
move.l #gestaltTalkSelector,d0 |
_Gestalt |
move.l g,a1 |
move.l a0,(a1) |
} |
#endif |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14