2 * DEC 93 Erik Bos <erik@xs4all.nl>
4 * Copyright 1996 Marcus Meissner
6 * Mar 31, 1999. Ove Kåven <ovek@arcticnet.no>
7 * - Implemented buffers and EnableCommNotification.
9 * Apr 3, 1999. Lawson Whitney <lawson_whitney@juno.com>
10 * - Fixed the modem control part of EscapeCommFunction16.
12 * Mar 3, 1999. Ove Kåven <ovek@arcticnet.no>
13 * - Use port indices instead of unixfds for win16
14 * - Moved things around (separated win16 and win32 routines)
15 * - Added some hints on how to implement buffers and EnableCommNotification.
17 * May 26, 1997. Fixes and comments by Rick Richardson <rick@dgii.com> [RER]
18 * - ptr->fd wasn't getting cleared on close.
19 * - GetCommEventMask() and GetCommError() didn't do much of anything.
20 * IMHO, they are still wrong, but they at least implement the RXCHAR
21 * event and return I/O queue sizes, which makes the app I'm interested
22 * in (analog devices EZKIT DSP development system) work.
24 * August 12, 1997. Take a bash at SetCommEventMask - Lawson Whitney
25 * <lawson_whitney@juno.com>
26 * July 6, 1998. Fixes and comments by Valentijn Sessink
27 * <vsessink@ic.uva.nl> [V]
28 * Oktober 98, Rein Klazes [RHK]
29 * A program that wants to monitor the modem status line (RLSD/DCD) may
30 * poll the modem status register in the commMask structure. I update the bit
31 * in GetCommError, waiting for an implementation of communication events.
47 #ifdef HAVE_SYS_FILIO_H
48 # include <sys/filio.h>
50 #include <sys/ioctl.h>
53 #include "wine/winuser16.h"
55 #ifdef HAVE_SYS_MODEM_H
56 # include <sys/modem.h>
58 #ifdef HAVE_SYS_STRTIO_H
59 # include <sys/strtio.h>
64 #include "server/request.h"
72 DEFAULT_DEBUG_CHANNEL(comm
)
75 #define TIOCINQ FIONREAD
77 #define COMM_MSR_OFFSET 35 /* see knowledge base Q101417 */
80 struct DosDeviceStruct COM
[MAX_PORTS
];
81 struct DosDeviceStruct LPT
[MAX_PORTS
];
82 /* pointers to unknown(==undocumented) comm structure */
83 LPCVOID
*unknown
[MAX_PORTS
];
84 /* save terminal states */
85 static struct termios m_stat
[MAX_PORTS
];
90 char option
[10], temp
[256], *btemp
;
93 for (x
=0; x
!=MAX_PORTS
; x
++) {
94 strcpy(option
,"COMx");
98 PROFILE_GetWineIniString( "serialports", option
, "*",
100 if (!strcmp(temp
, "*") || *temp
== '\0')
101 COM
[x
].devicename
= NULL
;
103 btemp
= strchr(temp
,',');
106 COM
[x
].baudrate
= atoi(btemp
);
108 COM
[x
].baudrate
= -1;
111 if (!S_ISCHR(st
.st_mode
))
112 WARN(comm
,"Can't use `%s' as %s !\n", temp
, option
);
114 if ((COM
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
115 WARN(comm
,"Can't malloc for device info!\n");
118 strcpy(COM
[x
].devicename
, temp
);
120 TRACE(comm
, "%s = %s\n", option
, COM
[x
].devicename
);
123 strcpy(option
, "LPTx");
127 PROFILE_GetWineIniString( "parallelports", option
, "*",
128 temp
, sizeof(temp
) );
129 if (!strcmp(temp
, "*") || *temp
== '\0')
130 LPT
[x
].devicename
= NULL
;
133 if (!S_ISCHR(st
.st_mode
))
134 WARN(comm
,"Can't use `%s' as %s !\n", temp
, option
);
136 if ((LPT
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
137 WARN(comm
,"Can't malloc for device info!\n");
140 strcpy(LPT
[x
].devicename
, temp
);
142 TRACE(comm
, "%s = %s\n", option
, LPT
[x
].devicename
);
149 struct DosDeviceStruct
*GetDeviceStruct_fd(int fd
)
153 for (x
=0; x
!=MAX_PORTS
; x
++) {
163 struct DosDeviceStruct
*GetDeviceStruct(int fd
)
165 if ((fd
&0x7F)<=MAX_PORTS
) {
166 if (!(fd
&FLAG_LPT
)) {
178 int GetCommPort_fd(int fd
)
182 for (x
=0; x
<MAX_PORTS
; x
++) {
190 int ValidCOMPort(int x
)
192 return(x
< MAX_PORTS
? (int) COM
[x
].devicename
: 0);
195 int ValidLPTPort(int x
)
197 return(x
< MAX_PORTS
? (int) LPT
[x
].devicename
: 0);
202 TRACE(comm
, "errno = %d\n", errno
);
209 static unsigned comm_inbuf(struct DosDeviceStruct
*ptr
)
211 return ((ptr
->ibuf_tail
> ptr
->ibuf_head
) ? ptr
->ibuf_size
: 0)
212 + ptr
->ibuf_head
- ptr
->ibuf_tail
;
215 static unsigned comm_outbuf(struct DosDeviceStruct
*ptr
)
217 return ((ptr
->obuf_tail
> ptr
->obuf_head
) ? ptr
->obuf_size
: 0)
218 + ptr
->obuf_head
- ptr
->obuf_tail
;
221 static int COMM_WhackModem(int fd
, unsigned int andy
, unsigned int orrie
)
223 unsigned int mstat
, okay
;
224 okay
= ioctl(fd
, TIOCMGET
, &mstat
);
225 if (okay
) return okay
;
226 if (andy
) mstat
&= andy
;
228 return ioctl(fd
, TIOCMSET
, &mstat
);
231 static void comm_notification(int fd
,void*private)
233 struct DosDeviceStruct
*ptr
= (struct DosDeviceStruct
*)private;
234 int prev
, bleft
, len
;
236 int cid
= GetCommPort_fd(fd
);
238 /* read data from comm port */
239 prev
= comm_inbuf(ptr
);
241 bleft
= ((ptr
->ibuf_tail
> ptr
->ibuf_head
) ? (ptr
->ibuf_tail
-1) : ptr
->ibuf_size
)
243 len
= read(fd
, ptr
->inbuf
+ ptr
->ibuf_head
, bleft
?bleft
:1);
246 ptr
->commerror
= CE_RXOVER
;
248 ptr
->ibuf_head
+= len
;
249 if (ptr
->ibuf_head
>= ptr
->ibuf_size
)
252 if (ptr
->eventmask
& EV_RXCHAR
)
253 *(WORD
*)(unknown
[cid
]) |= EV_RXCHAR
;
254 /* FIXME: check for event character (EV_RXFLAG) */
258 /* check for notification */
259 if (ptr
->wnd
&& (ptr
->n_read
>0) && (prev
<ptr
->n_read
) &&
260 (comm_inbuf(ptr
)>=ptr
->n_read
)) {
261 /* passed the receive notification threshold */
265 /* write any TransmitCommChar character */
267 len
= write(fd
, &(ptr
->xmit
), 1);
268 if (len
> 0) ptr
->xmit
= -1;
270 /* write from output queue */
271 prev
= comm_outbuf(ptr
);
273 bleft
= ((ptr
->obuf_tail
<= ptr
->obuf_head
) ? ptr
->obuf_head
: ptr
->obuf_size
)
275 len
= bleft
? write(fd
, ptr
->outbuf
+ ptr
->obuf_tail
, bleft
) : 0;
277 ptr
->obuf_tail
+= len
;
278 if (ptr
->obuf_tail
>= ptr
->obuf_size
)
281 if ((ptr
->obuf_tail
== ptr
->obuf_head
) && (ptr
->eventmask
& EV_TXEMPTY
))
282 *(WORD
*)(unknown
[cid
]) |= EV_TXEMPTY
;
285 /* check for notification */
286 if (ptr
->wnd
&& (ptr
->n_write
>0) && (prev
>=ptr
->n_write
) &&
287 (comm_outbuf(ptr
)<ptr
->n_write
)) {
288 /* passed the transmit notification threshold */
292 /* send notifications, if any */
293 if (ptr
->wnd
&& mask
) {
294 PostMessage16(ptr
->wnd
, WM_COMMNOTIFY
, cid
, mask
);
298 /**************************************************************************
299 * BuildCommDCB (USER.213)
301 BOOL16 WINAPI
BuildCommDCB16(LPCSTR device
, LPDCB16 lpdcb
)
303 /* "COM1:9600,n,8,1" */
306 char *ptr
, temp
[256];
308 TRACE(comm
, "(%s), ptr %p\n", device
, lpdcb
);
310 if (!lstrncmpiA(device
,"COM",3)) {
311 port
= device
[3] - '0';
315 ERR(comm
, "BUG ! COM0 can't exist!.\n");
319 if (!ValidCOMPort(port
)) {
323 memset(lpdcb
, 0, sizeof(DCB16
)); /* initialize */
330 if (*(device
+4) != ':')
333 strcpy(temp
,device
+5);
334 ptr
= strtok(temp
, ", ");
336 if (COM
[port
].baudrate
> 0)
337 lpdcb
->BaudRate
= COM
[port
].baudrate
;
339 lpdcb
->BaudRate
= atoi(ptr
);
340 TRACE(comm
,"baudrate (%d)\n", lpdcb
->BaudRate
);
342 ptr
= strtok(NULL
, ", ");
344 *ptr
= toupper(*ptr
);
346 TRACE(comm
,"parity (%c)\n", *ptr
);
347 lpdcb
->fParity
= TRUE
;
350 lpdcb
->Parity
= NOPARITY
;
351 lpdcb
->fParity
= FALSE
;
354 lpdcb
->Parity
= EVENPARITY
;
357 lpdcb
->Parity
= MARKPARITY
;
360 lpdcb
->Parity
= ODDPARITY
;
363 WARN(comm
,"Unknown parity `%c'!\n", *ptr
);
367 ptr
= strtok(NULL
, ", ");
368 TRACE(comm
, "charsize (%c)\n", *ptr
);
369 lpdcb
->ByteSize
= *ptr
- '0';
371 ptr
= strtok(NULL
, ", ");
372 TRACE(comm
, "stopbits (%c)\n", *ptr
);
375 lpdcb
->StopBits
= ONESTOPBIT
;
378 lpdcb
->StopBits
= TWOSTOPBITS
;
381 WARN(comm
,"Unknown # of stopbits `%c'!\n", *ptr
);
389 /*****************************************************************************
390 * OpenComm (USER.200)
392 INT16 WINAPI
OpenComm16(LPCSTR device
,UINT16 cbInQueue
,UINT16 cbOutQueue
)
396 TRACE(comm
, "%s, %d, %d\n", device
, cbInQueue
, cbOutQueue
);
398 port
= device
[3] - '0';
401 ERR(comm
, "BUG ! COM0 or LPT0 don't exist !\n");
403 if (!lstrncmpiA(device
,"COM",3)) {
405 TRACE(comm
, "%s = %s\n", device
, COM
[port
].devicename
);
407 if (!ValidCOMPort(port
))
413 fd
= open(COM
[port
].devicename
, O_RDWR
| O_NONBLOCK
);
417 unknown
[port
] = SEGPTR_ALLOC(40);
418 bzero(unknown
[port
],40);
420 COM
[port
].commerror
= 0;
421 COM
[port
].eventmask
= 0;
422 /* save terminal state */
423 tcgetattr(fd
,&m_stat
[port
]);
424 /* set default parameters */
425 if(COM
[port
].baudrate
>-1){
427 GetCommState16(port
, &dcb
);
428 dcb
.BaudRate
=COM
[port
].baudrate
;
430 * databits, parity, stopbits
432 SetCommState16( &dcb
);
434 /* init priority characters */
435 COM
[port
].unget
= -1;
437 /* allocate buffers */
438 COM
[port
].ibuf_size
= cbInQueue
;
439 COM
[port
].ibuf_head
= COM
[port
].ibuf_tail
= 0;
440 COM
[port
].obuf_size
= cbOutQueue
;
441 COM
[port
].obuf_head
= COM
[port
].obuf_tail
= 0;
443 COM
[port
].inbuf
= malloc(cbInQueue
);
444 if (COM
[port
].inbuf
) {
445 COM
[port
].outbuf
= malloc(cbOutQueue
);
446 if (!COM
[port
].outbuf
)
447 free(COM
[port
].inbuf
);
448 } else COM
[port
].outbuf
= NULL
;
449 if (!COM
[port
].outbuf
) {
450 /* not enough memory */
451 tcsetattr(COM
[port
].fd
,TCSANOW
,&m_stat
[port
]);
456 /* enable async notifications */
457 ASYNC_RegisterFD(COM
[port
].fd
,comm_notification
,&COM
[port
]);
462 if (!lstrncmpiA(device
,"LPT",3)) {
464 if (!ValidLPTPort(port
))
470 fd
= open(LPT
[port
].devicename
, O_RDWR
| O_NONBLOCK
, 0);
475 LPT
[port
].commerror
= 0;
476 LPT
[port
].eventmask
= 0;
477 return port
|FLAG_LPT
;
483 /*****************************************************************************
484 * CloseComm (USER.207)
486 INT16 WINAPI
CloseComm16(INT16 cid
)
488 struct DosDeviceStruct
*ptr
;
490 TRACE(comm
,"cid=%d\n", cid
);
491 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
494 if (!(cid
&FLAG_LPT
)) {
496 SEGPTR_FREE(unknown
[cid
]); /* [LW] */
498 /* disable async notifications */
499 ASYNC_UnregisterFD(COM
[cid
].fd
,comm_notification
);
504 /* reset modem lines */
505 tcsetattr(ptr
->fd
,TCSANOW
,&m_stat
[cid
]);
508 if (close(ptr
->fd
) == -1) {
509 ptr
->commerror
= WinError();
510 /* FIXME: should we clear ptr->fd here? */
519 /*****************************************************************************
520 * SetCommBreak (USER.210)
522 INT16 WINAPI
SetCommBreak16(INT16 cid
)
524 struct DosDeviceStruct
*ptr
;
526 TRACE(comm
,"cid=%d\n", cid
);
527 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
536 /*****************************************************************************
537 * ClearCommBreak (USER.211)
539 INT16 WINAPI
ClearCommBreak16(INT16 cid
)
541 struct DosDeviceStruct
*ptr
;
543 TRACE(comm
,"cid=%d\n", cid
);
544 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
553 /*****************************************************************************
554 * EscapeCommFunction (USER.214)
556 LONG WINAPI
EscapeCommFunction16(UINT16 cid
,UINT16 nFunction
)
559 struct DosDeviceStruct
*ptr
;
562 TRACE(comm
,"cid=%d, function=%d\n", cid
, nFunction
);
563 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
566 if (tcgetattr(ptr
->fd
,&port
) == -1) {
567 ptr
->commerror
=WinError();
576 for (max
= MAX_PORTS
;!COM
[max
].devicename
;max
--)
582 for (max
= MAX_PORTS
;!LPT
[max
].devicename
;max
--)
584 return FLAG_LPT
+ max
;
589 return COMM_WhackModem(ptr
->fd
, ~TIOCM_DTR
, 0);
593 return COMM_WhackModem(ptr
->fd
, ~TIOCM_RTS
, 0);
598 return COMM_WhackModem(ptr
->fd
, 0, TIOCM_DTR
);
603 return COMM_WhackModem(ptr
->fd
, 0, TIOCM_RTS
);
607 port
.c_iflag
|= IXOFF
;
611 port
.c_iflag
|= IXON
;
615 WARN(comm
,"(cid=%d,nFunction=%d): Unknown function\n",
620 if (tcsetattr(ptr
->fd
, TCSADRAIN
, &port
) == -1) {
621 ptr
->commerror
= WinError();
629 /*****************************************************************************
630 * FlushComm (USER.215)
632 INT16 WINAPI
FlushComm16(INT16 cid
,INT16 fnQueue
)
635 struct DosDeviceStruct
*ptr
;
637 TRACE(comm
,"cid=%d, queue=%d\n", cid
, fnQueue
);
638 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
644 ptr
->obuf_tail
= ptr
->obuf_head
;
648 ptr
->ibuf_head
= ptr
->ibuf_tail
;
651 WARN(comm
,"(cid=%d,fnQueue=%d):Unknown queue\n",
655 if (tcflush(ptr
->fd
, queue
)) {
656 ptr
->commerror
= WinError();
664 /********************************************************************
665 * GetCommError (USER.203)
667 INT16 WINAPI
GetCommError16(INT16 cid
,LPCOMSTAT16 lpStat
)
670 struct DosDeviceStruct
*ptr
;
674 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
678 WARN(comm
," cid %d not comm port\n",cid
);
681 stol
= (unsigned char *)unknown
[cid
] + COMM_MSR_OFFSET
;
682 ioctl(ptr
->fd
,TIOCMGET
,&mstat
);
683 if( mstat
&TIOCM_CAR
)
691 lpStat
->cbOutQue
= comm_outbuf(ptr
);
692 lpStat
->cbInQue
= comm_inbuf(ptr
);
694 TRACE(comm
, "cid %d, error %d, lpStat %d %d %d stol %x\n",
695 cid
, ptr
->commerror
, lpStat
->status
, lpStat
->cbInQue
,
696 lpStat
->cbOutQue
, *stol
);
699 TRACE(comm
, "cid %d, error %d, lpStat NULL stol %x\n",
700 cid
, ptr
->commerror
, *stol
);
702 /* Return any errors and clear it */
703 temperror
= ptr
->commerror
;
708 /*****************************************************************************
709 * SetCommEventMask (USER.208)
711 SEGPTR WINAPI
SetCommEventMask16(INT16 cid
,UINT16 fuEvtMask
)
713 struct DosDeviceStruct
*ptr
;
718 TRACE(comm
,"cid %d,mask %d\n",cid
,fuEvtMask
);
719 if ((ptr
= GetDeviceStruct(cid
)) == NULL
)
722 ptr
->eventmask
= fuEvtMask
;
724 if ((cid
&FLAG_LPT
) || !ValidCOMPort(cid
)) {
725 WARN(comm
," cid %d not comm port\n",cid
);
728 /* it's a COM port ? -> modify flags */
729 stol
= (unsigned char *)unknown
[cid
] + COMM_MSR_OFFSET
;
730 repid
= ioctl(ptr
->fd
,TIOCMGET
,&mstat
);
731 TRACE(comm
, " ioctl %d, msr %x at %p %p\n",repid
,mstat
,stol
,unknown
[cid
]);
732 if ((mstat
&TIOCM_CAR
))
737 TRACE(comm
," modem dcd construct %x\n",*stol
);
738 return SEGPTR_GET(unknown
[cid
]);
741 /*****************************************************************************
742 * GetCommEventMask (USER.209)
744 UINT16 WINAPI
GetCommEventMask16(INT16 cid
,UINT16 fnEvtClear
)
746 struct DosDeviceStruct
*ptr
;
749 TRACE(comm
, "cid %d, mask %d\n", cid
, fnEvtClear
);
750 if ((ptr
= GetDeviceStruct(cid
)) == NULL
)
753 if ((cid
&FLAG_LPT
) || !ValidCOMPort(cid
)) {
754 WARN(comm
," cid %d not comm port\n",cid
);
758 events
= *(WORD
*)(unknown
[cid
]) & fnEvtClear
;
759 *(WORD
*)(unknown
[cid
]) &= ~fnEvtClear
;
763 /*****************************************************************************
764 * SetCommState16 (USER.201)
766 INT16 WINAPI
SetCommState16(LPDCB16 lpdcb
)
769 struct DosDeviceStruct
*ptr
;
771 TRACE(comm
, "cid %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
772 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
775 if (tcgetattr(ptr
->fd
, &port
) == -1) {
776 ptr
->commerror
= WinError();
781 port
.c_cc
[VTIME
] = 1;
784 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
786 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
788 port
.c_iflag
|= (IGNBRK
);
790 port
.c_oflag
&= ~(OPOST
);
792 port
.c_cflag
&= ~(HUPCL
);
793 port
.c_cflag
|= CLOCAL
| CREAD
;
795 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
796 port
.c_lflag
|= NOFLSH
;
798 TRACE(comm
,"baudrate %d\n",lpdcb
->BaudRate
);
800 port
.c_cflag
&= ~CBAUD
;
801 switch (lpdcb
->BaudRate
) {
804 port
.c_cflag
|= B110
;
808 port
.c_cflag
|= B300
;
812 port
.c_cflag
|= B600
;
816 port
.c_cflag
|= B1200
;
820 port
.c_cflag
|= B2400
;
824 port
.c_cflag
|= B4800
;
828 port
.c_cflag
|= B9600
;
832 port
.c_cflag
|= B19200
;
836 port
.c_cflag
|= B38400
;
840 port
.c_cflag
|= B57600
;
845 port
.c_cflag
|= B115200
;
849 ptr
->commerror
= IE_BAUDRATE
;
852 #elif !defined(__EMX__)
853 switch (lpdcb
->BaudRate
) {
856 port
.c_ospeed
= B110
;
860 port
.c_ospeed
= B300
;
864 port
.c_ospeed
= B600
;
868 port
.c_ospeed
= B1200
;
872 port
.c_ospeed
= B2400
;
876 port
.c_ospeed
= B4800
;
880 port
.c_ospeed
= B9600
;
884 port
.c_ospeed
= B19200
;
888 port
.c_ospeed
= B38400
;
891 ptr
->commerror
= IE_BAUDRATE
;
894 port
.c_ispeed
= port
.c_ospeed
;
896 TRACE(comm
,"bytesize %d\n",lpdcb
->ByteSize
);
897 port
.c_cflag
&= ~CSIZE
;
898 switch (lpdcb
->ByteSize
) {
912 ptr
->commerror
= IE_BYTESIZE
;
916 TRACE(comm
,"fParity %d Parity %d\n",lpdcb
->fParity
, lpdcb
->Parity
);
917 port
.c_cflag
&= ~(PARENB
| PARODD
);
919 port
.c_iflag
|= INPCK
;
921 port
.c_iflag
&= ~INPCK
;
922 switch (lpdcb
->Parity
) {
926 port
.c_cflag
|= (PARENB
| PARODD
);
929 port
.c_cflag
|= PARENB
;
932 ptr
->commerror
= IE_BYTESIZE
;
937 TRACE(comm
,"stopbits %d\n",lpdcb
->StopBits
);
939 switch (lpdcb
->StopBits
) {
941 port
.c_cflag
&= ~CSTOPB
;
944 port
.c_cflag
|= CSTOPB
;
947 ptr
->commerror
= IE_BYTESIZE
;
952 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
953 port
.c_cflag
|= CRTSCTS
;
955 if (lpdcb
->fDtrDisable
)
956 port
.c_cflag
&= ~CRTSCTS
;
959 port
.c_iflag
|= IXON
;
961 port
.c_iflag
&= ~IXON
;
963 port
.c_iflag
|= IXOFF
;
965 port
.c_iflag
&= ~IXOFF
;
967 if (tcsetattr(ptr
->fd
, TCSADRAIN
, &port
) == -1) {
968 ptr
->commerror
= WinError();
976 /*****************************************************************************
977 * GetCommState (USER.202)
979 INT16 WINAPI
GetCommState16(INT16 cid
, LPDCB16 lpdcb
)
981 struct DosDeviceStruct
*ptr
;
984 TRACE(comm
,"cid %d, ptr %p\n", cid
, lpdcb
);
985 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
988 if (tcgetattr(ptr
->fd
, &port
) == -1) {
989 ptr
->commerror
= WinError();
995 switch (port
.c_cflag
& CBAUD
) {
997 switch (port
.c_ospeed
) {
1000 lpdcb
->BaudRate
= 110;
1003 lpdcb
->BaudRate
= 300;
1006 lpdcb
->BaudRate
= 600;
1009 lpdcb
->BaudRate
= 1200;
1012 lpdcb
->BaudRate
= 2400;
1015 lpdcb
->BaudRate
= 4800;
1018 lpdcb
->BaudRate
= 9600;
1021 lpdcb
->BaudRate
= 19200;
1024 lpdcb
->BaudRate
= 38400;
1028 lpdcb
->BaudRate
= 57600;
1033 lpdcb
->BaudRate
= 57601;
1038 switch (port
.c_cflag
& CSIZE
) {
1040 lpdcb
->ByteSize
= 5;
1043 lpdcb
->ByteSize
= 6;
1046 lpdcb
->ByteSize
= 7;
1049 lpdcb
->ByteSize
= 8;
1053 if(port
.c_iflag
& INPCK
)
1054 lpdcb
->fParity
= TRUE
;
1056 lpdcb
->fParity
= FALSE
;
1057 switch (port
.c_cflag
& (PARENB
| PARODD
)) {
1059 lpdcb
->Parity
= NOPARITY
;
1062 lpdcb
->Parity
= EVENPARITY
;
1064 case (PARENB
| PARODD
):
1065 lpdcb
->Parity
= ODDPARITY
;
1069 if (port
.c_cflag
& CSTOPB
)
1070 lpdcb
->StopBits
= TWOSTOPBITS
;
1072 lpdcb
->StopBits
= ONESTOPBIT
;
1074 lpdcb
->RlsTimeout
= 50;
1075 lpdcb
->CtsTimeout
= 50;
1076 lpdcb
->DsrTimeout
= 50;
1080 lpdcb
->fDtrDisable
= 0;
1084 if (port
.c_cflag
& CRTSCTS
) {
1085 lpdcb
->fDtrflow
= 1;
1086 lpdcb
->fRtsflow
= 1;
1087 lpdcb
->fOutxCtsFlow
= 1;
1088 lpdcb
->fOutxDsrFlow
= 1;
1091 lpdcb
->fDtrDisable
= 1;
1093 if (port
.c_iflag
& IXON
)
1098 if (port
.c_iflag
& IXOFF
)
1107 lpdcb
->XoffLim
= 10;
1113 /*****************************************************************************
1114 * TransmitCommChar (USER.206)
1116 INT16 WINAPI
TransmitCommChar16(INT16 cid
,CHAR chTransmit
)
1118 struct DosDeviceStruct
*ptr
;
1120 TRACE(comm
, "cid %d, data %d \n", cid
, chTransmit
);
1121 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1125 if (ptr
->suspended
) {
1126 ptr
->commerror
= IE_HARDWARE
;
1130 if (ptr
->xmit
>= 0) {
1131 /* character already queued */
1132 /* FIXME: which error would Windows return? */
1133 ptr
->commerror
= CE_TXFULL
;
1137 if (ptr
->obuf_head
== ptr
->obuf_tail
) {
1138 /* transmit queue empty, try to transmit directly */
1139 if (write(ptr
->fd
, &chTransmit
, 1) == -1) {
1140 /* didn't work, queue it */
1141 ptr
->xmit
= chTransmit
;
1144 /* data in queue, let this char be transmitted next */
1145 ptr
->xmit
= chTransmit
;
1152 /*****************************************************************************
1153 * UngetCommChar (USER.212)
1155 INT16 WINAPI
UngetCommChar16(INT16 cid
,CHAR chUnget
)
1157 struct DosDeviceStruct
*ptr
;
1159 TRACE(comm
,"cid %d (char %d)\n", cid
, chUnget
);
1160 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1164 if (ptr
->suspended
) {
1165 ptr
->commerror
= IE_HARDWARE
;
1169 if (ptr
->unget
>=0) {
1170 /* character already queued */
1171 /* FIXME: which error would Windows return? */
1172 ptr
->commerror
= CE_RXOVER
;
1176 ptr
->unget
= chUnget
;
1182 /*****************************************************************************
1183 * ReadComm (USER.204)
1185 INT16 WINAPI
ReadComm16(INT16 cid
,LPSTR lpvBuf
,INT16 cbRead
)
1188 struct DosDeviceStruct
*ptr
;
1189 LPSTR orgBuf
= lpvBuf
;
1191 TRACE(comm
, "cid %d, ptr %p, length %d\n", cid
, lpvBuf
, cbRead
);
1192 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1196 if (ptr
->suspended
) {
1197 ptr
->commerror
= IE_HARDWARE
;
1201 /* read unget character */
1202 if (ptr
->unget
>=0) {
1203 *lpvBuf
++ = ptr
->unget
;
1210 /* read from receive buffer */
1211 while (length
< cbRead
) {
1212 status
= ((ptr
->ibuf_head
< ptr
->ibuf_tail
) ?
1213 ptr
->ibuf_size
: ptr
->ibuf_head
) - ptr
->ibuf_tail
;
1215 if ((cbRead
- length
) < status
)
1216 status
= cbRead
- length
;
1218 memcpy(lpvBuf
, ptr
->inbuf
+ ptr
->ibuf_tail
, status
);
1219 ptr
->ibuf_tail
+= status
;
1220 if (ptr
->ibuf_tail
>= ptr
->ibuf_size
)
1226 TRACE(comm
,"%.*s\n", length
, orgBuf
);
1231 /*****************************************************************************
1232 * WriteComm (USER.205)
1234 INT16 WINAPI
WriteComm16(INT16 cid
, LPSTR lpvBuf
, INT16 cbWrite
)
1237 struct DosDeviceStruct
*ptr
;
1239 TRACE(comm
,"cid %d, ptr %p, length %d\n",
1240 cid
, lpvBuf
, cbWrite
);
1241 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1245 if (ptr
->suspended
) {
1246 ptr
->commerror
= IE_HARDWARE
;
1250 TRACE(comm
,"%.*s\n", cbWrite
, lpvBuf
);
1253 while (length
< cbWrite
) {
1254 if ((ptr
->obuf_head
== ptr
->obuf_tail
) && (ptr
->xmit
< 0)) {
1255 /* no data queued, try to write directly */
1256 status
= write(ptr
->fd
, lpvBuf
, cbWrite
- length
);
1263 /* can't write directly, put into transmit buffer */
1264 status
= ((ptr
->obuf_tail
> ptr
->obuf_head
) ?
1265 (ptr
->obuf_tail
-1) : ptr
->obuf_size
) - ptr
->obuf_head
;
1267 if ((cbWrite
- length
) < status
)
1268 status
= cbWrite
- length
;
1269 memcpy(lpvBuf
, ptr
->outbuf
+ ptr
->obuf_head
, status
);
1270 ptr
->obuf_head
+= status
;
1271 if (ptr
->obuf_head
>= ptr
->obuf_size
)
1281 /***********************************************************************
1282 * EnableCommNotification (USER.246)
1284 BOOL16 WINAPI
EnableCommNotification16( INT16 cid
, HWND16 hwnd
,
1285 INT16 cbWriteNotify
, INT16 cbOutQueue
)
1287 struct DosDeviceStruct
*ptr
;
1289 TRACE(comm
, "(%d, %x, %d, %d)\n", cid
, hwnd
, cbWriteNotify
, cbOutQueue
);
1290 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1291 ptr
->commerror
= IE_BADID
;
1295 ptr
->n_read
= cbWriteNotify
;
1296 ptr
->n_write
= cbOutQueue
;
1301 /**************************************************************************
1302 * BuildCommDCBA (KERNEL32.14)
1304 BOOL WINAPI
BuildCommDCBA(LPCSTR device
,LPDCB lpdcb
)
1306 return BuildCommDCBAndTimeoutsA(device
,lpdcb
,NULL
);
1309 /**************************************************************************
1310 * BuildCommDCBAndTimeoutsA (KERNEL32.15)
1312 BOOL WINAPI
BuildCommDCBAndTimeoutsA(LPCSTR device
, LPDCB lpdcb
,
1313 LPCOMMTIMEOUTS lptimeouts
)
1318 TRACE(comm
,"(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
1320 if (!lstrncmpiA(device
,"COM",3)) {
1323 ERR(comm
,"BUG! COM0 can't exists!.\n");
1326 if (!ValidCOMPort(port
))
1328 if (*(device
+4)!=':')
1330 temp
=(LPSTR
)(device
+5);
1334 memset(lpdcb
, 0, sizeof(DCB
)); /* initialize */
1336 lpdcb
->DCBlength
= sizeof(DCB
);
1337 if (strchr(temp
,',')) { /* old style */
1340 char last
=temp
[strlen(temp
)-1];
1342 ret
=BuildCommDCB16(device
,&dcb16
);
1345 lpdcb
->BaudRate
= dcb16
.BaudRate
;
1346 lpdcb
->ByteSize
= dcb16
.ByteSize
;
1347 lpdcb
->fBinary
= dcb16
.fBinary
;
1348 lpdcb
->Parity
= dcb16
.Parity
;
1349 lpdcb
->fParity
= dcb16
.fParity
;
1350 lpdcb
->fNull
= dcb16
.fNull
;
1351 lpdcb
->StopBits
= dcb16
.StopBits
;
1354 lpdcb
->fOutX
= TRUE
;
1355 lpdcb
->fOutxCtsFlow
= FALSE
;
1356 lpdcb
->fOutxDsrFlow
= FALSE
;
1357 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1358 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1359 } else if (last
=='p') {
1360 lpdcb
->fInX
= FALSE
;
1361 lpdcb
->fOutX
= FALSE
;
1362 lpdcb
->fOutxCtsFlow
= TRUE
;
1363 lpdcb
->fOutxDsrFlow
= TRUE
;
1364 lpdcb
->fDtrControl
= DTR_CONTROL_HANDSHAKE
;
1365 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
1367 lpdcb
->fInX
= FALSE
;
1368 lpdcb
->fOutX
= FALSE
;
1369 lpdcb
->fOutxCtsFlow
= FALSE
;
1370 lpdcb
->fOutxDsrFlow
= FALSE
;
1371 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1372 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1374 lpdcb
->XonChar
= dcb16
.XonChar
;
1375 lpdcb
->XoffChar
= dcb16
.XoffChar
;
1376 lpdcb
->ErrorChar
= dcb16
.PeChar
;
1377 lpdcb
->fErrorChar
= dcb16
.fPeChar
;
1378 lpdcb
->EofChar
= dcb16
.EofChar
;
1379 lpdcb
->EvtChar
= dcb16
.EvtChar
;
1380 lpdcb
->XonLim
= dcb16
.XonLim
;
1381 lpdcb
->XoffLim
= dcb16
.XoffLim
;
1384 ptr
=strtok(temp
," ");
1389 if (!strncmp("baud=",ptr
,5)) {
1390 if (!sscanf(ptr
+5,"%ld",&x
))
1391 WARN(comm
,"Couldn't parse %s\n",ptr
);
1392 lpdcb
->BaudRate
= x
;
1395 if (!strncmp("stop=",ptr
,5)) {
1396 if (!sscanf(ptr
+5,"%ld",&x
))
1397 WARN(comm
,"Couldn't parse %s\n",ptr
);
1398 lpdcb
->StopBits
= x
;
1401 if (!strncmp("data=",ptr
,5)) {
1402 if (!sscanf(ptr
+5,"%ld",&x
))
1403 WARN(comm
,"Couldn't parse %s\n",ptr
);
1404 lpdcb
->ByteSize
= x
;
1407 if (!strncmp("parity=",ptr
,7)) {
1408 lpdcb
->fParity
= TRUE
;
1411 lpdcb
->fParity
= FALSE
;
1412 lpdcb
->Parity
= NOPARITY
;
1415 lpdcb
->Parity
= EVENPARITY
;
1418 lpdcb
->Parity
= ODDPARITY
;
1421 lpdcb
->Parity
= MARKPARITY
;
1427 ERR(comm
,"Unhandled specifier '%s', please report.\n",ptr
);
1428 ptr
=strtok(NULL
," ");
1430 if (lpdcb
->BaudRate
==110)
1431 lpdcb
->StopBits
= 2;
1435 /**************************************************************************
1436 * BuildCommDCBAndTimeoutsW (KERNEL32.16)
1438 BOOL WINAPI
BuildCommDCBAndTimeoutsW( LPCWSTR devid
, LPDCB lpdcb
,
1439 LPCOMMTIMEOUTS lptimeouts
)
1444 TRACE(comm
,"(%p,%p,%p)\n",devid
,lpdcb
,lptimeouts
);
1445 devidA
= HEAP_strdupWtoA( GetProcessHeap(), 0, devid
);
1446 ret
=BuildCommDCBAndTimeoutsA(devidA
,lpdcb
,lptimeouts
);
1447 HeapFree( GetProcessHeap(), 0, devidA
);
1451 /**************************************************************************
1452 * BuildCommDCBW (KERNEL32.17)
1454 BOOL WINAPI
BuildCommDCBW(LPCWSTR devid
,LPDCB lpdcb
)
1456 return BuildCommDCBAndTimeoutsW(devid
,lpdcb
,NULL
);
1459 /*****************************************************************************
1461 * returns a file descriptor for reading from or writing to
1462 * mode is GENERIC_READ or GENERIC_WRITE. Make sure to close
1463 * the handle afterwards!
1465 int COMM_Handle2fd(HANDLE handle
, int mode
) {
1466 struct get_read_fd_request r_req
;
1467 struct get_write_fd_request w_req
;
1470 w_req
.handle
= r_req
.handle
= handle
;
1474 CLIENT_SendRequest( REQ_GET_WRITE_FD
, -1, 1, &w_req
, sizeof(w_req
) );
1477 CLIENT_SendRequest( REQ_GET_READ_FD
, -1, 1, &r_req
, sizeof(r_req
) );
1480 ERR(comm
,"COMM_Handle2fd: Don't know what type of fd is required.\n");
1483 CLIENT_WaitReply( NULL
, &fd
, 0 );
1488 /* FIXME: having these global for win32 for now */
1489 int commerror
=0,eventmask
=0;
1491 /*****************************************************************************
1492 * SetCommBreak (KERNEL32.449)
1494 BOOL WINAPI
SetCommBreak(HANDLE handle
)
1496 FIXME(comm
,"handle %d, stub!\n", handle
);
1500 /*****************************************************************************
1501 * ClearCommBreak (KERNEL32.20)
1503 BOOL WINAPI
ClearCommBreak(HANDLE handle
)
1505 FIXME(comm
,"handle %d, stub!\n", handle
);
1509 /*****************************************************************************
1510 * EscapeCommFunction (KERNEL32.214)
1512 BOOL WINAPI
EscapeCommFunction(HANDLE handle
,UINT nFunction
)
1515 struct termios port
;
1517 TRACE(comm
,"handle %d, function=%d\n", handle
, nFunction
);
1518 fd
= COMM_Handle2fd(handle
, GENERIC_WRITE
);
1522 if (tcgetattr(fd
,&port
) == -1) {
1523 commerror
=WinError();
1528 switch (nFunction
) {
1534 port
.c_cflag
&= TIOCM_DTR
;
1540 port
.c_cflag
&= TIOCM_RTS
;
1546 port
.c_cflag
|= CRTSCTS
;
1550 port
.c_cflag
|= CRTSCTS
;
1555 port
.c_iflag
|= IXOFF
;
1559 port
.c_iflag
|= IXON
;
1562 FIXME(comm
,"setbreak, stub\n");
1563 /* ptr->suspended = 1; */
1566 FIXME(comm
,"clrbreak, stub\n");
1567 /* ptr->suspended = 0; */
1570 WARN(comm
,"(handle=%d,nFunction=%d): Unknown function\n",
1575 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
1576 commerror
= WinError();
1586 /********************************************************************
1587 * PurgeComm (KERNEL32.557)
1589 BOOL WINAPI
PurgeComm( HANDLE handle
, DWORD flags
)
1593 TRACE(comm
,"handle %d, flags %lx\n", handle
, flags
);
1595 fd
= COMM_Handle2fd(handle
, GENERIC_WRITE
);
1600 ** not exactly sure how these are different
1601 ** Perhaps if we had our own internal queues, one flushes them
1602 ** and the other flushes the kernel's buffers.
1604 if(flags
&PURGE_TXABORT
)
1606 tcflush(fd
,TCOFLUSH
);
1608 if(flags
&PURGE_RXABORT
)
1610 tcflush(fd
,TCIFLUSH
);
1612 if(flags
&PURGE_TXCLEAR
)
1614 tcflush(fd
,TCOFLUSH
);
1616 if(flags
&PURGE_RXCLEAR
)
1618 tcflush(fd
,TCIFLUSH
);
1625 /*****************************************************************************
1626 * ClearCommError (KERNEL32.21)
1628 BOOL WINAPI
ClearCommError(INT handle
,LPDWORD errors
,LPCOMSTAT lpStat
)
1632 fd
=COMM_Handle2fd(handle
,GENERIC_READ
);
1642 if(ioctl(fd
, TIOCOUTQ
, &lpStat
->cbOutQue
))
1643 WARN(comm
, "ioctl returned error\n");
1645 if(ioctl(fd
, TIOCINQ
, &lpStat
->cbInQue
))
1646 WARN(comm
, "ioctl returned error\n");
1651 TRACE(comm
,"handle %d cbInQue = %ld cbOutQue = %ld\n",
1660 ** After an asynchronous write opperation, the
1661 ** app will call ClearCommError to see if the
1662 ** results are ready yet. It waits for ERROR_IO_PENDING
1664 commerror
= ERROR_IO_PENDING
;
1669 /*****************************************************************************
1670 * SetupComm (KERNEL32.676)
1672 BOOL WINAPI
SetupComm( HANDLE handle
, DWORD insize
, DWORD outsize
)
1676 FIXME(comm
, "insize %ld outsize %ld unimplemented stub\n", insize
, outsize
);
1677 fd
=COMM_Handle2fd(handle
,GENERIC_WRITE
);
1686 /*****************************************************************************
1687 * GetCommMask (KERNEL32.156)
1689 BOOL WINAPI
GetCommMask(HANDLE handle
,LPDWORD evtmask
)
1693 TRACE(comm
, "handle %d, mask %p\n", handle
, evtmask
);
1694 if(0>(fd
=COMM_Handle2fd(handle
,GENERIC_READ
)))
1699 *evtmask
= eventmask
;
1703 /*****************************************************************************
1704 * SetCommMask (KERNEL32.451)
1706 BOOL WINAPI
SetCommMask(INT handle
,DWORD evtmask
)
1710 TRACE(comm
, "handle %d, mask %lx\n", handle
, evtmask
);
1711 if(0>(fd
=COMM_Handle2fd(handle
,GENERIC_WRITE
))) {
1715 eventmask
= evtmask
;
1719 /*****************************************************************************
1720 * SetCommState (KERNEL32.452)
1722 BOOL WINAPI
SetCommState(INT handle
,LPDCB lpdcb
)
1724 struct termios port
;
1726 struct get_write_fd_request req
;
1728 TRACE(comm
,"handle %d, ptr %p\n", handle
, lpdcb
);
1730 req
.handle
= handle
;
1731 CLIENT_SendRequest( REQ_GET_WRITE_FD
, -1, 1, &req
, sizeof(req
) );
1732 CLIENT_WaitReply( NULL
, &fd
, 0 );
1737 if (tcgetattr(fd
,&port
) == -1) {
1738 commerror
= WinError();
1742 port
.c_cc
[VMIN
] = 0;
1743 port
.c_cc
[VTIME
] = 1;
1746 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
1748 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
1750 port
.c_iflag
|= (IGNBRK
);
1752 port
.c_oflag
&= ~(OPOST
);
1754 port
.c_cflag
&= ~(HUPCL
);
1755 port
.c_cflag
|= CLOCAL
| CREAD
;
1757 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
1758 port
.c_lflag
|= NOFLSH
;
1761 ** MJM - removed default baudrate settings
1762 ** TRACE(comm,"baudrate %ld\n",lpdcb->BaudRate);
1765 port
.c_cflag
&= ~CBAUD
;
1766 switch (lpdcb
->BaudRate
) {
1769 port
.c_cflag
|= B110
;
1773 port
.c_cflag
|= B300
;
1777 port
.c_cflag
|= B600
;
1781 port
.c_cflag
|= B1200
;
1785 port
.c_cflag
|= B2400
;
1789 port
.c_cflag
|= B4800
;
1793 port
.c_cflag
|= B9600
;
1797 port
.c_cflag
|= B19200
;
1801 port
.c_cflag
|= B38400
;
1804 commerror
= IE_BAUDRATE
;
1807 #elif !defined(__EMX__)
1808 switch (lpdcb
->BaudRate
) {
1811 port
.c_ospeed
= B110
;
1815 port
.c_ospeed
= B300
;
1819 port
.c_ospeed
= B600
;
1823 port
.c_ospeed
= B1200
;
1827 port
.c_ospeed
= B2400
;
1831 port
.c_ospeed
= B4800
;
1835 port
.c_ospeed
= B9600
;
1839 port
.c_ospeed
= B19200
;
1843 port
.c_ospeed
= B38400
;
1846 commerror
= IE_BAUDRATE
;
1849 port
.c_ispeed
= port
.c_ospeed
;
1851 TRACE(comm
,"bytesize %d\n",lpdcb
->ByteSize
);
1852 port
.c_cflag
&= ~CSIZE
;
1853 switch (lpdcb
->ByteSize
) {
1855 port
.c_cflag
|= CS5
;
1858 port
.c_cflag
|= CS6
;
1861 port
.c_cflag
|= CS7
;
1864 port
.c_cflag
|= CS8
;
1867 commerror
= IE_BYTESIZE
;
1871 TRACE(comm
,"fParity %d Parity %d\n",lpdcb
->fParity
, lpdcb
->Parity
);
1872 port
.c_cflag
&= ~(PARENB
| PARODD
);
1874 port
.c_iflag
|= INPCK
;
1876 port
.c_iflag
&= ~INPCK
;
1877 switch (lpdcb
->Parity
) {
1881 port
.c_cflag
|= (PARENB
| PARODD
);
1884 port
.c_cflag
|= PARENB
;
1887 commerror
= IE_BYTESIZE
;
1892 TRACE(comm
,"stopbits %d\n",lpdcb
->StopBits
);
1893 switch (lpdcb
->StopBits
) {
1895 port
.c_cflag
&= ~CSTOPB
;
1898 port
.c_cflag
|= CSTOPB
;
1901 commerror
= IE_BYTESIZE
;
1905 if ( lpdcb
->fOutxCtsFlow
||
1906 lpdcb
->fDtrControl
== DTR_CONTROL_ENABLE
||
1907 lpdcb
->fRtsControl
== RTS_CONTROL_ENABLE
1909 port
.c_cflag
|= CRTSCTS
;
1910 if (lpdcb
->fDtrControl
== DTR_CONTROL_DISABLE
)
1911 port
.c_cflag
&= ~CRTSCTS
;
1915 port
.c_iflag
|= IXON
;
1917 port
.c_iflag
&= ~IXON
;
1919 port
.c_iflag
|= IXOFF
;
1921 port
.c_iflag
&= ~IXOFF
;
1923 if (tcsetattr(fd
,TCSADRAIN
,&port
)==-1) {
1924 commerror
= WinError();
1933 /*****************************************************************************
1934 * GetCommState (KERNEL32.159)
1936 BOOL WINAPI
GetCommState(INT handle
, LPDCB lpdcb
)
1938 struct termios port
;
1940 struct get_read_fd_request req
;
1942 TRACE(comm
,"handle %d, ptr %p\n", handle
, lpdcb
);
1943 req
.handle
= handle
;
1944 CLIENT_SendRequest( REQ_GET_READ_FD
, -1, 1, &req
, sizeof(req
) );
1945 CLIENT_WaitReply( NULL
, &fd
, 0 );
1950 if (tcgetattr(fd
, &port
) == -1) {
1951 TRACE(comm
,"tcgetattr(%d, ...) returned -1",fd
);
1952 commerror
= WinError();
1957 switch (port
.c_cflag
& CBAUD
) {
1959 switch (port
.c_ospeed
) {
1962 lpdcb
->BaudRate
= 110;
1965 lpdcb
->BaudRate
= 300;
1968 lpdcb
->BaudRate
= 600;
1971 lpdcb
->BaudRate
= 1200;
1974 lpdcb
->BaudRate
= 2400;
1977 lpdcb
->BaudRate
= 4800;
1980 lpdcb
->BaudRate
= 9600;
1983 lpdcb
->BaudRate
= 19200;
1986 lpdcb
->BaudRate
= 38400;
1990 switch (port
.c_cflag
& CSIZE
) {
1992 lpdcb
->ByteSize
= 5;
1995 lpdcb
->ByteSize
= 6;
1998 lpdcb
->ByteSize
= 7;
2001 lpdcb
->ByteSize
= 8;
2005 if(port
.c_iflag
& INPCK
)
2006 lpdcb
->fParity
= TRUE
;
2008 lpdcb
->fParity
= FALSE
;
2009 switch (port
.c_cflag
& (PARENB
| PARODD
)) {
2011 lpdcb
->Parity
= NOPARITY
;
2014 lpdcb
->Parity
= EVENPARITY
;
2016 case (PARENB
| PARODD
):
2017 lpdcb
->Parity
= ODDPARITY
;
2021 if (port
.c_cflag
& CSTOPB
)
2022 lpdcb
->StopBits
= TWOSTOPBITS
;
2024 lpdcb
->StopBits
= ONESTOPBIT
;
2031 if (port
.c_cflag
& CRTSCTS
) {
2032 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
2033 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
2034 lpdcb
->fOutxCtsFlow
= 1;
2035 lpdcb
->fOutxDsrFlow
= 1;
2039 lpdcb
->fDtrControl
= DTR_CONTROL_DISABLE
;
2040 lpdcb
->fRtsControl
= RTS_CONTROL_DISABLE
;
2042 if (port
.c_iflag
& IXON
)
2047 if (port
.c_iflag
& IXOFF
)
2056 lpdcb
->XoffLim
= 10;
2065 /*****************************************************************************
2066 * TransmitCommChar (KERNEL32.535)
2068 BOOL WINAPI
TransmitCommChar(INT cid
,CHAR chTransmit
)
2070 struct DosDeviceStruct
*ptr
;
2072 FIXME(comm
,"(%d,'%c'), use win32 handle!\n",cid
,chTransmit
);
2073 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
2077 if (ptr
->suspended
) {
2078 ptr
->commerror
= IE_HARDWARE
;
2081 if (write(ptr
->fd
, (void *) &chTransmit
, 1) == -1) {
2082 ptr
->commerror
= WinError();
2090 /*****************************************************************************
2091 * GetCommTimeouts (KERNEL32.160)
2093 BOOL WINAPI
GetCommTimeouts(INT cid
,LPCOMMTIMEOUTS lptimeouts
)
2095 FIXME(comm
,"(%x,%p):stub.\n",cid
,lptimeouts
);
2099 /*****************************************************************************
2100 * SetCommTimeouts (KERNEL32.453)
2102 BOOL WINAPI
SetCommTimeouts(INT cid
,LPCOMMTIMEOUTS lptimeouts
) {
2103 FIXME(comm
,"(%x,%p):stub.\n",cid
,lptimeouts
);
2107 /***********************************************************************
2108 * GetCommModemStatus (KERNEL32.285)
2110 BOOL WINAPI
GetCommModemStatus(HANDLE hFile
,LPDWORD lpModemStat
)
2112 FIXME(comm
, "(%d %p)\n",hFile
,lpModemStat
);
2115 /***********************************************************************
2116 * WaitCommEvent (KERNEL32.719)
2118 BOOL WINAPI
WaitCommEvent(HANDLE hFile
,LPDWORD eventmask
,LPOVERLAPPED overlapped
)
2120 FIXME(comm
, "(%d %p %p )\n",hFile
, eventmask
,overlapped
);
2124 /***********************************************************************
2125 * GetCommProperties (KERNEL32.???)
2127 BOOL WINAPI
GetCommProperties(HANDLE hFile
, LPDCB
*dcb
)
2129 FIXME(comm
, "(%d %p )\n",hFile
,dcb
);
2133 /***********************************************************************
2134 * SetCommProperties (KERNEL32.???)
2136 BOOL WINAPI
SetCommProperties(HANDLE hFile
, LPDCB dcb
)
2138 FIXME(comm
, "(%d %p )\n",hFile
,dcb
);