home *** CD-ROM | disk | FTP | other *** search
- /** 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.1 (Jul 88)\r\n";
- UWORD SSHrevision = 1;
- /*
- * 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.
- *
- * 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("screenshar.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.
- *
- * 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.
- *
- * 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) (sizeof(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));
- }
-