Initial import of the CDE 2.1.30 sources from the Open Group.
[oweals/cde.git] / cde / lib / DtSvc / DtEncap / spc-xt.c
1 /*
2  * File:         spc-xt.c $TOG: spc-xt.c /main/6 1998/03/16 14:41:02 mgreess $
3  * Language:     C
4  *
5  * (c) Copyright 1989, Hewlett-Packard Company, all rights reserved.
6  *
7  * (c) Copyright 1993, 1994 Hewlett-Packard Company                     *
8  * (c) Copyright 1993, 1994 International Business Machines Corp.       *
9  * (c) Copyright 1993, 1994 Sun Microsystems, Inc.                      *
10  * (c) Copyright 1993, 1994 Novell, Inc.                                *
11  */
12
13 #define __need_fd_set
14
15 #include <bms/sbport.h> /* NOTE: sbport.h must be the first include. */
16 #include <time.h>
17 #include <SPC/spcP.h>
18 /* #include <bms/SbEvent.h>  */ /* This file now included by spcP.h */
19 #include "DtSvcLock.h"
20
21 /* Externals */
22
23 extern int break_on_termination;
24
25 /* Utility functions */
26
27 /* First, declarations */
28
29 typedef struct {
30   SbInputId                     read_id;
31   SbInputId                     except_id;
32 } SPC_Callback_Struct;
33
34 static SPC_Callback_Struct **SPC_Fd_Mapping = NULL;
35
36 #define SPC_LOOKUP_FD_MAPPING(fd)   SPC_Fd_Mapping[(fd)]
37
38 static Boolean spc_xe_termination_flag;
39
40 /*-----------------------------------------------------------------------+*/
41 static int SPC_AddInput(int                     source,
42                  SPC_Callback_Condition         condition,
43                  SbInputId                      id)
44 /*-----------------------------------------------------------------------+*/
45 {
46   SPC_Callback_Struct *structptr = NULL;
47
48   _DtSvcProcessLock();
49   if (SPC_Fd_Mapping == NULL) {
50     SPC_Fd_Mapping = (SPC_Callback_Struct **) 
51                      XeMalloc (FD_SETSIZE * sizeof (SPC_Callback_Struct *));
52     memset(SPC_Fd_Mapping, NULL, FD_SETSIZE * sizeof(SPC_Callback_Struct *));
53   }
54   structptr=SPC_LOOKUP_FD_MAPPING(source);
55
56   if(!structptr) {
57     structptr=(SPC_Callback_Struct *) XeMalloc(sizeof(SPC_Callback_Struct));
58     SPC_LOOKUP_FD_MAPPING(source)=structptr;
59   }
60   _DtSvcProcessUnlock();
61
62   switch (condition) {
63
64   case SPC_Input:
65   case SPC_Terminator:
66   case SPC_Client:
67     structptr->read_id   = id;
68     break;
69
70   case SPC_Exception:
71     structptr->except_id = id;
72     break;
73
74   default:
75     break;
76   }
77
78   return(source);
79 }
80
81
82 /*-----------------------------------------------------------------------+*/
83 static SbInputId SPC_RemoveInput(int                     source,
84                           SPC_Callback_Condition condition)
85 /*-----------------------------------------------------------------------+*/
86 {
87   SPC_Callback_Struct *structptr = NULL;
88   
89   _DtSvcProcessLock();
90   if (SPC_Fd_Mapping == NULL) {
91     SPC_Fd_Mapping = (SPC_Callback_Struct **) 
92                      XeMalloc (FD_SETSIZE * sizeof (SPC_Callback_Struct *));
93     memset(SPC_Fd_Mapping, NULL, FD_SETSIZE * sizeof(SPC_Callback_Struct *));
94   }
95   structptr=SPC_LOOKUP_FD_MAPPING(source);
96   _DtSvcProcessUnlock();
97
98   switch(condition) {
99     
100   case SPC_Input:
101   case SPC_Terminator:
102   case SPC_Client:
103      return structptr->read_id;
104
105   case SPC_Exception:
106      return structptr->except_id;
107     
108   }
109
110   return NULL;
111 }
112   
113 /*-----------------------------------------------------------------------+*/
114 static SPC_Select(void )
115 /*-----------------------------------------------------------------------+*/
116 {
117     break_on_termination=TRUE;
118
119     _DtSvcProcessLock();
120     spc_xe_termination_flag= FALSE;
121
122     /* Use a function pointer so we don't have explict dependancy */
123     /* on libXe.a                                                   */
124     /* ---------------------------------------------------------- */
125     if (SbMainLoopUntil_hookfn == NULL)
126       (void) fprintf (stderr, "Error: SbMainLoopUntil = NULL\n");
127     else
128       (*SbMainLoopUntil_hookfn)(&spc_xe_termination_flag);
129     _DtSvcProcessUnlock();
130
131     break_on_termination=FALSE;
132     return(TRUE);
133 }
134
135
136 /*-----------------------------------------------------------------------+*/
137 int SPC_Wait_For_Termination(SPC_Channel_Ptr channel)
138 /*-----------------------------------------------------------------------+*/
139 {
140   int result;
141   
142   call_parent_method(channel, wait_for_termination, (channel), result);
143   
144   if(result==SPC_ERROR) return(SPC_ERROR);
145
146   do {
147
148     if(SPC_Select() == SPC_ERROR)
149       return(SPC_ERROR);
150     
151   } while(IS_ACTIVE(channel));
152   
153   return(TRUE);
154   
155 }
156
157
158 /*-----------------------------------------------------------------------+*/
159 void SPC_XtBreak(void)
160 /*-----------------------------------------------------------------------+*/
161 {
162   _DtSvcProcessLock();
163   if(!spc_xe_termination_flag) {
164      spc_xe_termination_flag = TRUE;
165      if (SbBreakMainLoop_hookfn == NULL)
166        (void) fprintf (stderr, "Error: SbBreakMainLoop = NULL\n");
167      else
168        (*SbBreakMainLoop_hookfn)();      
169   } 
170   _DtSvcProcessUnlock();
171 }
172
173
174   
175 /*-----------------------------------------------------------------------+*/
176 void SPC_XtAddInput(SPC_Channel_Ptr channel,
177                     int *id_addr,
178                     int fd,
179                     spc_handler_func_type handler,
180                     SPC_Callback_Condition condition)
181 /*-----------------------------------------------------------------------+*/
182 {
183   SbInputId id;
184   
185   switch(condition) {
186     
187   case SPC_Input:
188   case SPC_Terminator:
189   case SPC_Client:
190     /* fprintf(stderr, "SPC add input/terminator for %d\n", fd); */
191     if (SbAddInput_hookfn == NULL)
192       (void) fprintf (stderr, "Error: SbAddInput = NULL\n");
193     else
194       id = (*SbAddInput_hookfn)(fd, handler, channel);
195     break;
196     
197   case SPC_Exception:
198     /* fprintf(stderr, "SPC add exception for %d\n", fd); */
199     if (SbAddException_hookfn == NULL)
200       (void) fprintf (stderr, "Error: SbAddException = NULL\n");
201     else
202       id = (*SbAddException_hookfn)(fd, handler, channel);
203     break;
204     
205   }
206   
207   *id_addr=SPC_AddInput(fd, condition, id);
208 }
209
210
211 /*-----------------------------------------------------------------------+*/
212 void SPC_XtRemoveInput(int *id_addr, 
213                        SPC_Callback_Condition condition)
214 /*-----------------------------------------------------------------------+*/
215 {
216   if((*id_addr) != -1) {
217     
218     switch(condition) {
219       
220     case SPC_Input:
221     case SPC_Terminator:
222     case SPC_Client:
223       /* fprintf(stderr, "SPC remove input/terminator\n"); */
224       if (SbRemoveInput_hookfn == NULL)
225         (void) fprintf (stderr, "Error: SbRemoveInput = NULL\n");
226       else
227         (*SbRemoveInput_hookfn)(SPC_RemoveInput(*id_addr, condition));
228       break;
229       
230     case SPC_Exception:
231       /* fprintf(stderr, "SPC remove exception"); */
232       if (SbRemoveException_hookfn == NULL)
233         (void) fprintf (stderr, "Error: SbRemoveException = NULL\n");
234       else
235         (*SbRemoveException_hookfn)(SPC_RemoveInput(*id_addr, condition));
236       break;
237       
238     }
239     
240     *id_addr=(-1);
241   }
242 }