2 * Copyright 2002-2003 Red Hat Inc., Durham, North Carolina.
6 * Permission is hereby granted, free of charge, to any person obtaining
7 * a copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation on the rights to use, copy, modify, merge,
10 * publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial
16 * portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * Rickard E. (Rik) Faith <faith@redhat.com>
36 * Provides an interface for handling SIGIO signals for input devices. */
38 #ifdef HAVE_DMX_CONFIG_H
39 #include <dmx-config.h>
43 #include "dmxinputinit.h"
45 #include "dmxevents.h"
50 static int dmxFdCount
= 0;
51 static Bool dmxInputEnabled
= TRUE
;
53 /* Define equivalents for non-POSIX systems (e.g., SGI IRIX, Solaris) */
56 #define O_ASYNC FASYNC
62 #define O_NONBLOCK FNONBLK
66 dmxSigioHandler(int sig
)
69 DMXInputInfo
*dmxInput
;
71 for (i
= 0, dmxInput
= &dmxInputs
[0]; i
< dmxNumInputs
; i
++, dmxInput
++) {
72 if (dmxInput
->sigioState
== DMX_ACTIVESIGIO
) {
73 for (j
= 0; j
< dmxInput
->numDevs
; j
++) {
74 DMXLocalInputInfoPtr dmxLocal
= dmxInput
->devs
[j
];
76 if (dmxLocal
->collect_events
) {
77 dmxLocal
->collect_events(&dmxLocal
->pDevice
->public,
80 dmxCheckSpecialKeys
, DMX_NO_BLOCK
);
93 memset(&a
, 0, sizeof(a
));
94 a
.sa_handler
= dmxSigioHandler
;
95 sigemptyset(&a
.sa_mask
);
96 sigaddset(&a
.sa_mask
, SIGIO
);
97 sigaddset(&a
.sa_mask
, SIGALRM
);
98 sigaddset(&a
.sa_mask
, SIGVTALRM
);
99 sigaction(SIGIO
, &a
, 0);
102 sigprocmask(SIG_SETMASK
, &s
, 0);
110 memset(&a
, 0, sizeof(a
));
111 a
.sa_handler
= SIG_IGN
;
112 sigemptyset(&a
.sa_mask
);
113 sigaction(SIGIO
, &a
, 0);
117 dmxSigioAdd(DMXInputInfo
* dmxInput
)
122 switch (dmxInput
->sigioState
) {
126 dmxInput
->sigioState
= DMX_ACTIVESIGIO
;
128 case DMX_ACTIVESIGIO
:
132 for (i
= 0; i
< dmxInput
->sigioFdCount
; i
++) {
133 if (!dmxInput
->sigioAdded
[i
]) {
134 int fd
= dmxInput
->sigioFd
[i
];
136 fcntl(fd
, F_SETOWN
, getpid());
137 flags
= fcntl(fd
, F_GETFL
);
138 flags
|= O_ASYNC
| O_NONBLOCK
;
139 fcntl(fd
, F_SETFL
, flags
);
141 AddEnabledDevice(fd
);
142 dmxInput
->sigioAdded
[i
] = TRUE
;
144 if (++dmxFdCount
== 1)
151 dmxSigioRemove(DMXInputInfo
* dmxInput
)
156 switch (dmxInput
->sigioState
) {
161 case DMX_ACTIVESIGIO
:
162 dmxInput
->sigioState
= DMX_USESIGIO
;
166 for (i
= 0; i
< dmxInput
->sigioFdCount
; i
++) {
167 if (dmxInput
->sigioAdded
[i
]) {
168 int fd
= dmxInput
->sigioFd
[i
];
170 dmxInput
->sigioAdded
[i
] = FALSE
;
171 RemoveEnabledDevice(fd
);
173 flags
= fcntl(fd
, F_GETFL
);
174 flags
&= ~(O_ASYNC
| O_NONBLOCK
);
175 fcntl(fd
, F_SETFL
, flags
);
183 /** Enable SIGIO handling. This instantiates the handler with the OS. */
185 dmxSigioEnableInput(void)
188 DMXInputInfo
*dmxInput
;
190 dmxInputEnabled
= TRUE
;
191 for (i
= 0, dmxInput
= &dmxInputs
[0]; i
< dmxNumInputs
; i
++, dmxInput
++)
192 dmxSigioAdd(dmxInput
);
195 /** Disable SIGIO handling. This removes the hanlder from the OS. */
197 dmxSigioDisableInput(void)
200 DMXInputInfo
*dmxInput
;
202 dmxInputEnabled
= FALSE
;
203 for (i
= 0, dmxInput
= &dmxInputs
[0]; i
< dmxNumInputs
; i
++, dmxInput
++)
204 dmxSigioRemove(dmxInput
);
207 /** Make a note that the input device described in \a dmxInput will be
208 * using the file descriptor \a fd for SIGIO signals. Calls
209 * AddEnabledDevice ifi SIGIO handling has been enabled with
210 * #dmxSigioEnableInput(). */
212 dmxSigioRegister(DMXInputInfo
* dmxInput
, int fd
)
214 dmxInput
->sigioState
= DMX_USESIGIO
;
215 if (dmxInput
->sigioFdCount
>= DMX_MAX_SIGIO_FDS
)
216 dmxLog(dmxFatal
, "Too many SIGIO file descriptors (%d >= %d)\n",
217 dmxInput
->sigioFdCount
, DMX_MAX_SIGIO_FDS
);
219 dmxInput
->sigioFd
[dmxInput
->sigioFdCount
++] = fd
;
221 dmxSigioAdd(dmxInput
);
224 /** Remove the notes that \a dmxInput is using any file descriptors for
225 * SIGIO signals. Calls RemoveEnabledDevice. */
227 dmxSigioUnregister(DMXInputInfo
* dmxInput
)
229 if (dmxInput
->sigioState
== DMX_NOSIGIO
)
231 dmxSigioRemove(dmxInput
);
232 dmxInput
->sigioState
= DMX_NOSIGIO
;
233 dmxInput
->sigioFdCount
= 0;