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 >
Wrap
C/C++ Source or Header
|
1988-08-11
|
6KB
|
173 lines
/*=======================================================*/
/* TVMASYNC.C */
/* */
/* (c) Copyright 1988 Ralf Brown All Rights Reserved */
/* May be freely copied for noncommercial use, so long */
/* as this copyright notice remains intact, and any */
/* changes are marked in the comment blocks preceding */
/* functions. */
/*=======================================================*/
#include <stdio.h>
#include "tvapi.h"
#include "tvstream.h"
/*=======================================================*/
#define MIN_STACK 256
typedef struct _local_stack
{
void far (*func)(void) ; /* _TV_notify_handler relies on the */
int top ; /* positions of these two fields */
struct _local_stack *next ;
OBJECT window ;
int events ;
/* actual stack goes here, by allocating more than the size of this struct */
} LOCAL_STACK ;
/*=======================================================*/
static LOCAL_STACK *local_stacks = NULL ;
/*=======================================================*/
/*=======================================================*/
static LOCAL_STACK *make_local_stack(OBJECT win,void far (*func)(void),int size)
{
LOCAL_STACK *stack ;
if ((stack = malloc(sizeof(LOCAL_STACK)+size)) == NULL)
return NULL ;
stack->window = win ;
stack->func = func ;
stack->top = (int)stack + sizeof(LOCAL_STACK) + size ;
stack->events = 0 ;
stack->next = local_stacks ;
local_stacks = stack ;
return stack ;
}
/*=======================================================*/
/*=======================================================*/
static void free_local_stack(OBJECT win)
{
LOCAL_STACK *prev, *stack ;
prev = NULL ;
stack = local_stacks ;
while (stack && stack->window != win)
{
prev = stack ;
stack = stack->next ;
}
if (stack)
{
if (prev)
prev->next = stack->next ;
else
local_stacks = local_stacks->next ;
free(stack) ;
}
}
/*=======================================================*/
/* TVwin_async set asynchronous notification function */
/* Ralf Brown 4/4/88 */
/* Ralf Brown 8/11/88 rewritten */
/*=======================================================*/
int pascal TVwin_async(OBJECT win,void far (*func)(void),int stacksize)
{
LOCAL_STACK *stack ;
BYTE stream[] = { S_MANAGER(10), MS_PRIM_ASYNC, 0,0,0,0,
MS_SEC_ASYNC, 0,0,0,0 } ;
int events ;
if (func)
{
if (stacksize == 0)
stacksize = 512 ;
else if (stacksize < MIN_STACK)
stacksize = MIN_STACK ;
stack = local_stacks ;
while (stack && stack->window != win)
stack = stack->next ;
/* only allocate a new stack if there wasn't one or we need more */
/* space */
if (stack == NULL)
stack = make_local_stack(win,func,stacksize) ;
else if (stack->top - sizeof(LOCAL_STACK) - (int) stack < stacksize)
{
events = stack->events ;
free_local_stack(win) ;
stack = make_local_stack(win,func,stacksize) ;
stack->events = events ;
}
if (stack)
{
*((unsigned far **)(stream+5)) = (unsigned far *) _TVnotify_handler ;
*((unsigned far **)(stream+10)) = (unsigned far *) stack ;
}
else
return EOF ;
}
else
{
free_local_stack(win) ;
*((unsigned far **)(stream+5)) = (unsigned far *) 0 ;
*((unsigned far **)(stream+10)) = (unsigned far *) 0 ;
}
TVwin_stream(win,stream) ;
return 0 ;
}
/*=======================================================*/
/* TVwin_notify enable notification of specific event */
/* Ralf Brown 4/4/88 */
/* Ralf Brown 8/11/88 rewritten */
/*=======================================================*/
void pascal TVwin_notify(OBJECT win,int event)
{
LOCAL_STACK *stack ;
BYTE stream[] = { S_MANAGER(1), 0 } ; /* by not making it static, this function */
/* becomes reentrant */
stream[4] = event | MS_NOTIFY ;
TVwin_stream(win,stream) ;
stack = local_stacks ;
while (stack && stack->window != win)
stack = stack->next ;
if (stack)
stack->events |= (1 << event) ;
}
/*=======================================================*/
/* TVwin_cancel cancel notification of specific event */
/* Ralf Brown 4/4/88 */
/* Ralf Brown 8/11/88 rewritten */
/*=======================================================*/
void pascal TVwin_cancel(OBJECT win,int event,int release)
{
LOCAL_STACK *stack ;
BYTE stream[] = { S_MANAGER(1), 0 } ; /* by not making it static, this function */
/* becomes reentrant */
stream[4] = event | MS_NONOTIFY ;
TVwin_stream(win,stream) ;
stack = local_stacks ;
while (stack && stack->window != win)
stack = stack->next ;
if (stack)
{
stack->events &= ~(1 << event) ;
if (stack->events == 0 && release)
TVwin_async(win,NULL,0) ;
}
}
/* End of TVMASYNC.C */