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