home *** CD-ROM | disk | FTP | other *** search
/ Mega CD-ROM 1 / megacd_rom_1.zip / megacd_rom_1 / DESQVIEW / DVGLU101.ZIP / TVMASYNC.C < prev    next >
C/C++ Source or Header  |  1988-08-11  |  6KB  |  173 lines

  1. /*=======================================================*/
  2. /*  TVMASYNC.C                                           */
  3. /*                                                       */
  4. /*  (c) Copyright 1988 Ralf Brown  All Rights Reserved   */
  5. /*  May be freely copied for noncommercial use, so long  */
  6. /*  as this copyright notice remains intact, and any     */
  7. /*  changes are marked in the comment blocks preceding   */
  8. /*  functions.                                           */
  9. /*=======================================================*/
  10.  
  11. #include <stdio.h>
  12. #include "tvapi.h"
  13. #include "tvstream.h"
  14.  
  15. /*=======================================================*/
  16.  
  17. #define MIN_STACK 256
  18.  
  19. typedef struct _local_stack
  20.    {
  21.    void far (*func)(void) ;      /* _TV_notify_handler relies on the */
  22.    int top ;                     /* positions of these two fields */
  23.    struct _local_stack *next ;
  24.    OBJECT window ;
  25.    int events ;
  26.    /* actual stack goes here, by allocating more than the size of this struct */
  27.    } LOCAL_STACK ;
  28.  
  29. /*=======================================================*/
  30.  
  31. static LOCAL_STACK *local_stacks = NULL ;
  32.  
  33. /*=======================================================*/
  34. /*=======================================================*/
  35.  
  36. static LOCAL_STACK *make_local_stack(OBJECT win,void far (*func)(void),int size)
  37. {
  38.    LOCAL_STACK *stack ;
  39.  
  40.    if ((stack = malloc(sizeof(LOCAL_STACK)+size)) == NULL)
  41.       return NULL ;
  42.    stack->window = win ;
  43.    stack->func = func ;
  44.    stack->top = (int)stack + sizeof(LOCAL_STACK) + size ;
  45.    stack->events = 0 ;
  46.    stack->next = local_stacks ;
  47.    local_stacks = stack ;
  48.    return stack ;
  49. }
  50.  
  51. /*=======================================================*/
  52. /*=======================================================*/
  53.  
  54. static void free_local_stack(OBJECT win)
  55. {
  56.    LOCAL_STACK *prev, *stack ;
  57.  
  58.    prev = NULL ;
  59.    stack = local_stacks ;
  60.    while (stack && stack->window != win)
  61.       {
  62.       prev = stack ;
  63.       stack = stack->next ;
  64.       }
  65.    if (stack)
  66.       {
  67.       if (prev)
  68.          prev->next = stack->next ;
  69.       else
  70.          local_stacks = local_stacks->next ;
  71.       free(stack) ;
  72.       }
  73. }
  74.  
  75. /*=======================================================*/
  76. /* TVwin_async  set asynchronous notification function   */
  77. /*   Ralf Brown 4/4/88                                   */
  78. /*   Ralf Brown 8/11/88 rewritten                        */
  79. /*=======================================================*/
  80.  
  81. int pascal TVwin_async(OBJECT win,void far (*func)(void),int stacksize)
  82. {
  83.    LOCAL_STACK *stack ;
  84.    BYTE stream[] = { S_MANAGER(10), MS_PRIM_ASYNC, 0,0,0,0,
  85.                                     MS_SEC_ASYNC, 0,0,0,0 } ;
  86.    int events ;
  87.  
  88.    if (func)
  89.       {
  90.       if (stacksize == 0)
  91.          stacksize = 512 ;
  92.       else if (stacksize < MIN_STACK)
  93.          stacksize = MIN_STACK ;
  94.       stack = local_stacks ;
  95.       while (stack && stack->window != win)
  96.          stack = stack->next ;
  97.       /* only allocate a new stack if there wasn't one or we need more */
  98.       /* space */
  99.       if (stack == NULL)
  100.          stack = make_local_stack(win,func,stacksize) ;
  101.       else if (stack->top - sizeof(LOCAL_STACK) - (int) stack < stacksize)
  102.          {
  103.          events = stack->events ;
  104.          free_local_stack(win) ;
  105.          stack = make_local_stack(win,func,stacksize) ;
  106.          stack->events = events ;
  107.          }
  108.       if (stack)
  109.          {
  110.          *((unsigned far **)(stream+5)) = (unsigned far *) _TVnotify_handler ;
  111.          *((unsigned far **)(stream+10)) = (unsigned far *) stack ;
  112.          }
  113.       else
  114.          return EOF ;
  115.       }
  116.    else
  117.       {
  118.       free_local_stack(win) ;
  119.       *((unsigned far **)(stream+5)) = (unsigned far *) 0 ;
  120.       *((unsigned far **)(stream+10)) = (unsigned far *) 0 ;
  121.       }
  122.    TVwin_stream(win,stream) ;
  123.    return 0 ;
  124. }
  125.  
  126. /*=======================================================*/
  127. /* TVwin_notify  enable notification of specific event   */
  128. /*   Ralf Brown 4/4/88                                   */
  129. /*   Ralf Brown 8/11/88 rewritten                        */
  130. /*=======================================================*/
  131.  
  132. void pascal TVwin_notify(OBJECT win,int event)
  133. {
  134.    LOCAL_STACK *stack ;
  135.    BYTE stream[] = { S_MANAGER(1), 0 } ;  /* by not making it static, this function */
  136.                                           /* becomes reentrant */
  137.  
  138.    stream[4] = event | MS_NOTIFY ;
  139.    TVwin_stream(win,stream) ;
  140.    stack = local_stacks ;
  141.    while (stack && stack->window != win)
  142.       stack = stack->next ;
  143.    if (stack)
  144.       stack->events |= (1 << event) ;
  145. }
  146.  
  147. /*=======================================================*/
  148. /* TVwin_cancel  cancel notification of specific event   */
  149. /*   Ralf Brown 4/4/88                                   */
  150. /*   Ralf Brown 8/11/88 rewritten                        */
  151. /*=======================================================*/
  152.  
  153. void pascal TVwin_cancel(OBJECT win,int event,int release)
  154. {
  155.    LOCAL_STACK *stack ;
  156.    BYTE stream[] = { S_MANAGER(1), 0 } ;  /* by not making it static, this function */
  157.                                           /* becomes reentrant */
  158.  
  159.    stream[4] = event | MS_NONOTIFY ;
  160.    TVwin_stream(win,stream) ;
  161.    stack = local_stacks ;
  162.    while (stack && stack->window != win)
  163.       stack = stack->next ;
  164.    if (stack)
  165.       {
  166.       stack->events &= ~(1 << event) ;
  167.       if (stack->events == 0 && release)
  168.          TVwin_async(win,NULL,0) ;
  169.       }
  170. }
  171.  
  172. /* End of TVMASYNC.C */
  173.