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 * Mar 3, 1999. Ove Kåven <ovek@arcticnet.no>
10 * - Use port indices instead of unixfds for win16
11 * - Moved things around (separated win16 and win32 routines)
12 * - Added some hints on how to implement buffers and EnableCommNotification.
14 * May 26, 1997. Fixes and comments by Rick Richardson <rick@dgii.com> [RER]
15 * - ptr->fd wasn't getting cleared on close.
16 * - GetCommEventMask() and GetCommError() didn't do much of anything.
17 * IMHO, they are still wrong, but they at least implement the RXCHAR
18 * event and return I/O queue sizes, which makes the app I'm interested
19 * in (analog devices EZKIT DSP development system) work.
21 * August 12, 1997. Take a bash at SetCommEventMask - Lawson Whitney
22 * <lawson_whitney@juno.com>
23 * July 6, 1998. Fixes and comments by Valentijn Sessink
24 * <vsessink@ic.uva.nl> [V]
25 * Oktober 98, Rein Klazes [RHK]
26 * A program that wants to monitor the modem status line (RLSD/DCD) may
27 * poll the modem status register in the commMask structure. I update the bit
28 * in GetCommError, waiting for an implementation of communication events.
44 #ifdef HAVE_SYS_FILIO_H
45 # include <sys/filio.h>
47 #include <sys/ioctl.h>
50 #include "wine/winuser16.h"
52 #ifdef HAVE_SYS_MODEM_H
53 # include <sys/modem.h>
55 #ifdef HAVE_SYS_STRTIO_H
56 # include <sys/strtio.h>
61 #include "server/request.h"
70 #define TIOCINQ FIONREAD
72 #define COMM_MSR_OFFSET 35 /* see knowledge base Q101417 */
74 struct DosDeviceStruct COM
[MAX_PORTS
];
75 struct DosDeviceStruct LPT
[MAX_PORTS
];
76 /* pointers to unknown(==undocumented) comm structure */
77 LPCVOID
*unknown
[MAX_PORTS
];
78 /* save terminal states */
79 static struct termios m_stat
[MAX_PORTS
];
84 char option
[10], temp
[256], *btemp
;
87 for (x
=0; x
!=MAX_PORTS
; x
++) {
88 strcpy(option
,"COMx");
92 PROFILE_GetWineIniString( "serialports", option
, "*",
94 if (!strcmp(temp
, "*") || *temp
== '\0')
95 COM
[x
].devicename
= NULL
;
97 btemp
= strchr(temp
,',');
100 COM
[x
].baudrate
= atoi(btemp
);
102 COM
[x
].baudrate
= -1;
105 if (!S_ISCHR(st
.st_mode
))
106 WARN(comm
,"Can't use `%s' as %s !\n", temp
, option
);
108 if ((COM
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
109 WARN(comm
,"Can't malloc for device info!\n");
112 strcpy(COM
[x
].devicename
, temp
);
114 TRACE(comm
, "%s = %s\n", option
, COM
[x
].devicename
);
117 strcpy(option
, "LPTx");
121 PROFILE_GetWineIniString( "parallelports", option
, "*",
122 temp
, sizeof(temp
) );
123 if (!strcmp(temp
, "*") || *temp
== '\0')
124 LPT
[x
].devicename
= NULL
;
127 if (!S_ISCHR(st
.st_mode
))
128 WARN(comm
,"Can't use `%s' as %s !\n", temp
, option
);
130 if ((LPT
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
131 WARN(comm
,"Can't malloc for device info!\n");
134 strcpy(LPT
[x
].devicename
, temp
);
136 TRACE(comm
, "%s = %s\n", option
, LPT
[x
].devicename
);
143 struct DosDeviceStruct
*GetDeviceStruct_fd(int fd
)
147 for (x
=0; x
!=MAX_PORTS
; x
++) {
157 struct DosDeviceStruct
*GetDeviceStruct(int fd
)
159 if ((fd
&0x7F)<=MAX_PORTS
) {
172 int GetCommPort_fd(int fd
)
176 for (x
=0; x
<MAX_PORTS
; x
++) {
184 int ValidCOMPort(int x
)
186 return(x
< MAX_PORTS
? (int) COM
[x
].devicename
: 0);
189 int ValidLPTPort(int x
)
191 return(x
< MAX_PORTS
? (int) LPT
[x
].devicename
: 0);
196 TRACE(comm
, "errno = %d\n", errno
);
203 static unsigned comm_inbuf(struct DosDeviceStruct
*ptr
)
205 return ((ptr
->ibuf_tail
> ptr
->ibuf_head
) ? ptr
->ibuf_size
: 0)
206 + ptr
->ibuf_head
- ptr
->ibuf_tail
;
209 static unsigned comm_outbuf(struct DosDeviceStruct
*ptr
)
211 return ((ptr
->obuf_tail
> ptr
->obuf_head
) ? ptr
->obuf_size
: 0)
212 + ptr
->obuf_head
- ptr
->obuf_tail
;
215 static void comm_notification(int fd
,void*private)
217 struct DosDeviceStruct
*ptr
= (struct DosDeviceStruct
*)private;
218 int prev
, bleft
, len
;
220 int cid
= GetCommPort_fd(fd
);
222 /* read data from comm port */
223 prev
= comm_inbuf(ptr
);
225 bleft
= ((ptr
->ibuf_tail
> ptr
->ibuf_head
) ? (ptr
->ibuf_tail
-1) : ptr
->ibuf_size
)
227 len
= read(fd
, ptr
->inbuf
+ ptr
->ibuf_head
, bleft
?bleft
:1);
230 ptr
->commerror
= CE_RXOVER
;
232 ptr
->ibuf_head
+= len
;
233 if (ptr
->ibuf_head
>= ptr
->ibuf_size
)
236 if (ptr
->eventmask
& EV_RXCHAR
)
237 *(WORD
*)(unknown
[cid
]) |= EV_RXCHAR
;
238 /* FIXME: check for event character (EV_RXFLAG) */
242 /* check for notification */
243 if (ptr
->wnd
&& (ptr
->n_read
>0) && (prev
<ptr
->n_read
) &&
244 (comm_inbuf(ptr
)>=ptr
->n_read
)) {
245 /* passed the receive notification threshold */
249 /* write any TransmitCommChar character */
251 len
= write(fd
, &(ptr
->xmit
), 1);
252 if (len
> 0) ptr
->xmit
= -1;
254 /* write from output queue */
255 prev
= comm_outbuf(ptr
);
257 bleft
= ((ptr
->obuf_tail
< ptr
->obuf_head
) ? ptr
->obuf_head
: ptr
->obuf_size
)
259 len
= bleft
? write(fd
, ptr
->outbuf
+ ptr
->obuf_tail
, bleft
) : 0;
261 ptr
->obuf_tail
+= len
;
262 if (ptr
->obuf_tail
>= ptr
->obuf_size
)
265 if ((ptr
->obuf_tail
== ptr
->obuf_head
) && (ptr
->eventmask
& EV_TXEMPTY
))
266 *(WORD
*)(unknown
[cid
]) |= EV_TXEMPTY
;
269 /* check for notification */
270 if (ptr
->wnd
&& (ptr
->n_write
>0) && (prev
>=ptr
->n_write
) &&
271 (comm_outbuf(ptr
)<ptr
->n_write
)) {
272 /* passed the transmit notification threshold */
276 /* send notifications, if any */
277 if (ptr
->wnd
&& mask
) {
278 PostMessage16(ptr
->wnd
, WM_COMMNOTIFY
, cid
, mask
);
282 /**************************************************************************
283 * BuildCommDCB (USER.213)
285 BOOL16 WINAPI
BuildCommDCB16(LPCSTR device
, LPDCB16 lpdcb
)
287 /* "COM1:9600,n,8,1" */
290 char *ptr
, temp
[256];
292 TRACE(comm
, "(%s), ptr %p\n", device
, lpdcb
);
294 if (!lstrncmpiA(device
,"COM",3)) {
295 port
= device
[3] - '0';
299 ERR(comm
, "BUG ! COM0 can't exist!.\n");
303 if (!ValidCOMPort(port
)) {
307 memset(lpdcb
, 0, sizeof(DCB16
)); /* initialize */
314 if (*(device
+4) != ':')
317 strcpy(temp
,device
+5);
318 ptr
= strtok(temp
, ", ");
320 if (COM
[port
].baudrate
> 0)
321 lpdcb
->BaudRate
= COM
[port
].baudrate
;
323 lpdcb
->BaudRate
= atoi(ptr
);
324 TRACE(comm
,"baudrate (%d)\n", lpdcb
->BaudRate
);
326 ptr
= strtok(NULL
, ", ");
328 *ptr
= toupper(*ptr
);
330 TRACE(comm
,"parity (%c)\n", *ptr
);
331 lpdcb
->fParity
= TRUE
;
334 lpdcb
->Parity
= NOPARITY
;
335 lpdcb
->fParity
= FALSE
;
338 lpdcb
->Parity
= EVENPARITY
;
341 lpdcb
->Parity
= MARKPARITY
;
344 lpdcb
->Parity
= ODDPARITY
;
347 WARN(comm
,"Unknown parity `%c'!\n", *ptr
);
351 ptr
= strtok(NULL
, ", ");
352 TRACE(comm
, "charsize (%c)\n", *ptr
);
353 lpdcb
->ByteSize
= *ptr
- '0';
355 ptr
= strtok(NULL
, ", ");
356 TRACE(comm
, "stopbits (%c)\n", *ptr
);
359 lpdcb
->StopBits
= ONESTOPBIT
;
362 lpdcb
->StopBits
= TWOSTOPBITS
;
365 WARN(comm
,"Unknown # of stopbits `%c'!\n", *ptr
);
373 /*****************************************************************************
374 * OpenComm (USER.200)
376 INT16 WINAPI
OpenComm16(LPCSTR device
,UINT16 cbInQueue
,UINT16 cbOutQueue
)
380 TRACE(comm
, "%s, %d, %d\n", device
, cbInQueue
, cbOutQueue
);
382 if (!lstrncmpiA(device
,"COM",3)) {
383 port
= device
[3] - '0';
386 ERR(comm
, "BUG ! COM0 doesn't exist !\n");
389 TRACE(comm
, "%s = %s\n", device
, COM
[port
].devicename
);
391 if (!ValidCOMPort(port
)) {
398 fd
= open(COM
[port
].devicename
, O_RDWR
| O_NONBLOCK
);
402 unknown
[port
] = SEGPTR_ALLOC(40);
403 bzero(unknown
[port
],40);
405 COM
[port
].commerror
= 0;
406 COM
[port
].eventmask
= 0;
407 /* save terminal state */
408 tcgetattr(fd
,&m_stat
[port
]);
409 /* set default parameters */
410 if(COM
[port
].baudrate
>-1){
412 GetCommState16(port
, &dcb
);
413 dcb
.BaudRate
=COM
[port
].baudrate
;
415 * databits, parity, stopbits
417 SetCommState16( &dcb
);
419 /* init priority characters */
420 COM
[port
].unget
= -1;
422 /* allocate buffers */
423 COM
[port
].ibuf_size
= cbInQueue
;
424 COM
[port
].ibuf_head
= COM
[port
].ibuf_tail
= 0;
425 COM
[port
].obuf_size
= cbOutQueue
;
426 COM
[port
].obuf_head
= COM
[port
].obuf_tail
= 0;
428 COM
[port
].inbuf
= malloc(cbInQueue
);
429 if (COM
[port
].inbuf
) {
430 COM
[port
].outbuf
= malloc(cbOutQueue
);
431 if (!COM
[port
].outbuf
)
432 free(COM
[port
].inbuf
);
433 } else COM
[port
].outbuf
= NULL
;
434 if (!COM
[port
].outbuf
) {
435 /* not enough memory */
436 tcsetattr(COM
[port
].fd
,TCSANOW
,&m_stat
[port
]);
441 /* enable async notifications */
442 ASYNC_RegisterFD(COM
[port
].fd
,comm_notification
,&COM
[port
]);
447 if (!lstrncmpiA(device
,"LPT",3)) {
448 port
= device
[3] - '0';
451 ERR(comm
, "BUG ! LPT0 doesn't exist !\n");
454 if (!ValidLPTPort(port
)) {
461 fd
= open(LPT
[port
].devicename
, O_RDWR
| O_NONBLOCK
, 0);
466 LPT
[port
].commerror
= 0;
467 LPT
[port
].eventmask
= 0;
474 /*****************************************************************************
475 * CloseComm (USER.207)
477 INT16 WINAPI
CloseComm16(INT16 cid
)
479 struct DosDeviceStruct
*ptr
;
481 TRACE(comm
,"cid=%d\n", cid
);
482 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
487 SEGPTR_FREE(unknown
[cid
]); /* [LW] */
489 /* disable async notifications */
490 ASYNC_UnregisterFD(COM
[cid
].fd
,comm_notification
);
495 /* reset modem lines */
496 tcsetattr(ptr
->fd
,TCSANOW
,&m_stat
[cid
]);
499 if (close(ptr
->fd
) == -1) {
500 ptr
->commerror
= WinError();
501 /* FIXME: should we clear ptr->fd here? */
510 /*****************************************************************************
511 * SetCommBreak (USER.210)
513 INT16 WINAPI
SetCommBreak16(INT16 cid
)
515 struct DosDeviceStruct
*ptr
;
517 TRACE(comm
,"cid=%d\n", cid
);
518 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
527 /*****************************************************************************
528 * ClearCommBreak (USER.211)
530 INT16 WINAPI
ClearCommBreak16(INT16 cid
)
532 struct DosDeviceStruct
*ptr
;
534 TRACE(comm
,"cid=%d\n", cid
);
535 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
544 /*****************************************************************************
545 * EscapeCommFunction (USER.214)
547 LONG WINAPI
EscapeCommFunction16(UINT16 cid
,UINT16 nFunction
)
550 struct DosDeviceStruct
*ptr
;
553 TRACE(comm
,"cid=%d, function=%d\n", cid
, nFunction
);
554 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
557 if (tcgetattr(ptr
->fd
,&port
) == -1) {
558 ptr
->commerror
=WinError();
567 for (max
= MAX_PORTS
;!COM
[max
].devicename
;max
--)
573 for (max
= MAX_PORTS
;!LPT
[max
].devicename
;max
--)
580 port
.c_cflag
&= TIOCM_DTR
;
586 port
.c_cflag
&= TIOCM_RTS
;
592 port
.c_cflag
|= CRTSCTS
;
596 port
.c_cflag
|= CRTSCTS
;
601 port
.c_iflag
|= IXOFF
;
605 port
.c_iflag
|= IXON
;
609 WARN(comm
,"(cid=%d,nFunction=%d): Unknown function\n",
614 if (tcsetattr(ptr
->fd
, TCSADRAIN
, &port
) == -1) {
615 ptr
->commerror
= WinError();
623 /*****************************************************************************
624 * FlushComm (USER.215)
626 INT16 WINAPI
FlushComm16(INT16 cid
,INT16 fnQueue
)
629 struct DosDeviceStruct
*ptr
;
631 TRACE(comm
,"cid=%d, queue=%d\n", cid
, fnQueue
);
632 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
638 ptr
->obuf_tail
= ptr
->obuf_head
;
642 ptr
->ibuf_head
= ptr
->ibuf_tail
;
645 WARN(comm
,"(cid=%d,fnQueue=%d):Unknown queue\n",
649 if (tcflush(ptr
->fd
, queue
)) {
650 ptr
->commerror
= WinError();
658 /********************************************************************
659 * GetCommError (USER.203)
661 INT16 WINAPI
GetCommError16(INT16 cid
,LPCOMSTAT16 lpStat
)
664 struct DosDeviceStruct
*ptr
;
668 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
672 WARN(comm
," cid %d not comm port\n",cid
);
675 stol
= (unsigned char *)unknown
[cid
] + COMM_MSR_OFFSET
;
676 ioctl(ptr
->fd
,TIOCMGET
,&mstat
);
677 if( mstat
&TIOCM_CAR
)
685 lpStat
->cbOutQue
= comm_outbuf(ptr
);
686 lpStat
->cbInQue
= comm_inbuf(ptr
);
688 TRACE(comm
, "cid %d, error %d, lpStat %d %d %d stol %x\n",
689 cid
, ptr
->commerror
, lpStat
->status
, lpStat
->cbInQue
,
690 lpStat
->cbOutQue
, *stol
);
693 TRACE(comm
, "cid %d, error %d, lpStat NULL stol %x\n",
694 cid
, ptr
->commerror
, *stol
);
696 /* Return any errors and clear it */
697 temperror
= ptr
->commerror
;
702 /*****************************************************************************
703 * SetCommEventMask (USER.208)
705 SEGPTR WINAPI
SetCommEventMask16(INT16 cid
,UINT16 fuEvtMask
)
707 struct DosDeviceStruct
*ptr
;
712 TRACE(comm
,"cid %d,mask %d\n",cid
,fuEvtMask
);
713 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
716 ptr
->eventmask
= fuEvtMask
;
718 WARN(comm
," cid %d not comm port\n",cid
);
719 return SEGPTR_GET(NULL
);
721 stol
= (unsigned char *)unknown
[cid
] + COMM_MSR_OFFSET
;
722 repid
= ioctl(ptr
->fd
,TIOCMGET
,&mstat
);
723 TRACE(comm
, " ioctl %d, msr %x at %p %p\n",repid
,mstat
,stol
,unknown
[cid
]);
724 if ((mstat
&TIOCM_CAR
)) {*stol
|= 0x80;}
726 TRACE(comm
," modem dcd construct %x\n",*stol
);
727 return SEGPTR_GET(unknown
[cid
]);
730 /*****************************************************************************
731 * GetCommEventMask (USER.209)
733 UINT16 WINAPI
GetCommEventMask16(INT16 cid
,UINT16 fnEvtClear
)
735 struct DosDeviceStruct
*ptr
;
738 TRACE(comm
, "cid %d, mask %d\n", cid
, fnEvtClear
);
739 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
743 WARN(comm
," cid %d not comm port\n",cid
);
747 events
= *(WORD
*)(unknown
[cid
]) & fnEvtClear
;
748 *(WORD
*)(unknown
[cid
]) &= ~fnEvtClear
;
752 /*****************************************************************************
753 * SetCommState16 (USER.201)
755 INT16 WINAPI
SetCommState16(LPDCB16 lpdcb
)
758 struct DosDeviceStruct
*ptr
;
760 TRACE(comm
, "cid %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
761 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
764 if (tcgetattr(ptr
->fd
, &port
) == -1) {
765 ptr
->commerror
= WinError();
770 port
.c_cc
[VTIME
] = 1;
773 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
775 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
777 port
.c_iflag
|= (IGNBRK
);
779 port
.c_oflag
&= ~(OPOST
);
781 port
.c_cflag
&= ~(HUPCL
);
782 port
.c_cflag
|= CLOCAL
| CREAD
;
784 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
785 port
.c_lflag
|= NOFLSH
;
787 TRACE(comm
,"baudrate %d\n",lpdcb
->BaudRate
);
789 port
.c_cflag
&= ~CBAUD
;
790 switch (lpdcb
->BaudRate
) {
793 port
.c_cflag
|= B110
;
797 port
.c_cflag
|= B300
;
801 port
.c_cflag
|= B600
;
805 port
.c_cflag
|= B1200
;
809 port
.c_cflag
|= B2400
;
813 port
.c_cflag
|= B4800
;
817 port
.c_cflag
|= B9600
;
821 port
.c_cflag
|= B19200
;
825 port
.c_cflag
|= B38400
;
829 port
.c_cflag
|= B57600
;
834 port
.c_cflag
|= B115200
;
838 ptr
->commerror
= IE_BAUDRATE
;
841 #elif !defined(__EMX__)
842 switch (lpdcb
->BaudRate
) {
845 port
.c_ospeed
= B110
;
849 port
.c_ospeed
= B300
;
853 port
.c_ospeed
= B600
;
857 port
.c_ospeed
= B1200
;
861 port
.c_ospeed
= B2400
;
865 port
.c_ospeed
= B4800
;
869 port
.c_ospeed
= B9600
;
873 port
.c_ospeed
= B19200
;
877 port
.c_ospeed
= B38400
;
880 ptr
->commerror
= IE_BAUDRATE
;
883 port
.c_ispeed
= port
.c_ospeed
;
885 TRACE(comm
,"bytesize %d\n",lpdcb
->ByteSize
);
886 port
.c_cflag
&= ~CSIZE
;
887 switch (lpdcb
->ByteSize
) {
901 ptr
->commerror
= IE_BYTESIZE
;
905 TRACE(comm
,"fParity %d Parity %d\n",lpdcb
->fParity
, lpdcb
->Parity
);
906 port
.c_cflag
&= ~(PARENB
| PARODD
);
908 port
.c_iflag
|= INPCK
;
910 port
.c_iflag
&= ~INPCK
;
911 switch (lpdcb
->Parity
) {
915 port
.c_cflag
|= (PARENB
| PARODD
);
918 port
.c_cflag
|= PARENB
;
921 ptr
->commerror
= IE_BYTESIZE
;
926 TRACE(comm
,"stopbits %d\n",lpdcb
->StopBits
);
928 switch (lpdcb
->StopBits
) {
930 port
.c_cflag
&= ~CSTOPB
;
933 port
.c_cflag
|= CSTOPB
;
936 ptr
->commerror
= IE_BYTESIZE
;
941 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
942 port
.c_cflag
|= CRTSCTS
;
944 if (lpdcb
->fDtrDisable
)
945 port
.c_cflag
&= ~CRTSCTS
;
948 port
.c_iflag
|= IXON
;
950 port
.c_iflag
&= ~IXON
;
952 port
.c_iflag
|= IXOFF
;
954 port
.c_iflag
&= ~IXOFF
;
956 if (tcsetattr(ptr
->fd
, TCSADRAIN
, &port
) == -1) {
957 ptr
->commerror
= WinError();
965 /*****************************************************************************
966 * GetCommState (USER.202)
968 INT16 WINAPI
GetCommState16(INT16 cid
, LPDCB16 lpdcb
)
970 struct DosDeviceStruct
*ptr
;
973 TRACE(comm
,"cid %d, ptr %p\n", cid
, lpdcb
);
974 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
977 if (tcgetattr(ptr
->fd
, &port
) == -1) {
978 ptr
->commerror
= WinError();
984 switch (port
.c_cflag
& CBAUD
) {
986 switch (port
.c_ospeed
) {
989 lpdcb
->BaudRate
= 110;
992 lpdcb
->BaudRate
= 300;
995 lpdcb
->BaudRate
= 600;
998 lpdcb
->BaudRate
= 1200;
1001 lpdcb
->BaudRate
= 2400;
1004 lpdcb
->BaudRate
= 4800;
1007 lpdcb
->BaudRate
= 9600;
1010 lpdcb
->BaudRate
= 19200;
1013 lpdcb
->BaudRate
= 38400;
1017 lpdcb
->BaudRate
= 57600;
1022 lpdcb
->BaudRate
= 57601;
1027 switch (port
.c_cflag
& CSIZE
) {
1029 lpdcb
->ByteSize
= 5;
1032 lpdcb
->ByteSize
= 6;
1035 lpdcb
->ByteSize
= 7;
1038 lpdcb
->ByteSize
= 8;
1042 if(port
.c_iflag
& INPCK
)
1043 lpdcb
->fParity
= TRUE
;
1045 lpdcb
->fParity
= FALSE
;
1046 switch (port
.c_cflag
& (PARENB
| PARODD
)) {
1048 lpdcb
->Parity
= NOPARITY
;
1051 lpdcb
->Parity
= EVENPARITY
;
1053 case (PARENB
| PARODD
):
1054 lpdcb
->Parity
= ODDPARITY
;
1058 if (port
.c_cflag
& CSTOPB
)
1059 lpdcb
->StopBits
= TWOSTOPBITS
;
1061 lpdcb
->StopBits
= ONESTOPBIT
;
1063 lpdcb
->RlsTimeout
= 50;
1064 lpdcb
->CtsTimeout
= 50;
1065 lpdcb
->DsrTimeout
= 50;
1069 lpdcb
->fDtrDisable
= 0;
1073 if (port
.c_cflag
& CRTSCTS
) {
1074 lpdcb
->fDtrflow
= 1;
1075 lpdcb
->fRtsflow
= 1;
1076 lpdcb
->fOutxCtsFlow
= 1;
1077 lpdcb
->fOutxDsrFlow
= 1;
1080 lpdcb
->fDtrDisable
= 1;
1082 if (port
.c_iflag
& IXON
)
1087 if (port
.c_iflag
& IXOFF
)
1096 lpdcb
->XoffLim
= 10;
1102 /*****************************************************************************
1103 * TransmitCommChar (USER.206)
1105 INT16 WINAPI
TransmitCommChar16(INT16 cid
,CHAR chTransmit
)
1107 struct DosDeviceStruct
*ptr
;
1109 TRACE(comm
, "cid %d, data %d \n", cid
, chTransmit
);
1110 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1114 if (ptr
->suspended
) {
1115 ptr
->commerror
= IE_HARDWARE
;
1119 if (ptr
->xmit
>= 0) {
1120 /* character already queued */
1121 /* FIXME: which error would Windows return? */
1122 ptr
->commerror
= CE_TXFULL
;
1126 if (ptr
->obuf_head
== ptr
->obuf_tail
) {
1127 /* transmit queue empty, try to transmit directly */
1128 if (write(ptr
->fd
, &chTransmit
, 1) == -1) {
1129 /* didn't work, queue it */
1130 ptr
->xmit
= chTransmit
;
1133 /* data in queue, let this char be transmitted next */
1134 ptr
->xmit
= chTransmit
;
1141 /*****************************************************************************
1142 * UngetCommChar (USER.212)
1144 INT16 WINAPI
UngetCommChar16(INT16 cid
,CHAR chUnget
)
1146 struct DosDeviceStruct
*ptr
;
1148 TRACE(comm
,"cid %d (char %d)\n", cid
, chUnget
);
1149 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1153 if (ptr
->suspended
) {
1154 ptr
->commerror
= IE_HARDWARE
;
1158 if (ptr
->unget
>=0) {
1159 /* character already queued */
1160 /* FIXME: which error would Windows return? */
1161 ptr
->commerror
= CE_RXOVER
;
1165 ptr
->unget
= chUnget
;
1171 /*****************************************************************************
1172 * ReadComm (USER.204)
1174 INT16 WINAPI
ReadComm16(INT16 cid
,LPSTR lpvBuf
,INT16 cbRead
)
1177 struct DosDeviceStruct
*ptr
;
1178 LPSTR orgBuf
= lpvBuf
;
1180 TRACE(comm
, "cid %d, ptr %p, length %d\n", cid
, lpvBuf
, cbRead
);
1181 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1185 if (ptr
->suspended
) {
1186 ptr
->commerror
= IE_HARDWARE
;
1190 /* read unget character */
1191 if (ptr
->unget
>=0) {
1192 *lpvBuf
++ = ptr
->unget
;
1199 /* read from receive buffer */
1200 while (length
< cbRead
) {
1201 status
= ((ptr
->ibuf_head
< ptr
->ibuf_tail
) ?
1202 ptr
->ibuf_size
: ptr
->ibuf_head
) - ptr
->ibuf_tail
;
1204 if ((cbRead
- length
) < status
)
1205 status
= cbRead
- length
;
1207 memcpy(lpvBuf
, ptr
->inbuf
+ ptr
->ibuf_tail
, status
);
1208 ptr
->ibuf_tail
+= status
;
1209 if (ptr
->ibuf_tail
>= ptr
->ibuf_size
)
1215 TRACE(comm
,"%.*s\n", length
, orgBuf
);
1220 /*****************************************************************************
1221 * WriteComm (USER.205)
1223 INT16 WINAPI
WriteComm16(INT16 cid
, LPSTR lpvBuf
, INT16 cbWrite
)
1226 struct DosDeviceStruct
*ptr
;
1228 TRACE(comm
,"cid %d, ptr %p, length %d\n",
1229 cid
, lpvBuf
, cbWrite
);
1230 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1234 if (ptr
->suspended
) {
1235 ptr
->commerror
= IE_HARDWARE
;
1239 TRACE(comm
,"%.*s\n", cbWrite
, lpvBuf
);
1242 while (length
< cbWrite
) {
1243 if ((ptr
->obuf_head
== ptr
->obuf_tail
) && (ptr
->xmit
< 0)) {
1244 /* no data queued, try to write directly */
1245 status
= write(ptr
->fd
, lpvBuf
, cbWrite
- length
);
1252 /* can't write directly, put into transmit buffer */
1253 status
= ((ptr
->obuf_tail
> ptr
->obuf_head
) ?
1254 (ptr
->obuf_tail
-1) : ptr
->obuf_size
) - ptr
->obuf_head
;
1256 if ((cbWrite
- length
) < status
)
1257 status
= cbWrite
- length
;
1258 memcpy(lpvBuf
, ptr
->outbuf
+ ptr
->obuf_head
, status
);
1259 ptr
->obuf_head
+= status
;
1260 if (ptr
->obuf_head
>= ptr
->obuf_size
)
1270 /***********************************************************************
1271 * EnableCommNotification (USER.246)
1273 BOOL16 WINAPI
EnableCommNotification16( INT16 cid
, HWND16 hwnd
,
1274 INT16 cbWriteNotify
, INT16 cbOutQueue
)
1276 struct DosDeviceStruct
*ptr
;
1278 TRACE(comm
, "(%d, %x, %d, %d)\n", cid
, hwnd
, cbWriteNotify
, cbOutQueue
);
1279 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
1280 ptr
->commerror
= IE_BADID
;
1284 ptr
->n_read
= cbWriteNotify
;
1285 ptr
->n_write
= cbOutQueue
;
1290 /**************************************************************************
1291 * BuildCommDCBA (KERNEL32.14)
1293 BOOL WINAPI
BuildCommDCBA(LPCSTR device
,LPDCB lpdcb
)
1295 return BuildCommDCBAndTimeoutsA(device
,lpdcb
,NULL
);
1298 /**************************************************************************
1299 * BuildCommDCBAndTimeoutsA (KERNEL32.15)
1301 BOOL WINAPI
BuildCommDCBAndTimeoutsA(LPCSTR device
, LPDCB lpdcb
,
1302 LPCOMMTIMEOUTS lptimeouts
)
1307 TRACE(comm
,"(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
1309 if (!lstrncmpiA(device
,"COM",3)) {
1312 ERR(comm
,"BUG! COM0 can't exists!.\n");
1315 if (!ValidCOMPort(port
))
1317 if (*(device
+4)!=':')
1319 temp
=(LPSTR
)(device
+5);
1323 memset(lpdcb
, 0, sizeof(DCB
)); /* initialize */
1325 lpdcb
->DCBlength
= sizeof(DCB
);
1326 if (strchr(temp
,',')) { /* old style */
1329 char last
=temp
[strlen(temp
)-1];
1331 ret
=BuildCommDCB16(device
,&dcb16
);
1334 lpdcb
->BaudRate
= dcb16
.BaudRate
;
1335 lpdcb
->ByteSize
= dcb16
.ByteSize
;
1336 lpdcb
->fBinary
= dcb16
.fBinary
;
1337 lpdcb
->Parity
= dcb16
.Parity
;
1338 lpdcb
->fParity
= dcb16
.fParity
;
1339 lpdcb
->fNull
= dcb16
.fNull
;
1340 lpdcb
->StopBits
= dcb16
.StopBits
;
1343 lpdcb
->fOutX
= TRUE
;
1344 lpdcb
->fOutxCtsFlow
= FALSE
;
1345 lpdcb
->fOutxDsrFlow
= FALSE
;
1346 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1347 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1348 } else if (last
=='p') {
1349 lpdcb
->fInX
= FALSE
;
1350 lpdcb
->fOutX
= FALSE
;
1351 lpdcb
->fOutxCtsFlow
= TRUE
;
1352 lpdcb
->fOutxDsrFlow
= TRUE
;
1353 lpdcb
->fDtrControl
= DTR_CONTROL_HANDSHAKE
;
1354 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
1356 lpdcb
->fInX
= FALSE
;
1357 lpdcb
->fOutX
= FALSE
;
1358 lpdcb
->fOutxCtsFlow
= FALSE
;
1359 lpdcb
->fOutxDsrFlow
= FALSE
;
1360 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1361 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1363 lpdcb
->XonChar
= dcb16
.XonChar
;
1364 lpdcb
->XoffChar
= dcb16
.XoffChar
;
1365 lpdcb
->ErrorChar
= dcb16
.PeChar
;
1366 lpdcb
->fErrorChar
= dcb16
.fPeChar
;
1367 lpdcb
->EofChar
= dcb16
.EofChar
;
1368 lpdcb
->EvtChar
= dcb16
.EvtChar
;
1369 lpdcb
->XonLim
= dcb16
.XonLim
;
1370 lpdcb
->XoffLim
= dcb16
.XoffLim
;
1373 ptr
=strtok(temp
," ");
1378 if (!strncmp("baud=",ptr
,5)) {
1379 if (!sscanf(ptr
+5,"%ld",&x
))
1380 WARN(comm
,"Couldn't parse %s\n",ptr
);
1381 lpdcb
->BaudRate
= x
;
1384 if (!strncmp("stop=",ptr
,5)) {
1385 if (!sscanf(ptr
+5,"%ld",&x
))
1386 WARN(comm
,"Couldn't parse %s\n",ptr
);
1387 lpdcb
->StopBits
= x
;
1390 if (!strncmp("data=",ptr
,5)) {
1391 if (!sscanf(ptr
+5,"%ld",&x
))
1392 WARN(comm
,"Couldn't parse %s\n",ptr
);
1393 lpdcb
->ByteSize
= x
;
1396 if (!strncmp("parity=",ptr
,7)) {
1397 lpdcb
->fParity
= TRUE
;
1400 lpdcb
->fParity
= FALSE
;
1401 lpdcb
->Parity
= NOPARITY
;
1404 lpdcb
->Parity
= EVENPARITY
;
1407 lpdcb
->Parity
= ODDPARITY
;
1410 lpdcb
->Parity
= MARKPARITY
;
1416 ERR(comm
,"Unhandled specifier '%s', please report.\n",ptr
);
1417 ptr
=strtok(NULL
," ");
1419 if (lpdcb
->BaudRate
==110)
1420 lpdcb
->StopBits
= 2;
1424 /**************************************************************************
1425 * BuildCommDCBAndTimeoutsW (KERNEL32.16)
1427 BOOL WINAPI
BuildCommDCBAndTimeoutsW( LPCWSTR devid
, LPDCB lpdcb
,
1428 LPCOMMTIMEOUTS lptimeouts
)
1433 TRACE(comm
,"(%p,%p,%p)\n",devid
,lpdcb
,lptimeouts
);
1434 devidA
= HEAP_strdupWtoA( GetProcessHeap(), 0, devid
);
1435 ret
=BuildCommDCBAndTimeoutsA(devidA
,lpdcb
,lptimeouts
);
1436 HeapFree( GetProcessHeap(), 0, devidA
);
1440 /**************************************************************************
1441 * BuildCommDCBW (KERNEL32.17)
1443 BOOL WINAPI
BuildCommDCBW(LPCWSTR devid
,LPDCB lpdcb
)
1445 return BuildCommDCBAndTimeoutsW(devid
,lpdcb
,NULL
);
1448 /*****************************************************************************
1450 * returns a file descriptor for reading from or writing to
1451 * mode is GENERIC_READ or GENERIC_WRITE. Make sure to close
1452 * the handle afterwards!
1454 int COMM_Handle2fd(HANDLE handle
, int mode
) {
1455 struct get_read_fd_request r_req
;
1456 struct get_write_fd_request w_req
;
1459 w_req
.handle
= r_req
.handle
= handle
;
1463 CLIENT_SendRequest( REQ_GET_WRITE_FD
, -1, 1, &w_req
, sizeof(w_req
) );
1466 CLIENT_SendRequest( REQ_GET_READ_FD
, -1, 1, &r_req
, sizeof(r_req
) );
1469 ERR(comm
,"COMM_Handle2fd: Don't know what type of fd is required.\n");
1472 CLIENT_WaitReply( NULL
, &fd
, 0 );
1477 /* FIXME: having these global for win32 for now */
1478 int commerror
=0,eventmask
=0;
1480 /*****************************************************************************
1481 * SetCommBreak (KERNEL32.449)
1483 BOOL WINAPI
SetCommBreak(HANDLE handle
)
1485 FIXME(comm
,"handle %d, stub!\n", handle
);
1489 /*****************************************************************************
1490 * ClearCommBreak (KERNEL32.20)
1492 BOOL WINAPI
ClearCommBreak(HANDLE handle
)
1494 FIXME(comm
,"handle %d, stub!\n", handle
);
1498 /*****************************************************************************
1499 * EscapeCommFunction (KERNEL32.214)
1501 BOOL WINAPI
EscapeCommFunction(HANDLE handle
,UINT nFunction
)
1504 struct termios port
;
1506 TRACE(comm
,"handle %d, function=%d\n", handle
, nFunction
);
1507 fd
= COMM_Handle2fd(handle
, GENERIC_WRITE
);
1511 if (tcgetattr(fd
,&port
) == -1) {
1512 commerror
=WinError();
1517 switch (nFunction
) {
1523 port
.c_cflag
&= TIOCM_DTR
;
1529 port
.c_cflag
&= TIOCM_RTS
;
1535 port
.c_cflag
|= CRTSCTS
;
1539 port
.c_cflag
|= CRTSCTS
;
1544 port
.c_iflag
|= IXOFF
;
1548 port
.c_iflag
|= IXON
;
1551 FIXME(comm
,"setbreak, stub\n");
1552 /* ptr->suspended = 1; */
1555 FIXME(comm
,"clrbreak, stub\n");
1556 /* ptr->suspended = 0; */
1559 WARN(comm
,"(handle=%d,nFunction=%d): Unknown function\n",
1564 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
1565 commerror
= WinError();
1575 /********************************************************************
1576 * PurgeComm (KERNEL32.557)
1578 BOOL WINAPI
PurgeComm( HANDLE handle
, DWORD flags
)
1582 TRACE(comm
,"handle %d, flags %lx\n", handle
, flags
);
1584 fd
= COMM_Handle2fd(handle
, GENERIC_WRITE
);
1589 ** not exactly sure how these are different
1590 ** Perhaps if we had our own internal queues, one flushes them
1591 ** and the other flushes the kernel's buffers.
1593 if(flags
&PURGE_TXABORT
)
1595 tcflush(fd
,TCOFLUSH
);
1597 if(flags
&PURGE_RXABORT
)
1599 tcflush(fd
,TCIFLUSH
);
1601 if(flags
&PURGE_TXCLEAR
)
1603 tcflush(fd
,TCOFLUSH
);
1605 if(flags
&PURGE_RXCLEAR
)
1607 tcflush(fd
,TCIFLUSH
);
1614 /*****************************************************************************
1615 * ClearCommError (KERNEL32.21)
1617 BOOL WINAPI
ClearCommError(INT handle
,LPDWORD errors
,LPCOMSTAT lpStat
)
1621 fd
=COMM_Handle2fd(handle
,GENERIC_READ
);
1631 if(ioctl(fd
, TIOCOUTQ
, &lpStat
->cbOutQue
))
1632 WARN(comm
, "ioctl returned error\n");
1634 if(ioctl(fd
, TIOCINQ
, &lpStat
->cbInQue
))
1635 WARN(comm
, "ioctl returned error\n");
1640 TRACE(comm
,"handle %d cbInQue = %ld cbOutQue = %ld\n",
1649 ** After an asynchronous write opperation, the
1650 ** app will call ClearCommError to see if the
1651 ** results are ready yet. It waits for ERROR_IO_PENDING
1653 commerror
= ERROR_IO_PENDING
;
1658 /*****************************************************************************
1659 * SetupComm (KERNEL32.676)
1661 BOOL WINAPI
SetupComm( HANDLE handle
, DWORD insize
, DWORD outsize
)
1665 FIXME(comm
, "insize %ld outsize %ld unimplemented stub\n", insize
, outsize
);
1666 fd
=COMM_Handle2fd(handle
,GENERIC_WRITE
);
1675 /*****************************************************************************
1676 * GetCommMask (KERNEL32.156)
1678 BOOL WINAPI
GetCommMask(HANDLE handle
,LPDWORD evtmask
)
1682 TRACE(comm
, "handle %d, mask %p\n", handle
, evtmask
);
1683 if(0>(fd
=COMM_Handle2fd(handle
,GENERIC_READ
)))
1688 *evtmask
= eventmask
;
1692 /*****************************************************************************
1693 * SetCommMask (KERNEL32.451)
1695 BOOL WINAPI
SetCommMask(INT handle
,DWORD evtmask
)
1699 TRACE(comm
, "handle %d, mask %lx\n", handle
, evtmask
);
1700 if(0>(fd
=COMM_Handle2fd(handle
,GENERIC_WRITE
))) {
1704 eventmask
= evtmask
;
1708 /*****************************************************************************
1709 * SetCommState (KERNEL32.452)
1711 BOOL WINAPI
SetCommState(INT handle
,LPDCB lpdcb
)
1713 struct termios port
;
1715 struct get_write_fd_request req
;
1717 TRACE(comm
,"handle %d, ptr %p\n", handle
, lpdcb
);
1719 req
.handle
= handle
;
1720 CLIENT_SendRequest( REQ_GET_WRITE_FD
, -1, 1, &req
, sizeof(req
) );
1721 CLIENT_WaitReply( NULL
, &fd
, 0 );
1726 if (tcgetattr(fd
,&port
) == -1) {
1727 commerror
= WinError();
1731 port
.c_cc
[VMIN
] = 0;
1732 port
.c_cc
[VTIME
] = 1;
1735 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
1737 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
1739 port
.c_iflag
|= (IGNBRK
);
1741 port
.c_oflag
&= ~(OPOST
);
1743 port
.c_cflag
&= ~(HUPCL
);
1744 port
.c_cflag
|= CLOCAL
| CREAD
;
1746 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
1747 port
.c_lflag
|= NOFLSH
;
1750 ** MJM - removed default baudrate settings
1751 ** TRACE(comm,"baudrate %ld\n",lpdcb->BaudRate);
1754 port
.c_cflag
&= ~CBAUD
;
1755 switch (lpdcb
->BaudRate
) {
1758 port
.c_cflag
|= B110
;
1762 port
.c_cflag
|= B300
;
1766 port
.c_cflag
|= B600
;
1770 port
.c_cflag
|= B1200
;
1774 port
.c_cflag
|= B2400
;
1778 port
.c_cflag
|= B4800
;
1782 port
.c_cflag
|= B9600
;
1786 port
.c_cflag
|= B19200
;
1790 port
.c_cflag
|= B38400
;
1793 commerror
= IE_BAUDRATE
;
1796 #elif !defined(__EMX__)
1797 switch (lpdcb
->BaudRate
) {
1800 port
.c_ospeed
= B110
;
1804 port
.c_ospeed
= B300
;
1808 port
.c_ospeed
= B600
;
1812 port
.c_ospeed
= B1200
;
1816 port
.c_ospeed
= B2400
;
1820 port
.c_ospeed
= B4800
;
1824 port
.c_ospeed
= B9600
;
1828 port
.c_ospeed
= B19200
;
1832 port
.c_ospeed
= B38400
;
1835 commerror
= IE_BAUDRATE
;
1838 port
.c_ispeed
= port
.c_ospeed
;
1840 TRACE(comm
,"bytesize %d\n",lpdcb
->ByteSize
);
1841 port
.c_cflag
&= ~CSIZE
;
1842 switch (lpdcb
->ByteSize
) {
1844 port
.c_cflag
|= CS5
;
1847 port
.c_cflag
|= CS6
;
1850 port
.c_cflag
|= CS7
;
1853 port
.c_cflag
|= CS8
;
1856 commerror
= IE_BYTESIZE
;
1860 TRACE(comm
,"fParity %d Parity %d\n",lpdcb
->fParity
, lpdcb
->Parity
);
1861 port
.c_cflag
&= ~(PARENB
| PARODD
);
1863 port
.c_iflag
|= INPCK
;
1865 port
.c_iflag
&= ~INPCK
;
1866 switch (lpdcb
->Parity
) {
1870 port
.c_cflag
|= (PARENB
| PARODD
);
1873 port
.c_cflag
|= PARENB
;
1876 commerror
= IE_BYTESIZE
;
1881 TRACE(comm
,"stopbits %d\n",lpdcb
->StopBits
);
1882 switch (lpdcb
->StopBits
) {
1884 port
.c_cflag
&= ~CSTOPB
;
1887 port
.c_cflag
|= CSTOPB
;
1890 commerror
= IE_BYTESIZE
;
1894 if ( lpdcb
->fOutxCtsFlow
||
1895 lpdcb
->fDtrControl
== DTR_CONTROL_ENABLE
||
1896 lpdcb
->fRtsControl
== RTS_CONTROL_ENABLE
1898 port
.c_cflag
|= CRTSCTS
;
1899 if (lpdcb
->fDtrControl
== DTR_CONTROL_DISABLE
)
1900 port
.c_cflag
&= ~CRTSCTS
;
1904 port
.c_iflag
|= IXON
;
1906 port
.c_iflag
&= ~IXON
;
1908 port
.c_iflag
|= IXOFF
;
1910 port
.c_iflag
&= ~IXOFF
;
1912 if (tcsetattr(fd
,TCSADRAIN
,&port
)==-1) {
1913 commerror
= WinError();
1922 /*****************************************************************************
1923 * GetCommState (KERNEL32.159)
1925 BOOL WINAPI
GetCommState(INT handle
, LPDCB lpdcb
)
1927 struct termios port
;
1929 struct get_read_fd_request req
;
1931 TRACE(comm
,"handle %d, ptr %p\n", handle
, lpdcb
);
1932 req
.handle
= handle
;
1933 CLIENT_SendRequest( REQ_GET_READ_FD
, -1, 1, &req
, sizeof(req
) );
1934 CLIENT_WaitReply( NULL
, &fd
, 0 );
1939 if (tcgetattr(fd
, &port
) == -1) {
1940 TRACE(comm
,"tcgetattr(%d, ...) returned -1",fd
);
1941 commerror
= WinError();
1946 switch (port
.c_cflag
& CBAUD
) {
1948 switch (port
.c_ospeed
) {
1951 lpdcb
->BaudRate
= 110;
1954 lpdcb
->BaudRate
= 300;
1957 lpdcb
->BaudRate
= 600;
1960 lpdcb
->BaudRate
= 1200;
1963 lpdcb
->BaudRate
= 2400;
1966 lpdcb
->BaudRate
= 4800;
1969 lpdcb
->BaudRate
= 9600;
1972 lpdcb
->BaudRate
= 19200;
1975 lpdcb
->BaudRate
= 38400;
1979 switch (port
.c_cflag
& CSIZE
) {
1981 lpdcb
->ByteSize
= 5;
1984 lpdcb
->ByteSize
= 6;
1987 lpdcb
->ByteSize
= 7;
1990 lpdcb
->ByteSize
= 8;
1994 if(port
.c_iflag
& INPCK
)
1995 lpdcb
->fParity
= TRUE
;
1997 lpdcb
->fParity
= FALSE
;
1998 switch (port
.c_cflag
& (PARENB
| PARODD
)) {
2000 lpdcb
->Parity
= NOPARITY
;
2003 lpdcb
->Parity
= EVENPARITY
;
2005 case (PARENB
| PARODD
):
2006 lpdcb
->Parity
= ODDPARITY
;
2010 if (port
.c_cflag
& CSTOPB
)
2011 lpdcb
->StopBits
= TWOSTOPBITS
;
2013 lpdcb
->StopBits
= ONESTOPBIT
;
2020 if (port
.c_cflag
& CRTSCTS
) {
2021 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
2022 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
2023 lpdcb
->fOutxCtsFlow
= 1;
2024 lpdcb
->fOutxDsrFlow
= 1;
2028 lpdcb
->fDtrControl
= DTR_CONTROL_DISABLE
;
2029 lpdcb
->fRtsControl
= RTS_CONTROL_DISABLE
;
2031 if (port
.c_iflag
& IXON
)
2036 if (port
.c_iflag
& IXOFF
)
2045 lpdcb
->XoffLim
= 10;
2054 /*****************************************************************************
2055 * TransmitCommChar (KERNEL32.535)
2057 BOOL WINAPI
TransmitCommChar(INT cid
,CHAR chTransmit
)
2059 struct DosDeviceStruct
*ptr
;
2061 FIXME(comm
,"(%d,'%c'), use win32 handle!\n",cid
,chTransmit
);
2062 if ((ptr
= GetDeviceStruct(cid
)) == NULL
) {
2066 if (ptr
->suspended
) {
2067 ptr
->commerror
= IE_HARDWARE
;
2070 if (write(ptr
->fd
, (void *) &chTransmit
, 1) == -1) {
2071 ptr
->commerror
= WinError();
2079 /*****************************************************************************
2080 * GetCommTimeouts (KERNEL32.160)
2082 BOOL WINAPI
GetCommTimeouts(INT cid
,LPCOMMTIMEOUTS lptimeouts
)
2084 FIXME(comm
,"(%x,%p):stub.\n",cid
,lptimeouts
);
2088 /*****************************************************************************
2089 * SetCommTimeouts (KERNEL32.453)
2091 BOOL WINAPI
SetCommTimeouts(INT cid
,LPCOMMTIMEOUTS lptimeouts
) {
2092 FIXME(comm
,"(%x,%p):stub.\n",cid
,lptimeouts
);
2096 /***********************************************************************
2097 * GetCommModemStatus (KERNEL32.285)
2099 BOOL WINAPI
GetCommModemStatus(HANDLE hFile
,LPDWORD lpModemStat
)
2101 FIXME(comm
, "(%d %p)\n",hFile
,lpModemStat
);
2104 /***********************************************************************
2105 * WaitCommEvent (KERNEL32.719)
2107 BOOL WINAPI
WaitCommEvent(HANDLE hFile
,LPDWORD eventmask
,LPOVERLAPPED overlapped
)
2109 FIXME(comm
, "(%d %p %p )\n",hFile
, eventmask
,overlapped
);
2113 /***********************************************************************
2114 * GetCommProperties (KERNEL32.???)
2116 BOOL WINAPI
GetCommProperties(HANDLE hFile
, LPDCB
*dcb
)
2118 FIXME(comm
, "(%d %p )\n",hFile
,dcb
);
2122 /***********************************************************************
2123 * SetCommProperties (KERNEL32.???)
2125 BOOL WINAPI
SetCommProperties(HANDLE hFile
, LPDCB dcb
)
2127 FIXME(comm
, "(%d %p )\n",hFile
,dcb
);