home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d02xx / d0246.lha / ScreenShare / pubscr.c < prev    next >
C/C++ Source or Header  |  1989-09-14  |  10KB  |  514 lines

  1. /** pubscr.c
  2. *
  3. *   These are the screen management routines
  4. *
  5. **/
  6. #include <exec/exec.h>
  7. #include <stdio.h>
  8. #include <functions.h>
  9. #include "pubscr.h"
  10. /*
  11. *   The following two strings must exist.
  12. */
  13. char SSHname[] = "screenshare.library";
  14. char SSHid[]   = "screenshare 1.2 (Sep 89)\r\n";
  15. UWORD SSHrevision = 2;
  16. /*
  17. *   ScreenList is the only static variable
  18. */
  19. static struct List *ScreenList = NULL;
  20.  
  21. static struct ScreenNode *ScrListAlloc(), *ScrListFree(), *ScrListFind();
  22. static struct Library *ScrSharBase;
  23.                          
  24. /**
  25. *
  26. *    NAME
  27. *
  28. *    GetPubScrList
  29. *    =============
  30. *
  31. *    SYNOPSIS
  32. *
  33. *    struct List *ScreenList = GetPubScrList()
  34. *    D0
  35. *
  36. *    FUNCTION
  37. *
  38. *    This function returns a pointer to the Exec-style
  39. *    list of shared screen nodes.
  40. *
  41. *    INPUTS
  42. *
  43. *    None
  44. *
  45. *    RESULT
  46. *
  47. *    Pointer to the first node.
  48. *
  49. *    ADDITIONAL    CONSIDERATIONS
  50. *
  51. *    This routine is not normally used in applications.
  52. *    The ScreenNode structure is described in pubscr.h.
  53. *
  54. *    BUGS
  55. *
  56. *    None known.
  57. *
  58. *    AUTHOR
  59. *
  60. *    W.G.J. Langeveld (WGL)
  61. *
  62. **/
  63. struct List *GetPubScrList()
  64. {
  65.    return(ScreenList);
  66. }
  67.  
  68. /**
  69. *
  70. *    NAME
  71. *
  72. *    PublicScreen
  73. *    ============
  74. *
  75. *    SYNOPSIS
  76. *
  77. *    int result = PublicScreen(Name, ScreenAddress)
  78. *       D0                        A0    A1
  79. *
  80. *    FUNCTION
  81. *
  82. *    This function adds a named screen to the public screen list.
  83. *
  84. *    INPUTS
  85. *
  86. *    Name        Name to be assigned to the public screen.
  87. *    ScreenAddress    Pointer to the Screen structure.
  88. *
  89. *    RESULT
  90. *
  91. *    0 on failure, 1 on success.
  92. *    Note: the return code is a 16 bit int (a short).
  93. *
  94. *    ADDITIONAL    CONSIDERATIONS
  95. *
  96. *    This routine should be called by an application ("host") if it wants
  97. *    to make its custom screen accessible to the outside world ("symbionts").
  98. *    When an application calls this function, it promises in particular to 
  99. *    NOT CLOSE this screen until it has ascertained that the screen is no
  100. *    longer occupied by symbionts through calling PubScrLocked(), and until
  101. *    it has reverted the status of the screen to private by calling 
  102. *    PrivateScreen().
  103. *
  104. *    If a screen with the same name already exists, the screen pointer is
  105. *    compared with that of the existing public screen. The function only
  106. *    returns successfully in that case if the two pointers are identical.
  107. *    In such a case, the symbiont open count is not affected.
  108. *    Otherwise, the function returns 0 and performs no action.
  109. *
  110. *    BUGS
  111. *
  112. *    None known.
  113. *
  114. *    AUTHOR
  115. *
  116. *    W.G.J. Langeveld (WGL)
  117. *
  118. **/
  119. int PublicScreen(name, address)
  120. char *name;
  121. struct Screen *address;
  122. {
  123.    struct ScreenNode *olditem = NULL;
  124.    int res;
  125. /*
  126. *   Can't interrupt this
  127. */
  128.    Forbid();
  129.    res = 0;
  130. /*
  131. *   First try to find this one. If found, and the addess is the same, return okay
  132. */
  133.    if (olditem = ScrListFind(name)) {
  134.       if (olditem->sn_Address == address) res = 1;
  135.    }
  136. /*
  137. *   Else allocate a new node and open ourselves so we don't go away
  138. */
  139.    else {
  140.       if (ScrListAlloc(name, address)) {
  141.          ScrSharBase = OpenLibrary("screenshar.library", 0L);
  142.          res = 1;
  143.       }
  144.    }
  145.    Permit();
  146.    return(res);
  147. }
  148.  
  149. /**
  150. *
  151. *    NAME
  152. *
  153. *    PrivateScreen
  154. *    =============
  155. *
  156. *    SYNOPSIS
  157. *
  158. *    int result = PrivateScreen(Name)
  159. *       D0                         A0
  160. *
  161. *    FUNCTION
  162. *
  163. *    This function removes a named screen from the public screen list.
  164. *
  165. *    INPUTS
  166. *
  167. *    Name        Name of the public screen
  168. *
  169. *    RESULT
  170. *
  171. *    0 on failure, 1 on success.
  172. *    Note: the return code is a 16 bit int (a short).
  173. *
  174. *    ADDITIONAL    CONSIDERATIONS
  175. *
  176. *    This routine should be called by an application that has made itself
  177. *    the "host" to a named public screen through a call to PublicScreen().
  178. *    Before calling PrivateScreen(), the application should verify that no
  179. *    "symbionts" are currently present on the screen through a call to 
  180. *    PubScrLocked().
  181. *
  182. *    If the Name is not found in the public screen list, the function
  183. *    performs no operation and returns 0.
  184. *    If the Name is found, the current symbiont open count is checked.
  185. *    If the open count is non-zero, the function performs no operation
  186. *    and returns 0.
  187. *
  188. *    BUGS
  189. *
  190. *    None known.
  191. *
  192. *    AUTHOR
  193. *
  194. *    W.G.J. Langeveld (WGL)
  195. *
  196. **/
  197. int PrivateScreen(name)
  198. char *name;
  199. {
  200.    struct ScreenNode *olditem = NULL;
  201.    int res;
  202. /*
  203. *   Can't interrupt this
  204. */
  205.    Forbid();
  206.    res = 0;
  207. /*
  208. *   Try to find this name, if found, free node and close ourselves.
  209. */
  210.    if (olditem = ScrListFind(name)) {
  211.       if (olditem->sn_OpenCount == 0) {
  212.          ScrListFree(olditem);
  213.          if (ScrSharBase) CloseLibrary(ScrSharBase);
  214.          res = 1;
  215.       }
  216.    }
  217.    Permit();
  218.    return(res);
  219. }
  220.  
  221. /**
  222. *
  223. *    NAME
  224. *
  225. *    PubScrLocked
  226. *    ============
  227. *
  228. *    SYNOPSIS
  229. *
  230. *    int result = PubScrLocked(Name)
  231. *       D0                       A0
  232. *
  233. *    FUNCTION
  234. *
  235. *    This function returns the number of symbionts still open on this
  236. *    named screen.
  237. *
  238. *    INPUTS
  239. *
  240. *    Name        Name of the public screen
  241. *
  242. *    RESULT
  243. *
  244. *    Number of symbionts with windows still open on this screen.
  245. *    Note: the return code is a 16 bit int (a short).
  246. *
  247. *    ADDITIONAL    CONSIDERATIONS
  248. *
  249. *    This function should be used by an application that has made itself
  250. *    the "host" to a named public screen through a call to PublicScreen()
  251. *    in order to determine whether it is safe to call PrivateScreen().
  252. *
  253. *    If a screen with the given Name is not found, the function returns 0.
  254. *
  255. *    BUGS
  256. *
  257. *    None known.
  258. *
  259. *    AUTHOR
  260. *
  261. *    W.G.J. Langeveld (WGL)
  262. *
  263. **/
  264. int PubScrLocked(name)
  265. char *name;
  266. {
  267.    struct ScreenNode *olditem = NULL;
  268.    int res;
  269. /*
  270. *   Can't interrupt this
  271. */
  272.    Forbid();
  273.    res = 0;
  274.    if (olditem = ScrListFind(name)) res = olditem->sn_OpenCount;
  275.    Permit();
  276.  
  277.    return(res);
  278. }
  279.  
  280. /**
  281. *
  282. *    NAME
  283. *
  284. *    LockPubScreen
  285. *    =============
  286. *
  287. *    SYNOPSIS
  288. *
  289. *    struct Screen *ScreenPtr = LockPubScreen(Name)
  290. *       D0                                       A0
  291. *
  292. *    FUNCTION
  293. *
  294. *    This function returns the address of a named public screen, and 
  295. *    increments the screenshare.library's symbiont counter for this
  296. *    screen.
  297. *
  298. *    INPUTS
  299. *
  300. *    Name        Name of the public screen
  301. *
  302. *    RESULT
  303. *
  304. *    Pointer to the public screen, if found. NULL otherwise.
  305. *
  306. *    ADDITIONAL    CONSIDERATIONS
  307. *
  308. *    This function should be used by the symbiont in order to find
  309. *    the address of the Screen structure of the application that has declared
  310. *    its screen public. The symbiont should use UnlockPubScreen() whenever
  311. *    it has closed its window(s) on that screen, and not open any windows
  312. *    on that screen until after a call to LockPubScreen().
  313. *
  314. *    BUGS
  315. *
  316. *    None known.
  317. *
  318. *    AUTHOR
  319. *
  320. *    W.G.J. Langeveld (WGL)
  321. *
  322. **/
  323. struct Screen *LockPubScreen(name)
  324. char *name;
  325. {
  326.    struct Screen *res;
  327.    struct ScreenNode *olditem;
  328. /*
  329. *   Can't interrupt this
  330. */
  331.    Forbid();
  332.    res = 0L;
  333. /*
  334. *   Find the screen. If found, increment its counter. Return the address.
  335. */
  336.    if (olditem = ScrListFind(name)) {
  337.       olditem->sn_OpenCount++;
  338.       res = olditem->sn_Address;
  339.    }
  340.    Permit();
  341.    return(res);
  342. }
  343.  
  344. /**
  345. *
  346. *    NAME
  347. *
  348. *    UnlockPubScreen
  349. *    ===============
  350. *
  351. *    SYNOPSIS
  352. *
  353. *    struct Screen *ScreenPtr = UnlockPubScreen(Name)
  354. *       D0                                         A0
  355. *
  356. *    FUNCTION
  357. *
  358. *    This function decrements the symbiont counter of the named screen.
  359. *
  360. *    INPUTS
  361. *
  362. *    Name        Name of the public screen
  363. *
  364. *    RESULT
  365. *
  366. *    Guaranteed NULL.
  367. *
  368. *    ADDITIONAL    CONSIDERATIONS
  369. *
  370. *    This function should be used by the symbiont in order to decrement the
  371. *    the symbiont counter of the named screen to signal it has closed its
  372. *    window(s) on that screen. The symbiont should use LockPubScreen()
  373. *    before opening any windows on that screen, and not call UnlockPubScreen()
  374. *    until it has closed its window(s) on that screen.
  375. *
  376. *    BUGS
  377. *
  378. *    None known.
  379. *
  380. *    AUTHOR
  381. *
  382. *    W.G.J. Langeveld (WGL)
  383. *
  384. **/
  385. struct Screen *UnlockPubScreen(name)
  386. char *name;
  387. {
  388.    struct Screen *res;
  389.    struct ScreenNode *olditem;
  390. /*
  391. *   Can't interrupt this
  392. */
  393.    Forbid();
  394.    res = 0L;
  395. /*
  396. *   First find the screen. If found, decrement its counter.
  397. */
  398.    if (olditem = ScrListFind(name)) {
  399.       if (olditem->sn_OpenCount != 0) olditem->sn_OpenCount--;
  400.       res = 0L;
  401.    }
  402.    Permit();
  403.    return(res);
  404. }
  405.  
  406.  
  407.  
  408. /**
  409. *
  410. *   The following are local routines, not accessible from the outside world
  411. *   =======================================================================
  412. *
  413. *   Routine to add another node to the Screen list.
  414. *
  415. **/
  416. #define SNSIZE ((long) sizeof(struct ScreenNode))
  417. #define SLSIZE ((long) sizeof(struct List))
  418.  
  419. static struct ScreenNode *ScrListAlloc(s, scr)
  420. char *s;
  421. struct Screen *scr;
  422. {
  423.    struct ScreenNode *sn;
  424.  
  425. /*
  426. *   If no list exists, create one
  427. */
  428.    if (ScreenList == NULL) {
  429.       ScreenList = (struct List *) AllocMem(SLSIZE, MEMF_PUBLIC | MEMF_CLEAR);
  430.       if (!ScreenList) return(NULL);
  431.       NewList(ScreenList);
  432.    }
  433. /*
  434. *   Create a node
  435. */
  436.    sn = (struct ScreenNode *) AllocMem(SNSIZE, MEMF_PUBLIC | MEMF_CLEAR);
  437.    if (sn) {
  438. /*
  439. *   Allocate room for the name
  440. */
  441.       sn->sn_Node.ln_Name = (char *)
  442.          AllocMem((long) (strlen(s) + 1), MEMF_PUBLIC | MEMF_CLEAR);
  443.       if (sn->sn_Node.ln_Name) {
  444. /*
  445. *   ...and copy the name
  446. */
  447.          strcpy(sn->sn_Node.ln_Name, s);
  448. /*
  449. *   Copy the address and zero the open count.
  450. */
  451.          sn->sn_Address = scr;
  452.          sn->sn_OpenCount = 0;
  453. /*
  454. *   Add this one to the list
  455. */
  456.          AddTail(ScreenList, sn);
  457.       }
  458.    }
  459.    return(sn);
  460. }
  461.  
  462. /**
  463. *
  464. *   Free a ScreenNode node
  465. *
  466. **/
  467. static struct ScreenNode *ScrListFree(item)
  468. struct ScreenNode *item;
  469. {
  470.    if (item == 0L)       return(0L);
  471.    if (ScreenList == 0L) return(0L);
  472. /*
  473. *   Isolate this item from the list.
  474. */
  475.    Remove(item);
  476. /*
  477. *   Free the string
  478. */
  479.    if (item->sn_Node.ln_Name) 
  480.       FreeMem(item->sn_Node.ln_Name, (long) (strlen(item->sn_Node.ln_Name) + 1));
  481. /*
  482. *   Free the item
  483. */
  484.    FreeMem(item, SNSIZE);
  485. /*
  486. *   If this is the last item, free the list.
  487. */
  488.    if (ScreenList->lh_TailPred == ScreenList) {
  489.       FreeMem(ScreenList, SLSIZE);
  490.       ScreenList = NULL;
  491.    }
  492.  
  493.    return(0L);
  494. }
  495.  
  496. /**
  497. *
  498. *   Find a screen with a certain name
  499. *
  500. **/
  501. static struct ScreenNode *ScrListFind(name)
  502. char *name;
  503. {
  504. /*
  505. *   If the name is null or there is no header, return
  506. */
  507.    if (name == 0L)       return(0L);
  508.    if (ScreenList == 0L) return(0L);
  509. /*
  510. *   Find it
  511. */
  512.    return((struct ScreenNode *) FindName(ScreenList, name));
  513. }
  514.