Tcl7.5 Generic file handling.
[ir-tcl-moved-to-github.git] / select.c
1 /*
2  * IR toolkit for tcl/tk
3  * (c) Index Data 1996
4  * See the file LICENSE for details.
5  * Sebastian Hammer, Adam Dickmeiss
6  *
7  * $Log: select.c,v $
8  * Revision 1.1  1996-08-20 09:33:23  adam
9  * Tcl7.5 Generic file handling.
10  *
11  */
12
13 #include <tcl.h>
14 #include <log.h>
15 #include "ir-tcl.h"
16
17 #if TCL_MAJOR_VERSION > 7 || (TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION > 4)
18
19 #define IRTCL_USE_TIMER 0
20
21 struct sel_proc {
22     void (*f)(ClientData clientData, int r, int w, int e);
23     ClientData clientData;
24     int fd;
25 #if IRTCL_USE_TIMER
26     int mask;
27     Tcl_TimerToken timer_token;
28 #else
29     Tcl_File tcl_File;
30 #endif
31     struct sel_proc *next;
32 };
33
34 static struct sel_proc *sel_proc_list = NULL;
35
36 #if IRTCL_USE_TIMER
37 static void ir_tcl_timer_proc (ClientData clientData)
38 {
39     struct sel_proc *sp = (struct sel_proc *) clientData;
40
41     if (!sp->f)
42         return ;
43     sp->timer_token =
44         Tcl_CreateTimerHandler (250, ir_tcl_timer_proc, clientData);
45     (*sp->f)(sp->clientData, sp->mask & TCL_READABLE, sp->mask & TCL_WRITABLE,
46              sp->mask & TCL_EXCEPTION);
47     
48 }
49
50 void ir_tcl_select_set (void (*f)(ClientData clientData, int r, int w, int e),
51                         int fd, ClientData clientData, int r, int w, int e)
52 {
53     int mask = 0;
54     struct sel_proc **sp = &sel_proc_list;
55
56     if (r)
57         mask |= TCL_READABLE;
58     if (w)
59         mask |= TCL_WRITABLE;
60     if (e)
61         mask |= TCL_EXCEPTION;
62     while (*sp)
63     {
64         if ((*sp)->fd == fd)
65             break;
66         sp = &(*sp)->next;
67     }
68     if (!*sp)
69     {
70         *sp = ir_tcl_malloc (sizeof(**sp));
71         (*sp)->next = NULL;
72         (*sp)->fd = fd;
73         (*sp)->timer_token =
74             Tcl_CreateTimerHandler (250, ir_tcl_timer_proc, *sp);
75     }
76     (*sp)->mask = TCL_READABLE|TCL_WRITABLE;
77     (*sp)->f = f;
78     (*sp)->clientData = clientData;
79     if (!f)
80     {
81         struct sel_proc *sp_tmp = *sp;
82         Tcl_DeleteTimerHandler ((*sp)->timer_token);
83         *sp = (*sp)->next;
84         xfree (sp_tmp);
85     }
86 }
87
88 #else
89 static void ir_tcl_tk_select_proc (ClientData clientData, int mask)
90 {
91     struct sel_proc *sp = (struct sel_proc *) clientData;
92
93     if (!sp->f)
94         return ;
95     (*sp->f)(sp->clientData, mask & TCL_READABLE, mask & TCL_WRITABLE,
96              mask & TCL_EXCEPTION);
97 }
98
99 void ir_tcl_select_set (void (*f)(ClientData clientData, int r, int w, int e),
100                         int fd, ClientData clientData, int r, int w, int e)
101 {
102     int mask = 0;
103     struct sel_proc *sp = sel_proc_list;
104
105     if (r)
106         mask |= TCL_READABLE;
107     if (w)
108         mask |= TCL_WRITABLE;
109     if (e)
110         mask |= TCL_EXCEPTION;
111     while (sp)
112     {
113         if (sp->fd == fd)
114              break;
115         sp = sp->next;
116     }
117     if (!sp)
118     {
119         sp = ir_tcl_malloc (sizeof(*sp));
120         sp->next = sel_proc_list;
121         sel_proc_list = sp;
122         sp->fd = fd;
123 #if WINDOWS
124         sp->tcl_File = Tcl_GetFile ((ClientData) fd, TCL_WIN_SOCKET);
125 #else
126         sp->tcl_File = Tcl_GetFile ((ClientData) fd, TCL_UNIX_FD);
127 #endif
128     }
129     sp->f = f;
130     sp->clientData = clientData;
131     if (f)
132         Tcl_CreateFileHandler (sp->tcl_File, mask, ir_tcl_tk_select_proc, sp);
133     else
134         Tcl_DeleteFileHandler (sp->tcl_File);
135 }
136 #endif
137
138 #endif