1 | /* xf86sup.c -- Support for Holger Veit's xf86sup device driver
|
---|
2 | Copyright (c) 1995-1996 by Eberhard Mattes
|
---|
3 |
|
---|
4 | This file is part of emx.
|
---|
5 |
|
---|
6 | emx is free software; you can redistribute it and/or modify it
|
---|
7 | under the terms of the GNU General Public License as published by
|
---|
8 | the Free Software Foundation; either version 2, or (at your option)
|
---|
9 | any later version.
|
---|
10 |
|
---|
11 | emx is distributed in the hope that it will be useful,
|
---|
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
14 | GNU General Public License for more details.
|
---|
15 |
|
---|
16 | You should have received a copy of the GNU General Public License
|
---|
17 | along with emx; see the file COPYING. If not, write to
|
---|
18 | the Free Software Foundation, 59 Temple Place - Suite 330,
|
---|
19 | Boston, MA 02111-1307, USA.
|
---|
20 |
|
---|
21 | As special exception, emx.dll can be distributed without source code
|
---|
22 | unless it has been changed. If you modify emx.dll, this exception
|
---|
23 | no longer applies and you must remove this paragraph from all source
|
---|
24 | files for emx.dll. */
|
---|
25 |
|
---|
26 |
|
---|
27 | #define INCL_DOSDEVICES
|
---|
28 | #define INCL_DOSDEVIOCTL
|
---|
29 | #define INCL_DOSERRORS
|
---|
30 | #define INCL_DOSSEMAPHORES
|
---|
31 | #include <os2emx.h>
|
---|
32 | #include <sys/errno.h>
|
---|
33 | #include <sys/types.h>
|
---|
34 | #include <sys/fcntl.h>
|
---|
35 | #include <sys/ioctl.h>
|
---|
36 | #include <sys/so_ioctl.h>
|
---|
37 | #include <sys/termio.h> /* SysV */
|
---|
38 | #include <termios.h> /* POSIX.1 */
|
---|
39 | #include "emxdll.h"
|
---|
40 | #include "files.h"
|
---|
41 | #include "select.h"
|
---|
42 | #include "xf86sup.h"
|
---|
43 | #include "clib.h"
|
---|
44 |
|
---|
45 |
|
---|
46 | ULONG xf86sup_query (ULONG handle, ULONG *pflags)
|
---|
47 | {
|
---|
48 | struct xf86sup_drvid drvid;
|
---|
49 | ULONG rc, data_length;
|
---|
50 | my_file *d;
|
---|
51 |
|
---|
52 | memset (&drvid, 0, sizeof (drvid));
|
---|
53 | data_length = sizeof (drvid);
|
---|
54 | rc = DosDevIOCtl (handle, IOCTL_XF86SUP, XF86SUP_DRVID,
|
---|
55 | NULL, 0, NULL,
|
---|
56 | &drvid, data_length, &data_length);
|
---|
57 | if (rc != 0) return rc;
|
---|
58 | if (data_length != sizeof (drvid)
|
---|
59 | || drvid.magic != XF86SUP_MAGIC)
|
---|
60 | return ERROR_BAD_DEV_TYPE;
|
---|
61 | switch (drvid.id)
|
---|
62 | {
|
---|
63 | case XF86SUP_ID_PTY:
|
---|
64 | case XF86SUP_ID_TTY:
|
---|
65 | case XF86SUP_ID_CONSOLE:
|
---|
66 | case XF86SUP_ID_PMAP:
|
---|
67 | case XF86SUP_ID_FASTIO:
|
---|
68 | case XF86SUP_ID_PTMS:
|
---|
69 | break;
|
---|
70 | default:
|
---|
71 | return ERROR_BAD_DEV_TYPE;
|
---|
72 | }
|
---|
73 | *pflags = HF_XF86SUP;
|
---|
74 | d = GET_FILE (handle);
|
---|
75 | d->x.xf86sup.id = drvid.id;
|
---|
76 | d->x.xf86sup.sem_open = FALSE;
|
---|
77 | d->x.xf86sup.sem = 0;
|
---|
78 | return 0;
|
---|
79 | }
|
---|
80 |
|
---|
81 |
|
---|
82 | int xf86sup_avail (ULONG handle, int *errnop)
|
---|
83 | {
|
---|
84 | ULONG rc, data_length, avail;
|
---|
85 |
|
---|
86 | data_length = sizeof (avail);
|
---|
87 | rc = DosDevIOCtl (handle, IOCTL_XF86SUP, XF86SUP_FIONREAD,
|
---|
88 | NULL, 0, NULL,
|
---|
89 | &avail, data_length, &data_length);
|
---|
90 | if (rc != 0)
|
---|
91 | {
|
---|
92 | *errnop = set_error (rc);
|
---|
93 | return -1;
|
---|
94 | }
|
---|
95 | if (data_length != sizeof (avail))
|
---|
96 | {
|
---|
97 | *errnop = EINVAL;
|
---|
98 | return -1;
|
---|
99 | }
|
---|
100 | *errnop = 0;
|
---|
101 | return (int)avail;
|
---|
102 | }
|
---|
103 |
|
---|
104 |
|
---|
105 | /* __fcntl() for a tty or pty handle. This function is called for
|
---|
106 | F_SETFL only, and only if O_NDELAY was changed. */
|
---|
107 |
|
---|
108 |
|
---|
109 | int xf86sup_fcntl (ULONG handle, ULONG request, ULONG arg, int *errnop)
|
---|
110 | {
|
---|
111 | int on;
|
---|
112 |
|
---|
113 | on = arg & O_NDELAY;
|
---|
114 | return xf86sup_ioctl (handle, FIONBIO, (ULONG)&on, errnop);
|
---|
115 | }
|
---|
116 |
|
---|
117 |
|
---|
118 |
|
---|
119 | /* Common code for xf86sup_termio_get() and xf86sup_termios_get().
|
---|
120 | Returns 0 on success, -1 on error. Always sets *ERRNOP. */
|
---|
121 |
|
---|
122 | static int xf86sup_tiocgeta (ULONG handle, struct xf86sup_termios *p,
|
---|
123 | int *errnop)
|
---|
124 | {
|
---|
125 | ULONG rc, data_length;
|
---|
126 |
|
---|
127 | data_length = sizeof (*p);
|
---|
128 | rc = DosDevIOCtl (handle, IOCTL_XF86SUP, XF86SUP_TIOCGETA,
|
---|
129 | NULL, 0, NULL,
|
---|
130 | p, data_length, &data_length);
|
---|
131 | if (rc != 0)
|
---|
132 | {
|
---|
133 | *errnop = set_error (rc);
|
---|
134 | return -1;
|
---|
135 | }
|
---|
136 | *errnop = 0;
|
---|
137 | return 0;
|
---|
138 | }
|
---|
139 |
|
---|
140 |
|
---|
141 | /* Handle the TCGETA ioctl. Returns 0 on success, -1 on error.
|
---|
142 | Always sets *ERRNOP.*/
|
---|
143 |
|
---|
144 | static int xf86sup_termio_get (ULONG handle, struct termio *p, int *errnop)
|
---|
145 | {
|
---|
146 | struct xf86sup_termios xtio;
|
---|
147 |
|
---|
148 | if (xf86sup_tiocgeta (handle, &xtio, errnop) != 0)
|
---|
149 | return -1;
|
---|
150 | p->c_iflag = xtio.c_iflag;
|
---|
151 | p->c_oflag = xtio.c_oflag;
|
---|
152 | p->c_cflag = xtio.c_cflag;
|
---|
153 | p->c_lflag = xtio.c_lflag;
|
---|
154 | p->c_line = 0;
|
---|
155 | /* Note that this drops three characters! */
|
---|
156 | memcpy (p->c_cc, xtio.c_cc, NCC);
|
---|
157 | return 0;
|
---|
158 | }
|
---|
159 |
|
---|
160 |
|
---|
161 | /* Handle the _TCGA ioctl for tcgetattr(). Returns 0 on success, -1
|
---|
162 | on error. Always sets *ERRNOP. */
|
---|
163 |
|
---|
164 | static int xf86sup_termios_get (ULONG handle, struct termios *p, int *errnop)
|
---|
165 | {
|
---|
166 | struct xf86sup_termios xtio;
|
---|
167 |
|
---|
168 | if (xf86sup_tiocgeta (handle, &xtio, errnop) != 0)
|
---|
169 | return -1;
|
---|
170 | p->c_iflag = xtio.c_iflag;
|
---|
171 | p->c_oflag = xtio.c_oflag;
|
---|
172 | p->c_cflag = xtio.c_cflag;
|
---|
173 | p->c_lflag = xtio.c_lflag;
|
---|
174 | memcpy (p->c_cc, xtio.c_cc, NCCS);
|
---|
175 | return 0;
|
---|
176 | }
|
---|
177 |
|
---|
178 |
|
---|
179 | /* Common code for xf86sup_termio_set() and xf86sup_termios_set().
|
---|
180 | Returns 0 on success, -1 on error. Always sets *ERRNOP. */
|
---|
181 |
|
---|
182 | static int xf86sup_tiocseta (ULONG handle, struct xf86sup_termios *p,
|
---|
183 | ULONG request, int *errnop)
|
---|
184 | {
|
---|
185 | ULONG rc, data_length;
|
---|
186 |
|
---|
187 | data_length = sizeof (*p);
|
---|
188 | rc = DosDevIOCtl (handle, IOCTL_XF86SUP, request,
|
---|
189 | p, data_length, &data_length,
|
---|
190 | NULL, 0, NULL);
|
---|
191 | if (rc != 0)
|
---|
192 | {
|
---|
193 | *errnop = set_error (rc);
|
---|
194 | return -1;
|
---|
195 | }
|
---|
196 | *errnop = 0;
|
---|
197 | return 0;
|
---|
198 | }
|
---|
199 |
|
---|
200 |
|
---|
201 | /* Handle the TCSETA, TCSETAF, and TCSETAW ioctls. Returns 0 on
|
---|
202 | success, -1 on error. Always sets *ERRNOP. */
|
---|
203 |
|
---|
204 | static int xf86sup_termio_set (ULONG handle, const struct termio *p,
|
---|
205 | ULONG request, int *errnop)
|
---|
206 | {
|
---|
207 | struct xf86sup_termios xtio;
|
---|
208 |
|
---|
209 | /* Get the current settings. This is required for VSUSP, VSTOP, and
|
---|
210 | VSTART, which are not provided in `struct termio'. */
|
---|
211 |
|
---|
212 | if (xf86sup_tiocgeta (handle, &xtio, errnop) != 0)
|
---|
213 | return -1;
|
---|
214 | xtio.c_iflag = p->c_iflag;
|
---|
215 | xtio.c_oflag = p->c_oflag;
|
---|
216 | xtio.c_cflag = p->c_cflag;
|
---|
217 | xtio.c_lflag = p->c_lflag;
|
---|
218 | /* This leaves alone the last three characters! */
|
---|
219 | memcpy (xtio.c_cc, p->c_cc, NCC);
|
---|
220 | return xf86sup_tiocseta (handle, &xtio, request, errnop);
|
---|
221 | }
|
---|
222 |
|
---|
223 |
|
---|
224 | /* Handle the _TCSANOW, _TCSADRAIN, and _TCSAFLUSH ioctls for
|
---|
225 | tcsetattr(). Returns 0 on success, -1 on error. Always sets
|
---|
226 | *ERRNOP. */
|
---|
227 |
|
---|
228 | static int xf86sup_termios_set (ULONG handle, const struct termios *p,
|
---|
229 | ULONG request, int *errnop)
|
---|
230 | {
|
---|
231 | struct xf86sup_termios xtio;
|
---|
232 |
|
---|
233 | memset (&xtio, 0, sizeof (xtio)); /* Clear reserved fields */
|
---|
234 | xtio.c_iflag = p->c_iflag;
|
---|
235 | xtio.c_oflag = p->c_oflag;
|
---|
236 | xtio.c_cflag = p->c_cflag;
|
---|
237 | xtio.c_lflag = p->c_lflag;
|
---|
238 | memcpy (xtio.c_cc, p->c_cc, NCCS);
|
---|
239 | return xf86sup_tiocseta (handle, &xtio, request, errnop);
|
---|
240 | }
|
---|
241 |
|
---|
242 |
|
---|
243 | /* __ioct2l() for a tty or pty handle. */
|
---|
244 |
|
---|
245 | int xf86sup_ioctl (ULONG handle, ULONG request, ULONG arg, int *errnop)
|
---|
246 | {
|
---|
247 | int n;
|
---|
248 | ULONG rc, parm_length;
|
---|
249 |
|
---|
250 | switch (request)
|
---|
251 | {
|
---|
252 | case FGETHTYPE:
|
---|
253 | *(int *)arg = HT_DEV_OTHER; /* TODO */
|
---|
254 | break;
|
---|
255 |
|
---|
256 | case FIONREAD:
|
---|
257 | n = xf86sup_avail (handle, errnop);
|
---|
258 | if (n == -1)
|
---|
259 | return -1;
|
---|
260 | *(int *)arg = n;
|
---|
261 | break;
|
---|
262 |
|
---|
263 | case FIONBIO:
|
---|
264 | parm_length = sizeof (int);
|
---|
265 | rc = DosDevIOCtl (handle, IOCTL_XF86SUP, XF86SUP_FIONBIO,
|
---|
266 | (PVOID)arg, parm_length, &parm_length,
|
---|
267 | NULL, 0, NULL);
|
---|
268 | if (rc != 0)
|
---|
269 | {
|
---|
270 | *errnop = set_error (rc);
|
---|
271 | return -1;
|
---|
272 | }
|
---|
273 | if (*(int *)arg)
|
---|
274 | handle_flags[handle] |= HF_NDELAY;
|
---|
275 | else
|
---|
276 | handle_flags[handle] &= ~HF_NDELAY;
|
---|
277 | break;
|
---|
278 |
|
---|
279 | case TCGETA:
|
---|
280 | return xf86sup_termio_get (handle, (struct termio *)arg, errnop);
|
---|
281 |
|
---|
282 | case TCSETA:
|
---|
283 | return xf86sup_termio_set (handle, (const struct termio *)arg,
|
---|
284 | XF86SUP_TIOCSETA, errnop);
|
---|
285 |
|
---|
286 | case TCSETAF:
|
---|
287 | return xf86sup_termio_set (handle, (const struct termio *)arg,
|
---|
288 | XF86SUP_TIOCSETAF, errnop);
|
---|
289 |
|
---|
290 | case TCSETAW:
|
---|
291 | return xf86sup_termio_set (handle, (const struct termio *)arg,
|
---|
292 | XF86SUP_TIOCSETAW, errnop);
|
---|
293 |
|
---|
294 | case TCFLSH:
|
---|
295 | parm_length = sizeof (int);
|
---|
296 | rc = DosDevIOCtl (handle, IOCTL_XF86SUP, XF86SUP_TIOCFLUSH,
|
---|
297 | &arg, parm_length, &parm_length,
|
---|
298 | NULL, 0, NULL);
|
---|
299 | if (rc != 0)
|
---|
300 | {
|
---|
301 | *errnop = set_error (rc);
|
---|
302 | return -1;
|
---|
303 | }
|
---|
304 | break;
|
---|
305 |
|
---|
306 | case TCSBRK:
|
---|
307 | rc = DosDevIOCtl (handle, IOCTL_XF86SUP, XF86SUP_TIOCDRAIN,
|
---|
308 | NULL, 0, NULL,
|
---|
309 | NULL, 0, NULL);
|
---|
310 | if (rc != 0)
|
---|
311 | {
|
---|
312 | *errnop = set_error (rc);
|
---|
313 | return -1;
|
---|
314 | }
|
---|
315 | break;
|
---|
316 |
|
---|
317 | case TCXONC:
|
---|
318 | /* Flow control. */
|
---|
319 | break;
|
---|
320 |
|
---|
321 | case _TCGA:
|
---|
322 | return xf86sup_termios_get (handle, (struct termios *)arg, errnop);
|
---|
323 |
|
---|
324 | case _TCSANOW:
|
---|
325 | return xf86sup_termios_set (handle, (const struct termios *)arg,
|
---|
326 | XF86SUP_TIOCSETA, errnop);
|
---|
327 |
|
---|
328 | case _TCSADRAIN:
|
---|
329 | return xf86sup_termios_set (handle, (const struct termios *)arg,
|
---|
330 | XF86SUP_TIOCSETAW, errnop);
|
---|
331 |
|
---|
332 | case _TCSAFLUSH:
|
---|
333 | return xf86sup_termios_set (handle, (const struct termios *)arg,
|
---|
334 | XF86SUP_TIOCSETAF, errnop);
|
---|
335 |
|
---|
336 | default:
|
---|
337 | *errnop = EINVAL;
|
---|
338 | return -1;
|
---|
339 | }
|
---|
340 |
|
---|
341 | /* Function successfully completed. */
|
---|
342 |
|
---|
343 | *errnop = 0;
|
---|
344 | return 0;
|
---|
345 | }
|
---|
346 |
|
---|
347 |
|
---|
348 | /* __select(): Add a semaphore for a pty, tty, or /dev/console$ handle,
|
---|
349 | to be posted when data becomes ready for reading. */
|
---|
350 |
|
---|
351 | int xf86sup_select_add_read (struct select_data *d, int fd)
|
---|
352 | {
|
---|
353 | HEV sem;
|
---|
354 | my_file *f;
|
---|
355 | int i;
|
---|
356 | ULONG rc, parm_length, data_length, arm_on;
|
---|
357 | struct xf86sup_selreg selreg;
|
---|
358 |
|
---|
359 | if (!IS_VALID_FILE (fd))
|
---|
360 | return EBADF;
|
---|
361 |
|
---|
362 | f = GET_FILE (fd);
|
---|
363 | if (f->x.xf86sup.id != XF86SUP_ID_PTY && f->x.xf86sup.id != XF86SUP_ID_TTY
|
---|
364 | && f->x.xf86sup.id != XF86SUP_ID_CONSOLE)
|
---|
365 | return 0; /* Silently ignore */
|
---|
366 | if (f->x.xf86sup.sem_open)
|
---|
367 | sem = f->x.xf86sup.sem;
|
---|
368 | else
|
---|
369 | {
|
---|
370 | /* Check whether a semaphore is already registered. As the
|
---|
371 | semaphore handles to be registered are null (invalid) and
|
---|
372 | xf86sup.sys tries to open the new semaphore handles, we'll
|
---|
373 | get ERROR_INVALID_PARAMETER if there are no semaphores
|
---|
374 | registered. */
|
---|
375 |
|
---|
376 | selreg.rsel = selreg.xsel = 0;
|
---|
377 | selreg.code = 0;
|
---|
378 | parm_length = sizeof (selreg);
|
---|
379 | data_length = sizeof (selreg);
|
---|
380 | rc = DosDevIOCtl (fd, IOCTL_XF86SUP, XF86SUP_SELREG,
|
---|
381 | &selreg, parm_length, &parm_length,
|
---|
382 | &selreg, data_length, &data_length);
|
---|
383 | if (rc == 0 && selreg.rsel != 0)
|
---|
384 | {
|
---|
385 | /* There is a semaphore registered. Open it. */
|
---|
386 |
|
---|
387 | sem = (HEV)selreg.rsel;
|
---|
388 | rc = DosOpenEventSem (NULL, &sem);
|
---|
389 | if (rc != 0) return set_error (rc);
|
---|
390 | f->x.xf86sup.sem = sem;
|
---|
391 | f->x.xf86sup.sem_open = TRUE;
|
---|
392 | }
|
---|
393 | else
|
---|
394 | {
|
---|
395 | /* Create a semaphore which will be registered with
|
---|
396 | xf86sup.sys. Don't use create_event_sem() as the
|
---|
397 | semaphore will stick forever (and to avoid overflowing
|
---|
398 | the semaphore table). */
|
---|
399 |
|
---|
400 | if (DosCreateEventSem (NULL, &sem, DC_SEM_SHARED, FALSE) != 0)
|
---|
401 | return EINVAL;
|
---|
402 |
|
---|
403 | /* Register the semaphore with xf86sup.sys. Unfortunately,
|
---|
404 | xf86sup.sys does not accept null handles, therefore we
|
---|
405 | use the semaphore also for xsel. TODO: This will cause
|
---|
406 | problems with other processes trying to register two
|
---|
407 | distinct semaphores with this pty/tty pair in the
|
---|
408 | future. */
|
---|
409 |
|
---|
410 | selreg.rsel = (ULONG)sem; selreg.xsel = (ULONG)sem;
|
---|
411 | selreg.code = 0;
|
---|
412 | parm_length = sizeof (selreg);
|
---|
413 | data_length = sizeof (selreg);
|
---|
414 | rc = DosDevIOCtl (fd, IOCTL_XF86SUP, XF86SUP_SELREG,
|
---|
415 | &selreg, parm_length, &parm_length,
|
---|
416 | &selreg, data_length, &data_length);
|
---|
417 | if (rc != 0)
|
---|
418 | {
|
---|
419 | DosCloseEventSem (sem);
|
---|
420 | return set_error (rc);
|
---|
421 | }
|
---|
422 |
|
---|
423 | /* If someone else has registered a semaphore in the
|
---|
424 | meantime, use that semaphore. */
|
---|
425 |
|
---|
426 | if (selreg.code & XF86SUP_SEL_READ)
|
---|
427 | {
|
---|
428 | DosCloseEventSem (sem);
|
---|
429 | sem = (HEV)selreg.rsel;
|
---|
430 | }
|
---|
431 | f->x.xf86sup.sem = sem;
|
---|
432 | f->x.xf86sup.sem_open = TRUE;
|
---|
433 | }
|
---|
434 | }
|
---|
435 |
|
---|
436 | /* The semaphore handle is now in SEM. Add the semaphore to the
|
---|
437 | MuxWait list, unless it's already in the list. */
|
---|
438 |
|
---|
439 | for (i = 0; i < d->sem_count; ++i)
|
---|
440 | if (d->list[i].hsemCur == (HSEM)sem)
|
---|
441 | break;
|
---|
442 | if (i >= d->sem_count)
|
---|
443 | {
|
---|
444 | /* The semaphore is not yet in the list. Add it. */
|
---|
445 |
|
---|
446 | if (d->sem_count >= d->max_sem)
|
---|
447 | return EINVAL;
|
---|
448 | else
|
---|
449 | {
|
---|
450 | d->list[d->sem_count].hsemCur = (HSEM)sem;
|
---|
451 | d->list[d->sem_count].ulUser = 0;
|
---|
452 | ++d->sem_count;
|
---|
453 | }
|
---|
454 | }
|
---|
455 |
|
---|
456 | /* Arm the semaphore. Arming a semaphore multiple times doesn't
|
---|
457 | hurt as we first arm all semaphores, then poll all handles. */
|
---|
458 |
|
---|
459 | parm_length = sizeof (arm_on);
|
---|
460 | arm_on = XF86SUP_SEL_READ;
|
---|
461 | rc = DosDevIOCtl (fd, IOCTL_XF86SUP, XF86SUP_SELARM,
|
---|
462 | &arm_on, parm_length, &parm_length,
|
---|
463 | NULL, 0, NULL);
|
---|
464 | if (rc != 0)
|
---|
465 | return set_error (rc);
|
---|
466 | return 0;
|
---|
467 | }
|
---|
468 |
|
---|
469 |
|
---|
470 | int xf86sup_ttyname (char *dst, ULONG dst_size, ULONG handle, int *errnop)
|
---|
471 | {
|
---|
472 | ULONG rc, parm_length, data_length;
|
---|
473 | char buf[14], *p;
|
---|
474 |
|
---|
475 | parm_length = 0;
|
---|
476 | data_length = sizeof (buf);
|
---|
477 | rc = DosDevIOCtl (handle, IOCTL_XF86SUP, XF86SUP_NAME,
|
---|
478 | NULL, parm_length, &parm_length,
|
---|
479 | buf, data_length, &data_length);
|
---|
480 | if (rc != 0)
|
---|
481 | {
|
---|
482 | *errnop = set_error (rc);
|
---|
483 | return -1;
|
---|
484 | }
|
---|
485 |
|
---|
486 | /* There's no point in handling DBCS characters here. */
|
---|
487 |
|
---|
488 | for (p = buf; *p != 0; ++p)
|
---|
489 | if (*p == '\\')
|
---|
490 | *p = '/';
|
---|
491 | return set_ttyname (dst, dst_size, buf, errnop);
|
---|
492 | }
|
---|
493 |
|
---|
494 |
|
---|
495 | ULONG xf86sup_uncond_enadup (ULONG handle, ULONG on)
|
---|
496 | {
|
---|
497 | ULONG data_length;
|
---|
498 |
|
---|
499 | data_length = sizeof (on);
|
---|
500 | return DosDevIOCtl (handle, IOCTL_XF86SUP, XF86SUP_ENADUP,
|
---|
501 | &on, data_length, &data_length,
|
---|
502 | NULL, 0, NULL);
|
---|
503 | }
|
---|
504 |
|
---|
505 |
|
---|
506 | ULONG xf86sup_maybe_enadup (ULONG handle, ULONG on)
|
---|
507 | {
|
---|
508 | if (handle < handle_count
|
---|
509 | && (handle_flags[handle] & (HF_OPEN|HF_XF86SUP))
|
---|
510 | && IS_VALID_FILE (handle)
|
---|
511 | && GET_FILE (handle)->x.xf86sup.id == XF86SUP_ID_PTY)
|
---|
512 | return xf86sup_uncond_enadup (handle, on);
|
---|
513 | else
|
---|
514 | return 0;
|
---|
515 | }
|
---|
516 |
|
---|
517 |
|
---|
518 | void xf86sup_all_enadup (ULONG on)
|
---|
519 | {
|
---|
520 | ULONG i;
|
---|
521 |
|
---|
522 | for (i = 0; i < handle_count; ++i)
|
---|
523 | if ((handle_flags[i] & (HF_OPEN|HF_XF86SUP))
|
---|
524 | && IS_VALID_FILE (i)
|
---|
525 | && GET_FILE (i)->x.xf86sup.id == XF86SUP_ID_PTY)
|
---|
526 | xf86sup_uncond_enadup (i, on);
|
---|
527 | }
|
---|