home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
339.lha
/
screenshare.library_v1.21
/
pubscr.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-02-08
|
10KB
|
514 lines
/** pubscr.c
*
* These are the screen management routines
*
**/
#include <exec/exec.h>
#include <stdio.h>
#include <functions.h>
#include "pubscr.h"
/*
* The following two strings must exist.
*/
char SSHname[] = "screenshare.library";
char SSHid[] = "screenshare 1.21 (Oct 89)\r\n";
UWORD SSHrevision = 21;
/*
* ScreenList is the only static variable
*/
static struct List *ScreenList = NULL;
static struct ScreenNode *ScrListAlloc(), *ScrListFree(), *ScrListFind();
static struct Library *ScrSharBase;
/**
*
* NAME
*
* GetPubScrList
* =============
*
* SYNOPSIS
*
* struct List *ScreenList = GetPubScrList()
* D0
*
* FUNCTION
*
* This function returns a pointer to the Exec-style
* list of shared screen nodes.
*
* INPUTS
*
* None
*
* RESULT
*
* Pointer to the first node.
*
* ADDITIONAL CONSIDERATIONS
*
* This routine is not normally used in applications.
* The ScreenNode structure is described in pubscr.h.
*
* BUGS
*
* None known.
*
* AUTHOR
*
* W.G.J. Langeveld (WGL)
*
**/
struct List *GetPubScrList()
{
return(ScreenList);
}
/**
*
* NAME
*
* PublicScreen
* ============
*
* SYNOPSIS
*
* int result = PublicScreen(Name, ScreenAddress)
* D0 A0 A1
*
* FUNCTION
*
* This function adds a named screen to the public screen list.
*
* INPUTS
*
* Name Name to be assigned to the public screen.
* ScreenAddress Pointer to the Screen structure.
*
* RESULT
*
* 0 on failure, 1 on success.
* Note: the return code is a 16 bit int (a short).
*
* ADDITIONAL CONSIDERATIONS
*
* This routine should be called by an application ("host") if it wants
* to make its custom screen accessible to the outside world ("symbionts").
* When an application calls this function, it promises in particular to
* NOT CLOSE this screen until it has ascertained that the screen is no
* longer occupied by symbionts through calling PubScrLocked(), and until
* it has reverted the status of the screen to private by calling
* PrivateScreen().
*
* If a screen with the same name already exists, the screen pointer is
* compared with that of the existing public screen. The function only
* returns successfully in that case if the two pointers are identical.
* In such a case, the symbiont open count is not affected.
* Otherwise, the function returns 0 and performs no action.
*
* BUGS
*
* None known.
*
* AUTHOR
*
* W.G.J. Langeveld (WGL)
*
**/
int PublicScreen(name, address)
char *name;
struct Screen *address;
{
struct ScreenNode *olditem = NULL;
int res;
/*
* Can't interrupt this
*/
Forbid();
res = 0;
/*
* First try to find this one. If found, and the addess is the same, return okay
*/
if (olditem = ScrListFind(name)) {
if (olditem->sn_Address == address) res = 1;
}
/*
* Else allocate a new node and open ourselves so we don't go away
*/
else {
if (ScrListAlloc(name, address)) {
ScrSharBase = OpenLibrary("screenshare.library", 0L);
res = 1;
}
}
Permit();
return(res);
}
/**
*
* NAME
*
* PrivateScreen
* =============
*
* SYNOPSIS
*
* int result = PrivateScreen(Name)
* D0 A0
*
* FUNCTION
*
* This function removes a named screen from the public screen list.
*
* INPUTS
*
* Name Name of the public screen
*
* RESULT
*
* 0 on failure, 1 on success.
* Note: the return code is a 16 bit int (a short).
*
* ADDITIONAL CONSIDERATIONS
*
* This routine should be called by an application that has made itself
* the "host" to a named public screen through a call to PublicScreen().
* Before calling PrivateScreen(), the application should verify that no
* "symbionts" are currently present on the screen through a call to
* PubScrLocked().
*
* If the Name is not found in the public screen list, the function
* performs no operation and returns 0.
* If the Name is found, the current symbiont open count is checked.
* If the open count is non-zero, the function performs no operation
* and returns 0.
*
* BUGS
*
* None known.
*
* AUTHOR
*
* W.G.J. Langeveld (WGL)
*
**/
int PrivateScreen(name)
char *name;
{
struct ScreenNode *olditem = NULL;
int res;
/*
* Can't interrupt this
*/
Forbid();
res = 0;
/*
* Try to find this name, if found, free node and close ourselves.
*/
if (olditem = ScrListFind(name)) {
if (olditem->sn_OpenCount == 0) {
ScrListFree(olditem);
if (ScrSharBase) CloseLibrary(ScrSharBase);
res = 1;
}
}
Permit();
return(res);
}
/**
*
* NAME
*
* PubScrLocked
* ============
*
* SYNOPSIS
*
* int result = PubScrLocked(Name)
* D0 A0
*
* FUNCTION
*
* This function returns the number of symbionts still open on this
* named screen.
*
* INPUTS
*
* Name Name of the public screen
*
* RESULT
*
* Number of symbionts with windows still open on this screen.
* Note: the return code is a 16 bit int (a short).
*
* ADDITIONAL CONSIDERATIONS
*
* This function should be used by an application that has made itself
* the "host" to a named public screen through a call to PublicScreen()
* in order to determine whether it is safe to call PrivateScreen().
*
* If a screen with the given Name is not found, the function returns 0.
*
* BUGS
*
* None known.
*
* AUTHOR
*
* W.G.J. Langeveld (WGL)
*
**/
int PubScrLocked(name)
char *name;
{
struct ScreenNode *olditem = NULL;
int res;
/*
* Can't interrupt this
*/
Forbid();
res = 0;
if (olditem = ScrListFind(name)) res = olditem->sn_OpenCount;
Permit();
return(res);
}
/**
*
* NAME
*
* LockPubScreen
* =============
*
* SYNOPSIS
*
* struct Screen *ScreenPtr = LockPubScreen(Name)
* D0 A0
*
* FUNCTION
*
* This function returns the address of a named public screen, and
* increments the screenshare.library's symbiont counter for this
* screen.
*
* INPUTS
*
* Name Name of the public screen
*
* RESULT
*
* Pointer to the public screen, if found. NULL otherwise.
*
* ADDITIONAL CONSIDERATIONS
*
* This function should be used by the symbiont in order to find
* the address of the Screen structure of the application that has declared
* its screen public. The symbiont should use UnlockPubScreen() whenever
* it has closed its window(s) on that screen, and not open any windows
* on that screen until after a call to LockPubScreen().
*
* BUGS
*
* None known.
*
* AUTHOR
*
* W.G.J. Langeveld (WGL)
*
**/
struct Screen *LockPubScreen(name)
char *name;
{
struct Screen *res;
struct ScreenNode *olditem;
/*
* Can't interrupt this
*/
Forbid();
res = 0L;
/*
* Find the screen. If found, increment its counter. Return the address.
*/
if (olditem = ScrListFind(name)) {
olditem->sn_OpenCount++;
res = olditem->sn_Address;
}
Permit();
return(res);
}
/**
*
* NAME
*
* UnlockPubScreen
* ===============
*
* SYNOPSIS
*
* struct Screen *ScreenPtr = UnlockPubScreen(Name)
* D0 A0
*
* FUNCTION
*
* This function decrements the symbiont counter of the named screen.
*
* INPUTS
*
* Name Name of the public screen
*
* RESULT
*
* Guaranteed NULL.
*
* ADDITIONAL CONSIDERATIONS
*
* This function should be used by the symbiont in order to decrement the
* the symbiont counter of the named screen to signal it has closed its
* window(s) on that screen. The symbiont should use LockPubScreen()
* before opening any windows on that screen, and not call UnlockPubScreen()
* until it has closed its window(s) on that screen.
*
* BUGS
*
* None known.
*
* AUTHOR
*
* W.G.J. Langeveld (WGL)
*
**/
struct Screen *UnlockPubScreen(name)
char *name;
{
struct Screen *res;
struct ScreenNode *olditem;
/*
* Can't interrupt this
*/
Forbid();
res = 0L;
/*
* First find the screen. If found, decrement its counter.
*/
if (olditem = ScrListFind(name)) {
if (olditem->sn_OpenCount != 0) olditem->sn_OpenCount--;
res = 0L;
}
Permit();
return(res);
}
/**
*
* The following are local routines, not accessible from the outside world
* =======================================================================
*
* Routine to add another node to the Screen list.
*
**/
#define SNSIZE ((long) sizeof(struct ScreenNode))
#define SLSIZE ((long) sizeof(struct List))
static struct ScreenNode *ScrListAlloc(s, scr)
char *s;
struct Screen *scr;
{
struct ScreenNode *sn;
/*
* If no list exists, create one
*/
if (ScreenList == NULL) {
ScreenList = (struct List *) AllocMem(SLSIZE, MEMF_PUBLIC | MEMF_CLEAR);
if (!ScreenList) return(NULL);
NewList(ScreenList);
}
/*
* Create a node
*/
sn = (struct ScreenNode *) AllocMem(SNSIZE, MEMF_PUBLIC | MEMF_CLEAR);
if (sn) {
/*
* Allocate room for the name
*/
sn->sn_Node.ln_Name = (char *)
AllocMem((long) (strlen(s) + 1), MEMF_PUBLIC | MEMF_CLEAR);
if (sn->sn_Node.ln_Name) {
/*
* ...and copy the name
*/
strcpy(sn->sn_Node.ln_Name, s);
/*
* Copy the address and zero the open count.
*/
sn->sn_Address = scr;
sn->sn_OpenCount = 0;
/*
* Add this one to the list
*/
AddTail(ScreenList, sn);
}
}
return(sn);
}
/**
*
* Free a ScreenNode node
*
**/
static struct ScreenNode *ScrListFree(item)
struct ScreenNode *item;
{
if (item == 0L) return(0L);
if (ScreenList == 0L) return(0L);
/*
* Isolate this item from the list.
*/
Remove(item);
/*
* Free the string
*/
if (item->sn_Node.ln_Name)
FreeMem(item->sn_Node.ln_Name, (long) (strlen(item->sn_Node.ln_Name) + 1));
/*
* Free the item
*/
FreeMem(item, SNSIZE);
/*
* If this is the last item, free the list.
*/
if (ScreenList->lh_TailPred == ScreenList) {
FreeMem(ScreenList, SLSIZE);
ScreenList = NULL;
}
return(0L);
}
/**
*
* Find a screen with a certain name
*
**/
static struct ScreenNode *ScrListFind(name)
char *name;
{
/*
* If the name is null or there is no header, return
*/
if (name == 0L) return(0L);
if (ScreenList == 0L) return(0L);
/*
* Find it
*/
return((struct ScreenNode *) FindName(ScreenList, name));
}