Uses GNU autoconf 2.3.
[ir-tcl-moved-to-github.git] / tclmain.c
1 /*
2  * IR toolkit for tcl/tk
3  * (c) Index Data 1995
4  * See the file LICENSE for details.
5  * Sebastian Hammer, Adam Dickmeiss
6  *
7  * $Log: tclmain.c,v $
8  * Revision 1.7  1995-06-21 11:04:54  adam
9  * Uses GNU autoconf 2.3.
10  * Install procedure implemented.
11  * boook bitmaps moved to sub directory bitmaps.
12  *
13  * Revision 1.6  1995/05/29  08:44:28  adam
14  * Work on delete of objects.
15  *
16  * Revision 1.5  1995/03/20  08:53:30  adam
17  * Event loop in tclmain.c rewritten. New method searchStatus.
18  *
19  * Revision 1.4  1995/03/17  07:50:31  adam
20  * Headers have changed a little.
21  *
22  */
23
24 #include <unistd.h>
25 #include <sys/time.h>
26 #include <sys/types.h>
27 #if HAVE_SYS_SELECT_H
28 #include <sys/select.h>
29 #endif
30 #include <assert.h>
31
32 #include <tcl.h>
33
34 #include "ir-tcl.h"
35
36 static char *fileName = NULL;
37
38 /* select(2) callbacks */
39 struct callback {
40     void (*r_handle)(void *p);
41     void (*w_handle)(void *p);
42     void (*x_handle)(void *p);
43     void *obj;
44 };
45 #define MAX_CALLBACK 200
46
47 static struct callback callback_table[MAX_CALLBACK];
48 static int max_fd = 3;            /* don't worry: it will grow... */
49
50 void tcl_mainloop (Tcl_Interp *interp, int interactive);
51
52 int Tcl_AppInit (Tcl_Interp *interp)
53 {
54     if (Tcl_Init(interp) == TCL_ERROR)
55         return TCL_ERROR;
56     if (ir_tcl_init(interp) == TCL_ERROR)
57         return TCL_ERROR;
58     return TCL_OK;
59 }
60
61 int main (int argc, char **argv)
62 {
63     Tcl_Interp *interp;
64     int code;
65     int i;
66
67     interp = Tcl_CreateInterp();
68     Tcl_SetVar (interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
69     if (argc == 2)
70         fileName = argv[1];
71
72     if (Tcl_AppInit(interp) != TCL_OK) {
73         fprintf(stderr, "Tcl_AppInit failed: %s\n", interp->result);
74     }
75     for (i=0; i<MAX_CALLBACK; i++)
76     {
77         callback_table[i].r_handle = NULL;
78         callback_table[i].w_handle = NULL;
79         callback_table[i].x_handle = NULL;
80     }
81     if (fileName)
82     {
83         code = Tcl_EvalFile (interp, fileName);
84         if (*interp->result != 0)
85             printf ("%s\n", interp->result);
86         if (code != TCL_OK)
87             exit (1);
88         tcl_mainloop (interp, 0);
89     }
90     else
91     {
92         Tcl_SetVar (interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY);
93         tcl_mainloop (interp, 1);
94     }
95     exit (0);
96 }
97
98 void tcl_mainloop (Tcl_Interp *interp, int interactive)
99 {
100     int i;
101     int res;
102     Tcl_DString command;
103     static fd_set fdset_tcl_r;
104     static fd_set fdset_tcl_w;
105     static fd_set fdset_tcl_x;
106     int min_fd;
107
108     min_fd = interactive ? 3 : 0;
109     if (interactive)
110     {
111         Tcl_DStringInit (&command);
112         printf ("[TCL]"); fflush (stdout);
113     }
114     while (1)
115     {
116         FD_ZERO (&fdset_tcl_r);
117         FD_ZERO (&fdset_tcl_w);
118         FD_ZERO (&fdset_tcl_x);
119         if (interactive)
120             FD_SET (0, &fdset_tcl_r);
121         for (res=0, i=min_fd; i<=max_fd; i++)
122         {
123             if (callback_table[i].w_handle)
124             {
125                 FD_SET (i, &fdset_tcl_w);
126                 res++;
127             }
128             if (callback_table[i].r_handle)
129             {
130                 FD_SET (i, &fdset_tcl_r);
131                 res++;
132             }
133             if (callback_table[i].x_handle)
134             {
135                 FD_SET (i, &fdset_tcl_x);
136                 res++;
137             }
138         }
139         if (!interactive && !res)
140             return;
141         if ((res = select(max_fd+1, &fdset_tcl_r, &fdset_tcl_w, 
142                           &fdset_tcl_x, 0)) < 0)
143         {
144             perror("select");
145             exit(1);
146         }
147         if (!res)
148             continue;
149         for (i=min_fd; i<=max_fd; i++)
150         {
151             if (FD_ISSET (i, &fdset_tcl_r))
152             {
153                 assert (callback_table[i].r_handle);
154                 (*callback_table[i].r_handle) (callback_table[i].obj);
155             }
156             if (FD_ISSET (i, &fdset_tcl_w))
157             {
158                 assert (callback_table[i].w_handle);
159                 (*callback_table[i].w_handle) (callback_table[i].obj);
160             }
161             if (FD_ISSET (i, &fdset_tcl_x))
162             {
163                 assert (callback_table[i].x_handle);
164                 (*callback_table[i].x_handle) (callback_table[i].obj);
165             }
166         }
167         if (interactive && FD_ISSET(0, &fdset_tcl_r))
168         {
169             char input_buf[256];
170             int count = read (0, input_buf, 256);
171
172             if (count <= 0)
173                 exit (0);
174             Tcl_DStringAppend (&command, input_buf, count);
175             if (Tcl_CommandComplete (Tcl_DStringValue (&command)))
176             {
177                 int code = Tcl_Eval (interp, Tcl_DStringValue (&command));
178                 Tcl_DStringFree (&command);
179                 if (code)
180                     printf ("[ERR:%s]\n", interp->result);
181                 else
182                     printf ("[RES:%s]\n", interp->result);
183                 printf ("[TCL]"); fflush (stdout);
184             }
185         }
186     }
187 }
188
189 void ir_select_add (int fd, void *obj)
190 {
191     callback_table[fd].obj = obj;
192     callback_table[fd].r_handle = ir_select_read;
193     callback_table[fd].w_handle = NULL;
194     callback_table[fd].x_handle = NULL;
195     if (fd > max_fd)
196         max_fd = fd;
197 }
198
199 void ir_select_add_write (int fd, void *obj)
200 {
201     callback_table[fd].w_handle = ir_select_write;
202     if (fd > max_fd)
203         max_fd = fd;
204 }
205
206 void ir_select_remove_write (int fd, void *obj)
207 {
208     callback_table[fd].w_handle = NULL;
209 }
210
211 void ir_select_remove (int fd, void *obj)
212 {
213     callback_table[fd].r_handle = NULL;
214     callback_table[fd].w_handle = NULL;
215     callback_table[fd].x_handle = NULL;
216 }