2 * DEC 93 Erik Bos <erik@xs4all.nl>
4 * Copyright 1996 Marcus Meissner
5 * FIXME: use HFILEs instead of unixfds
6 * the win32 functions here get HFILEs already.
8 * May 26, 1997. Fixes and comments by Rick Richardson <rick@dgii.com> [RER]
9 * - ptr->fd wasn't getting cleared on close.
10 * - GetCommEventMask() and GetCommError() didn't do much of anything.
11 * IMHO, they are still wrong, but they at least implement the RXCHAR
12 * event and return I/O queue sizes, which makes the app I'm interested
13 * in (analog devices EZKIT DSP development system) work.
15 * August 12, 1997. Take a bash at SetCommEventMask - Lawson Whitney
16 * <lawson_whitney@juno.com>
29 #ifdef HAVE_SYS_FILIO_H
30 # include <sys/filio.h>
32 #include <sys/ioctl.h>
42 #define TIOCINQ FIONREAD
44 #define msr 35 /* offset in unknown structure commMask */
46 * [RER] These are globals are wrong. They should be in DosDeviceStruct
47 * on a per port basis.
49 int commerror
= 0, eventmask
= 0;
51 struct DosDeviceStruct COM
[MAX_PORTS
];
52 struct DosDeviceStruct LPT
[MAX_PORTS
];
53 LPCVOID
*unknown
[MAX_PORTS
];
58 char option
[10], temp
[256], *btemp
;
61 for (x
=0; x
!=MAX_PORTS
; x
++) {
62 strcpy(option
,"COMx");
66 PROFILE_GetWineIniString( "serialports", option
, "*",
68 if (!strcmp(temp
, "*") || *temp
== '\0')
69 COM
[x
].devicename
= NULL
;
71 btemp
= strchr(temp
,',');
74 COM
[x
].baudrate
= atoi(btemp
);
79 if (!S_ISCHR(st
.st_mode
))
80 fprintf(stderr
,"comm: can't use `%s' as %s !\n", temp
, option
);
82 if ((COM
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
83 fprintf(stderr
,"comm: can't malloc for device info!\n");
86 strcpy(COM
[x
].devicename
, temp
);
88 TRACE(comm
, "%s = %s\n", option
, COM
[x
].devicename
);
91 strcpy(option
, "LPTx");
95 PROFILE_GetWineIniString( "parallelports", option
, "*",
97 if (!strcmp(temp
, "*") || *temp
== '\0')
98 LPT
[x
].devicename
= NULL
;
101 if (!S_ISCHR(st
.st_mode
))
102 fprintf(stderr
,"comm: can't use `%s' as %s !\n", temp
, option
);
104 if ((LPT
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
105 fprintf(stderr
,"comm: can't malloc for device info!\n");
108 strcpy(LPT
[x
].devicename
, temp
);
110 TRACE(comm
, "%s = %s\n", option
, LPT
[x
].devicename
);
117 struct DosDeviceStruct
*GetDeviceStruct(int fd
)
121 for (x
=0; x
!=MAX_PORTS
; x
++) {
131 int GetCommPort(int fd
)
135 for (x
=0; x
<MAX_PORTS
; x
++) {
143 int ValidCOMPort(int x
)
145 return(x
< MAX_PORTS
? (int) COM
[x
].devicename
: 0);
148 int ValidLPTPort(int x
)
150 return(x
< MAX_PORTS
? (int) LPT
[x
].devicename
: 0);
155 TRACE(comm
, "errno = %d\n", errno
);
162 /**************************************************************************
163 * BuildCommDCB (USER.213)
165 BOOL16 WINAPI
BuildCommDCB16(LPCSTR device
, LPDCB16 lpdcb
)
167 /* "COM1:9600,n,8,1" */
170 char *ptr
, temp
[256];
172 TRACE(comm
, "(%s), ptr %p\n", device
, lpdcb
);
175 if (!lstrncmpi32A(device
,"COM",3)) {
176 port
= device
[3] - '0';
180 fprintf(stderr
, "comm: BUG ! COM0 can't exists!.\n");
181 commerror
= IE_BADID
;
184 if (!ValidCOMPort(port
)) {
185 commerror
= IE_BADID
;
189 memset(lpdcb
, 0, sizeof(DCB16
)); /* initialize */
192 OpenComm(device
, 0, 0);
194 lpdcb
->Id
= COM
[port
].fd
;
199 if (*(device
+4) != ':')
202 strcpy(temp
,device
+5);
203 ptr
= strtok(temp
, ", ");
205 if (COM
[port
].baudrate
> 0)
206 lpdcb
->BaudRate
= COM
[port
].baudrate
;
208 lpdcb
->BaudRate
= atoi(ptr
);
209 TRACE(comm
,"baudrate (%d)\n", lpdcb
->BaudRate
);
211 ptr
= strtok(NULL
, ", ");
213 *ptr
= toupper(*ptr
);
215 TRACE(comm
,"parity (%c)\n", *ptr
);
219 lpdcb
->Parity
= NOPARITY
;
223 lpdcb
->Parity
= EVENPARITY
;
226 lpdcb
->Parity
= MARKPARITY
;
229 lpdcb
->Parity
= ODDPARITY
;
232 fprintf(stderr
,"comm: unknown parity `%c'!\n", *ptr
);
236 ptr
= strtok(NULL
, ", ");
237 TRACE(comm
, "charsize (%c)\n", *ptr
);
238 lpdcb
->ByteSize
= *ptr
- '0';
240 ptr
= strtok(NULL
, ", ");
241 TRACE(comm
, "stopbits (%c)\n", *ptr
);
244 lpdcb
->StopBits
= ONESTOPBIT
;
247 lpdcb
->StopBits
= TWOSTOPBITS
;
250 fprintf(stderr
,"comm: unknown # of stopbits `%c'!\n", *ptr
);
258 /**************************************************************************
259 * BuildCommDCBA (KERNEL32.14)
261 BOOL32 WINAPI
BuildCommDCB32A(LPCSTR device
,LPDCB32 lpdcb
)
263 return BuildCommDCBAndTimeouts32A(device
,lpdcb
,NULL
);
266 /**************************************************************************
267 * BuildCommDCBAndTimeoutsA (KERNEL32.15)
269 BOOL32 WINAPI
BuildCommDCBAndTimeouts32A(LPCSTR device
, LPDCB32 lpdcb
,
270 LPCOMMTIMEOUTS lptimeouts
)
275 TRACE(comm
,"(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
278 if (!lstrncmpi32A(device
,"COM",3)) {
281 fprintf(stderr
,"comm:BUG! COM0 can't exists!.\n");
284 if (!ValidCOMPort(port
))
286 if (*(device
+4)!=':')
288 temp
=(LPSTR
)(device
+5);
292 memset(lpdcb
, 0, sizeof(DCB32
)); /* initialize */
294 lpdcb
->DCBlength
= sizeof(DCB32
);
295 if (strchr(temp
,',')) { /* old style */
298 char last
=temp
[strlen(temp
)-1];
300 ret
=BuildCommDCB16(device
,&dcb16
);
303 lpdcb
->BaudRate
= dcb16
.BaudRate
;
304 lpdcb
->ByteSize
= dcb16
.ByteSize
;
305 lpdcb
->fBinary
= dcb16
.fBinary
;
306 lpdcb
->Parity
= dcb16
.Parity
;
307 lpdcb
->fParity
= dcb16
.fParity
;
308 lpdcb
->fNull
= dcb16
.fNull
;
309 lpdcb
->StopBits
= dcb16
.StopBits
;
313 lpdcb
->fOutxCtsFlow
= FALSE
;
314 lpdcb
->fOutxDsrFlow
= FALSE
;
315 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
316 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
317 } else if (last
=='p') {
319 lpdcb
->fOutX
= FALSE
;
320 lpdcb
->fOutxCtsFlow
= TRUE
;
321 lpdcb
->fOutxDsrFlow
= TRUE
;
322 lpdcb
->fDtrControl
= DTR_CONTROL_HANDSHAKE
;
323 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
326 lpdcb
->fOutX
= FALSE
;
327 lpdcb
->fOutxCtsFlow
= FALSE
;
328 lpdcb
->fOutxDsrFlow
= FALSE
;
329 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
330 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
332 lpdcb
->XonChar
= dcb16
.XonChar
;
333 lpdcb
->XoffChar
= dcb16
.XoffChar
;
334 lpdcb
->ErrorChar
= dcb16
.PeChar
;
335 lpdcb
->fErrorChar
= dcb16
.fPeChar
;
336 lpdcb
->EofChar
= dcb16
.EofChar
;
337 lpdcb
->EvtChar
= dcb16
.EvtChar
;
338 lpdcb
->XonLim
= dcb16
.XonLim
;
339 lpdcb
->XoffLim
= dcb16
.XoffLim
;
342 ptr
=strtok(temp
," ");
347 if (!strncmp("baud=",ptr
,5)) {
348 if (!sscanf(ptr
+5,"%ld",&x
))
349 fprintf(stderr
,"BuildCommDCB32A:Couldn't parse %s\n",ptr
);
353 if (!strncmp("stop=",ptr
,5)) {
354 if (!sscanf(ptr
+5,"%ld",&x
))
355 fprintf(stderr
,"BuildCommDCB32A:Couldn't parse %s\n",ptr
);
359 if (!strncmp("data=",ptr
,5)) {
360 if (!sscanf(ptr
+5,"%ld",&x
))
361 fprintf(stderr
,"BuildCommDCB32A:Couldn't parse %s\n",ptr
);
365 if (!strncmp("parity=",ptr
,7)) {
366 lpdcb
->fParity
= TRUE
;
369 lpdcb
->fParity
= FALSE
;
370 lpdcb
->Parity
= NOPARITY
;
373 lpdcb
->Parity
= EVENPARITY
;
376 lpdcb
->Parity
= ODDPARITY
;
379 lpdcb
->Parity
= MARKPARITY
;
385 fprintf(stderr
,"BuildCommDCB32A: Unhandled specifier '%s', please report.\n",ptr
);
386 ptr
=strtok(NULL
," ");
388 if (lpdcb
->BaudRate
==110)
393 /**************************************************************************
394 * BuildCommDCBAndTimeoutsW (KERNEL32.16)
396 BOOL32 WINAPI
BuildCommDCBAndTimeouts32W( LPCWSTR devid
, LPDCB32 lpdcb
,
397 LPCOMMTIMEOUTS lptimeouts
)
402 TRACE(comm
,"(%p,%p,%p)\n",devid
,lpdcb
,lptimeouts
);
403 devidA
= HEAP_strdupWtoA( GetProcessHeap(), 0, devid
);
404 ret
=BuildCommDCBAndTimeouts32A(devidA
,lpdcb
,lptimeouts
);
405 HeapFree( GetProcessHeap(), 0, devidA
);
409 /**************************************************************************
410 * BuildCommDCBW (KERNEL32.17)
412 BOOL32 WINAPI
BuildCommDCB32W(LPCWSTR devid
,LPDCB32 lpdcb
)
414 return BuildCommDCBAndTimeouts32W(devid
,lpdcb
,NULL
);
417 /*****************************************************************************
418 * OpenComm (USER.200)
420 INT16 WINAPI
OpenComm(LPCSTR device
,UINT16 cbInQueue
,UINT16 cbOutQueue
)
424 TRACE(comm
, "%s, %d, %d\n", device
, cbInQueue
, cbOutQueue
);
427 if (!lstrncmpi32A(device
,"COM",3)) {
428 port
= device
[3] - '0';
431 fprintf(stderr
, "comm: BUG ! COM0 doesn't exist !\n");
432 commerror
= IE_BADID
;
435 TRACE(comm
, "%s = %s\n", device
, COM
[port
].devicename
);
437 if (!ValidCOMPort(port
)) {
438 commerror
= IE_BADID
;
445 fd
= open(COM
[port
].devicename
, O_RDWR
| O_NONBLOCK
);
447 commerror
= WinError();
450 unknown
[port
] = SEGPTR_ALLOC(40);
451 bzero(unknown
[port
],40);
457 if (!lstrncmpi32A(device
,"LPT",3)) {
458 port
= device
[3] - '0';
460 if (!ValidLPTPort(port
)) {
461 commerror
= IE_BADID
;
469 fd
= open(LPT
[port
].devicename
, O_RDWR
| O_NONBLOCK
, 0);
471 commerror
= WinError();
481 /*****************************************************************************
482 * CloseComm (USER.207)
484 INT16 WINAPI
CloseComm(INT16 fd
)
487 TRACE(comm
,"fd %d\n", fd
);
488 if ((port
= GetCommPort(fd
)) !=-1) { /* [LW] */
489 SEGPTR_FREE(unknown
[port
]);
490 COM
[port
].fd
= 0; /* my adaptation of RER's fix */
492 commerror
= IE_BADID
;
496 if (close(fd
) == -1) {
497 commerror
= WinError();
505 /*****************************************************************************
506 * SetCommBreak (USER.210)
508 INT16 WINAPI
SetCommBreak16(INT16 fd
)
510 struct DosDeviceStruct
*ptr
;
512 TRACE(comm
,"fd=%d\n", fd
);
513 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
514 commerror
= IE_BADID
;
523 /*****************************************************************************
524 * SetCommBreak (KERNEL32.449)
526 BOOL32 WINAPI
SetCommBreak32(INT32 fd
)
529 struct DosDeviceStruct
*ptr
;
531 TRACE(comm
,"fd=%d\n", fd
);
532 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
533 commerror
= IE_BADID
;
542 /*****************************************************************************
543 * ClearCommBreak (USER.211)
545 INT16 WINAPI
ClearCommBreak16(INT16 fd
)
547 struct DosDeviceStruct
*ptr
;
549 TRACE(comm
,"fd=%d\n", fd
);
550 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
551 commerror
= IE_BADID
;
560 /*****************************************************************************
561 * ClearCommBreak (KERNEL32.20)
563 BOOL32 WINAPI
ClearCommBreak32(INT32 fd
)
565 struct DosDeviceStruct
*ptr
;
567 TRACE(comm
,"fd=%d\n", fd
);
568 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
569 commerror
= IE_BADID
;
578 /*****************************************************************************
579 * EscapeCommFunction (USER.214)
581 LONG WINAPI
EscapeCommFunction16(UINT16 fd
,UINT16 nFunction
)
586 TRACE(comm
,"fd=%d, function=%d\n", fd
, nFunction
);
587 if (tcgetattr(fd
,&port
) == -1) {
588 commerror
=WinError();
597 for (max
= MAX_PORTS
;!COM
[max
].devicename
;max
--)
603 for (max
= MAX_PORTS
;!LPT
[max
].devicename
;max
--)
610 port
.c_cflag
&= TIOCM_DTR
;
616 port
.c_cflag
&= TIOCM_RTS
;
622 port
.c_cflag
|= CRTSCTS
;
626 port
.c_cflag
|= CRTSCTS
;
631 port
.c_iflag
|= IXOFF
;
635 port
.c_iflag
|= IXON
;
640 "EscapeCommFunction fd: %d, unknown function: %d\n",
645 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
646 commerror
= WinError();
654 /*****************************************************************************
655 * EscapeCommFunction (KERNEL32.214)
657 BOOL32 WINAPI
EscapeCommFunction32(INT32 fd
,UINT32 nFunction
)
660 struct DosDeviceStruct
*ptr
;
662 TRACE(comm
,"fd=%d, function=%d\n", fd
, nFunction
);
663 if (tcgetattr(fd
,&port
) == -1) {
664 commerror
=WinError();
667 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
668 commerror
= IE_BADID
;
678 port
.c_cflag
&= TIOCM_DTR
;
684 port
.c_cflag
&= TIOCM_RTS
;
690 port
.c_cflag
|= CRTSCTS
;
694 port
.c_cflag
|= CRTSCTS
;
699 port
.c_iflag
|= IXOFF
;
703 port
.c_iflag
|= IXON
;
713 "EscapeCommFunction32 fd: %d, unknown function: %d\n",
718 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
719 commerror
= WinError();
727 /*****************************************************************************
728 * FlushComm (USER.215)
730 INT16 WINAPI
FlushComm(INT16 fd
,INT16 fnQueue
)
734 TRACE(comm
,"fd=%d, queue=%d\n", fd
, fnQueue
);
736 case 0: queue
= TCOFLUSH
;
738 case 1: queue
= TCIFLUSH
;
740 default:fprintf(stderr
,
741 "FlushComm fd: %d, UNKNOWN queue: %d\n",
745 if (tcflush(fd
, queue
)) {
746 commerror
= WinError();
754 /********************************************************************
755 * PurgeComm (KERNEL32.557)
757 BOOL32 WINAPI
PurgeComm( HANDLE32 hFile
, DWORD flags
)
759 FIXME(comm
, "(%08x %08lx) unimplemented stub\n",
764 /********************************************************************
765 * GetCommError (USER.203)
767 INT16 WINAPI
GetCommError(INT16 fd
,LPCOMSTAT lpStat
)
776 rc
= ioctl(fd
, TIOCOUTQ
, &cnt
);
777 if (rc
) fprintf(stderr
, "Error !\n");
778 lpStat
->cbOutQue
= cnt
;
780 rc
= ioctl(fd
, TIOCINQ
, &cnt
);
781 if (rc
) fprintf(stderr
, "Error !\n");
782 lpStat
->cbInQue
= cnt
;
784 TRACE(comm
, "fd %d, error %d, lpStat %d %d %d\n",
785 fd
, commerror
, lpStat
->status
, lpStat
->cbInQue
,
789 TRACE(comm
, "fd %d, error %d, lpStat NULL\n",
793 * [RER] I have no idea what the following is trying to accomplish.
794 * [RER] It is certainly not what the reference manual suggests.
796 temperror
= commerror
;
801 /*****************************************************************************
802 * ClearCommError (KERNEL32.21)
804 BOOL32 WINAPI
ClearCommError(INT32 fd
,LPDWORD errors
,LPCOMSTAT lpStat
)
808 TRACE(comm
, "fd %d (current error %d)\n",
810 temperror
= commerror
;
815 /*****************************************************************************
816 * SetCommEventMask (USER.208)
818 SEGPTR WINAPI
SetCommEventMask(INT16 fd
,UINT16 fuEvtMask
)
824 TRACE(comm
,"fd %d,mask %d\n",fd
,fuEvtMask
);
825 eventmask
|= fuEvtMask
;
826 if ((act
= GetCommPort(fd
)) == -1) {
827 WARN(comm
," fd %d not comm port\n",act
);
831 repid
= ioctl(fd
,TIOCMGET
,&mstat
);
832 TRACE(comm
, " ioctl %d, msr %x at %p %p\n",repid
,mstat
,stol
,unknown
[act
]);
833 if ((mstat
&TIOCM_CAR
)) {*stol
|= 0x80;}
835 TRACE(comm
," modem dcd construct %x\n",*stol
);
836 return SEGPTR_GET(unknown
[act
]);
839 /*****************************************************************************
840 * GetCommEventMask (USER.209)
842 UINT16 WINAPI
GetCommEventMask(INT16 fd
,UINT16 fnEvtClear
)
846 TRACE(comm
, "fd %d, mask %d\n", fd
, fnEvtClear
);
849 * Determine if any characters are available
851 if (fnEvtClear
& EV_RXCHAR
)
856 rc
= ioctl(fd
, TIOCINQ
, &cnt
);
857 if (cnt
) events
|= EV_RXCHAR
;
859 TRACE(comm
, "rxchar %ld\n", cnt
);
863 * There are other events that need to be checked for
867 TRACE(comm
, "return events %d\n", events
);
871 * [RER] The following was gibberish
874 tempmask
= eventmask
;
875 eventmask
&= ~fnEvtClear
;
880 /*****************************************************************************
881 * SetupComm (KERNEL32.676)
883 BOOL32 WINAPI
SetupComm( HANDLE32 hFile
, DWORD insize
, DWORD outsize
)
885 FIXME(comm
, "insize %ld outsize %ld unimplemented stub\n", insize
, outsize
);
889 /*****************************************************************************
890 * GetCommMask (KERNEL32.156)
892 BOOL32 WINAPI
GetCommMask(INT32 fd
,LPDWORD evtmask
)
894 TRACE(comm
, "fd %d, mask %p\n", fd
, evtmask
);
895 *evtmask
= eventmask
;
899 /*****************************************************************************
900 * SetCommMask (KERNEL32.451)
902 BOOL32 WINAPI
SetCommMask(INT32 fd
,DWORD evtmask
)
904 TRACE(comm
, "fd %d, mask %lx\n", fd
, evtmask
);
909 /*****************************************************************************
910 * SetCommState16 (USER.201)
912 INT16 WINAPI
SetCommState16(LPDCB16 lpdcb
)
915 struct DosDeviceStruct
*ptr
;
917 TRACE(comm
, "fd %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
918 if (tcgetattr(lpdcb
->Id
, &port
) == -1) {
919 commerror
= WinError();
924 port
.c_cc
[VTIME
] = 1;
927 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
929 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
931 port
.c_iflag
|= (IGNBRK
);
933 port
.c_oflag
&= ~(OPOST
);
935 port
.c_cflag
&= ~(HUPCL
);
936 port
.c_cflag
|= CLOCAL
| CREAD
;
938 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
939 port
.c_lflag
|= NOFLSH
;
941 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
942 commerror
= IE_BADID
;
945 if (ptr
->baudrate
> 0)
946 lpdcb
->BaudRate
= ptr
->baudrate
;
947 TRACE(comm
,"baudrate %d\n",lpdcb
->BaudRate
);
949 port
.c_cflag
&= ~CBAUD
;
950 switch (lpdcb
->BaudRate
) {
953 port
.c_cflag
|= B110
;
957 port
.c_cflag
|= B300
;
961 port
.c_cflag
|= B600
;
965 port
.c_cflag
|= B1200
;
969 port
.c_cflag
|= B2400
;
973 port
.c_cflag
|= B4800
;
977 port
.c_cflag
|= B9600
;
981 port
.c_cflag
|= B19200
;
985 port
.c_cflag
|= B38400
;
988 port
.c_cflag
|= B57600
;
991 port
.c_cflag
|= B115200
;
994 commerror
= IE_BAUDRATE
;
997 #elif !defined(__EMX__)
998 switch (lpdcb
->BaudRate
) {
1001 port
.c_ospeed
= B110
;
1005 port
.c_ospeed
= B300
;
1009 port
.c_ospeed
= B600
;
1013 port
.c_ospeed
= B1200
;
1017 port
.c_ospeed
= B2400
;
1021 port
.c_ospeed
= B4800
;
1025 port
.c_ospeed
= B9600
;
1029 port
.c_ospeed
= B19200
;
1033 port
.c_ospeed
= B38400
;
1036 commerror
= IE_BAUDRATE
;
1039 port
.c_ispeed
= port
.c_ospeed
;
1041 TRACE(comm
,"bytesize %d\n",lpdcb
->ByteSize
);
1042 port
.c_cflag
&= ~CSIZE
;
1043 switch (lpdcb
->ByteSize
) {
1045 port
.c_cflag
|= CS5
;
1048 port
.c_cflag
|= CS6
;
1051 port
.c_cflag
|= CS7
;
1054 port
.c_cflag
|= CS8
;
1057 commerror
= IE_BYTESIZE
;
1061 TRACE(comm
,"parity %d\n",lpdcb
->Parity
);
1062 port
.c_cflag
&= ~(PARENB
| PARODD
);
1064 switch (lpdcb
->Parity
) {
1066 port
.c_iflag
&= ~INPCK
;
1069 port
.c_cflag
|= (PARENB
| PARODD
);
1070 port
.c_iflag
|= INPCK
;
1073 port
.c_cflag
|= PARENB
;
1074 port
.c_iflag
|= INPCK
;
1077 commerror
= IE_BYTESIZE
;
1082 TRACE(comm
,"stopbits %d\n",lpdcb
->StopBits
);
1084 switch (lpdcb
->StopBits
) {
1086 port
.c_cflag
&= ~CSTOPB
;
1089 port
.c_cflag
|= CSTOPB
;
1092 commerror
= IE_BYTESIZE
;
1097 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
1098 port
.c_cflag
|= CRTSCTS
;
1100 if (lpdcb
->fDtrDisable
)
1101 port
.c_cflag
&= ~CRTSCTS
;
1104 port
.c_iflag
|= IXON
;
1106 port
.c_iflag
&= ~IXON
;
1108 port
.c_iflag
|= IXOFF
;
1110 port
.c_iflag
&= ~IXOFF
;
1112 if (tcsetattr(lpdcb
->Id
, TCSADRAIN
, &port
) == -1) {
1113 commerror
= WinError();
1121 /*****************************************************************************
1122 * SetCommState32 (KERNEL32.452)
1124 BOOL32 WINAPI
SetCommState32(INT32 fd
,LPDCB32 lpdcb
)
1126 struct termios port
;
1127 struct DosDeviceStruct
*ptr
;
1129 TRACE(comm
,"fd %d, ptr %p\n",fd
,lpdcb
);
1130 if (tcgetattr(fd
,&port
) == -1) {
1131 commerror
= WinError();
1135 port
.c_cc
[VMIN
] = 0;
1136 port
.c_cc
[VTIME
] = 1;
1139 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
1141 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
1143 port
.c_iflag
|= (IGNBRK
);
1145 port
.c_oflag
&= ~(OPOST
);
1147 port
.c_cflag
&= ~(HUPCL
);
1148 port
.c_cflag
|= CLOCAL
| CREAD
;
1150 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
1151 port
.c_lflag
|= NOFLSH
;
1153 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1154 commerror
= IE_BADID
;
1157 if (ptr
->baudrate
> 0)
1158 lpdcb
->BaudRate
= ptr
->baudrate
;
1159 TRACE(comm
,"baudrate %ld\n",lpdcb
->BaudRate
);
1161 port
.c_cflag
&= ~CBAUD
;
1162 switch (lpdcb
->BaudRate
) {
1165 port
.c_cflag
|= B110
;
1169 port
.c_cflag
|= B300
;
1173 port
.c_cflag
|= B600
;
1177 port
.c_cflag
|= B1200
;
1181 port
.c_cflag
|= B2400
;
1185 port
.c_cflag
|= B4800
;
1189 port
.c_cflag
|= B9600
;
1193 port
.c_cflag
|= B19200
;
1197 port
.c_cflag
|= B38400
;
1200 commerror
= IE_BAUDRATE
;
1203 #elif !defined(__EMX__)
1204 switch (lpdcb
->BaudRate
) {
1207 port
.c_ospeed
= B110
;
1211 port
.c_ospeed
= B300
;
1215 port
.c_ospeed
= B600
;
1219 port
.c_ospeed
= B1200
;
1223 port
.c_ospeed
= B2400
;
1227 port
.c_ospeed
= B4800
;
1231 port
.c_ospeed
= B9600
;
1235 port
.c_ospeed
= B19200
;
1239 port
.c_ospeed
= B38400
;
1242 commerror
= IE_BAUDRATE
;
1245 port
.c_ispeed
= port
.c_ospeed
;
1247 TRACE(comm
,"bytesize %d\n",lpdcb
->ByteSize
);
1248 port
.c_cflag
&= ~CSIZE
;
1249 switch (lpdcb
->ByteSize
) {
1251 port
.c_cflag
|= CS5
;
1254 port
.c_cflag
|= CS6
;
1257 port
.c_cflag
|= CS7
;
1260 port
.c_cflag
|= CS8
;
1263 commerror
= IE_BYTESIZE
;
1267 TRACE(comm
,"parity %d\n",lpdcb
->Parity
);
1268 port
.c_cflag
&= ~(PARENB
| PARODD
);
1270 switch (lpdcb
->Parity
) {
1272 port
.c_iflag
&= ~INPCK
;
1275 port
.c_cflag
|= (PARENB
| PARODD
);
1276 port
.c_iflag
|= INPCK
;
1279 port
.c_cflag
|= PARENB
;
1280 port
.c_iflag
|= INPCK
;
1283 commerror
= IE_BYTESIZE
;
1288 TRACE(comm
,"stopbits %d\n",lpdcb
->StopBits
);
1289 switch (lpdcb
->StopBits
) {
1291 port
.c_cflag
&= ~CSTOPB
;
1294 port
.c_cflag
|= CSTOPB
;
1297 commerror
= IE_BYTESIZE
;
1301 if ( lpdcb
->fOutxCtsFlow
||
1302 lpdcb
->fDtrControl
== DTR_CONTROL_ENABLE
||
1303 lpdcb
->fRtsControl
== RTS_CONTROL_ENABLE
1305 port
.c_cflag
|= CRTSCTS
;
1306 if (lpdcb
->fDtrControl
== DTR_CONTROL_DISABLE
)
1307 port
.c_cflag
&= ~CRTSCTS
;
1311 port
.c_iflag
|= IXON
;
1313 port
.c_iflag
&= ~IXON
;
1315 port
.c_iflag
|= IXOFF
;
1317 port
.c_iflag
&= ~IXOFF
;
1319 if (tcsetattr(fd
,TCSADRAIN
,&port
)==-1) {
1320 commerror
= WinError();
1329 /*****************************************************************************
1330 * GetCommState (USER.202)
1332 INT16 WINAPI
GetCommState16(INT16 fd
, LPDCB16 lpdcb
)
1334 struct termios port
;
1336 TRACE(comm
,"fd %d, ptr %p\n", fd
, lpdcb
);
1337 if (tcgetattr(fd
, &port
) == -1) {
1338 commerror
= WinError();
1344 switch (port
.c_cflag
& CBAUD
) {
1346 switch (port
.c_ospeed
) {
1349 lpdcb
->BaudRate
= 110;
1352 lpdcb
->BaudRate
= 300;
1355 lpdcb
->BaudRate
= 600;
1358 lpdcb
->BaudRate
= 1200;
1361 lpdcb
->BaudRate
= 2400;
1364 lpdcb
->BaudRate
= 4800;
1367 lpdcb
->BaudRate
= 9600;
1370 lpdcb
->BaudRate
= 19200;
1373 lpdcb
->BaudRate
= 38400;
1376 lpdcb
->BaudRate
= 57600;
1379 lpdcb
->BaudRate
= 57601;
1383 switch (port
.c_cflag
& CSIZE
) {
1385 lpdcb
->ByteSize
= 5;
1388 lpdcb
->ByteSize
= 6;
1391 lpdcb
->ByteSize
= 7;
1394 lpdcb
->ByteSize
= 8;
1398 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
1400 lpdcb
->fParity
= NOPARITY
;
1403 lpdcb
->fParity
= EVENPARITY
;
1405 case (PARENB
| PARODD
):
1406 lpdcb
->fParity
= ODDPARITY
;
1410 if (port
.c_cflag
& CSTOPB
)
1411 lpdcb
->StopBits
= TWOSTOPBITS
;
1413 lpdcb
->StopBits
= ONESTOPBIT
;
1415 lpdcb
->RlsTimeout
= 50;
1416 lpdcb
->CtsTimeout
= 50;
1417 lpdcb
->DsrTimeout
= 50;
1421 lpdcb
->fDtrDisable
= 0;
1425 if (port
.c_cflag
& CRTSCTS
) {
1426 lpdcb
->fDtrflow
= 1;
1427 lpdcb
->fRtsflow
= 1;
1428 lpdcb
->fOutxCtsFlow
= 1;
1429 lpdcb
->fOutxDsrFlow
= 1;
1432 lpdcb
->fDtrDisable
= 1;
1434 if (port
.c_iflag
& IXON
)
1439 if (port
.c_iflag
& IXOFF
)
1448 lpdcb
->XoffLim
= 10;
1454 /*****************************************************************************
1455 * GetCommState (KERNEL32.159)
1457 BOOL32 WINAPI
GetCommState32(INT32 fd
, LPDCB32 lpdcb
)
1459 struct termios port
;
1461 TRACE(comm
,"fd %d, ptr %p\n", fd
, lpdcb
);
1462 if (GetDeviceStruct(fd
) == NULL
) return FALSE
;
1463 if (tcgetattr(fd
, &port
) == -1) {
1464 commerror
= WinError();
1469 switch (port
.c_cflag
& CBAUD
) {
1471 switch (port
.c_ospeed
) {
1474 lpdcb
->BaudRate
= 110;
1477 lpdcb
->BaudRate
= 300;
1480 lpdcb
->BaudRate
= 600;
1483 lpdcb
->BaudRate
= 1200;
1486 lpdcb
->BaudRate
= 2400;
1489 lpdcb
->BaudRate
= 4800;
1492 lpdcb
->BaudRate
= 9600;
1495 lpdcb
->BaudRate
= 19200;
1498 lpdcb
->BaudRate
= 38400;
1502 switch (port
.c_cflag
& CSIZE
) {
1504 lpdcb
->ByteSize
= 5;
1507 lpdcb
->ByteSize
= 6;
1510 lpdcb
->ByteSize
= 7;
1513 lpdcb
->ByteSize
= 8;
1517 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
1519 lpdcb
->fParity
= NOPARITY
;
1522 lpdcb
->fParity
= EVENPARITY
;
1524 case (PARENB
| PARODD
):
1525 lpdcb
->fParity
= ODDPARITY
;
1529 if (port
.c_cflag
& CSTOPB
)
1530 lpdcb
->StopBits
= TWOSTOPBITS
;
1532 lpdcb
->StopBits
= ONESTOPBIT
;
1539 if (port
.c_cflag
& CRTSCTS
) {
1540 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1541 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1542 lpdcb
->fOutxCtsFlow
= 1;
1543 lpdcb
->fOutxDsrFlow
= 1;
1547 lpdcb
->fDtrControl
= DTR_CONTROL_DISABLE
;
1548 lpdcb
->fRtsControl
= RTS_CONTROL_DISABLE
;
1550 if (port
.c_iflag
& IXON
)
1555 if (port
.c_iflag
& IXOFF
)
1564 lpdcb
->XoffLim
= 10;
1570 /*****************************************************************************
1571 * TransmitCommChar (USER.206)
1573 INT16 WINAPI
TransmitCommChar16(INT16 fd
,CHAR chTransmit
)
1575 struct DosDeviceStruct
*ptr
;
1577 TRACE(comm
, "fd %d, data %d \n", fd
, chTransmit
);
1578 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1579 commerror
= IE_BADID
;
1583 if (ptr
->suspended
) {
1584 commerror
= IE_HARDWARE
;
1588 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
1589 commerror
= WinError();
1597 /*****************************************************************************
1598 * TransmitCommChar (KERNEL32.535)
1600 BOOL32 WINAPI
TransmitCommChar32(INT32 fd
,CHAR chTransmit
)
1602 struct DosDeviceStruct
*ptr
;
1604 TRACE(comm
,"(%d,'%c')\n",fd
,chTransmit
);
1605 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1606 commerror
= IE_BADID
;
1610 if (ptr
->suspended
) {
1611 commerror
= IE_HARDWARE
;
1614 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
1615 commerror
= WinError();
1623 /*****************************************************************************
1624 * UngetCommChar (USER.212)
1626 INT16 WINAPI
UngetCommChar(INT16 fd
,CHAR chUnget
)
1628 struct DosDeviceStruct
*ptr
;
1630 TRACE(comm
,"fd %d (char %d)\n", fd
, chUnget
);
1631 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1632 commerror
= IE_BADID
;
1636 if (ptr
->suspended
) {
1637 commerror
= IE_HARDWARE
;
1642 ptr
->unget_byte
= chUnget
;
1647 /*****************************************************************************
1648 * ReadComm (USER.204)
1650 INT16 WINAPI
ReadComm(INT16 fd
,LPSTR lpvBuf
,INT16 cbRead
)
1653 struct DosDeviceStruct
*ptr
;
1655 TRACE(comm
, "fd %d, ptr %p, length %d\n", fd
, lpvBuf
, cbRead
);
1656 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1657 commerror
= IE_BADID
;
1661 if (ptr
->suspended
) {
1662 commerror
= IE_HARDWARE
;
1667 *lpvBuf
= ptr
->unget_byte
;
1675 status
= read(fd
, (void *) lpvBuf
, cbRead
);
1678 if (errno
!= EAGAIN
) {
1679 commerror
= WinError();
1686 TRACE(comm
,"%*s\n", length
+status
, lpvBuf
);
1688 return length
+ status
;
1692 /*****************************************************************************
1693 * WriteComm (USER.205)
1695 INT16 WINAPI
WriteComm(INT16 fd
, LPSTR lpvBuf
, INT16 cbWrite
)
1698 struct DosDeviceStruct
*ptr
;
1700 TRACE(comm
,"fd %d, ptr %p, length %d\n",
1701 fd
, lpvBuf
, cbWrite
);
1702 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1703 commerror
= IE_BADID
;
1707 if (ptr
->suspended
) {
1708 commerror
= IE_HARDWARE
;
1712 TRACE(comm
,"%*s\n", cbWrite
, lpvBuf
);
1713 length
= write(fd
, (void *) lpvBuf
, cbWrite
);
1716 commerror
= WinError();
1725 /*****************************************************************************
1726 * GetCommTimeouts (KERNEL32.160)
1728 BOOL32 WINAPI
GetCommTimeouts(INT32 fd
,LPCOMMTIMEOUTS lptimeouts
)
1730 fprintf(stderr
,"GetCommTimeouts(%x,%p), empty stub.\n",
1736 /*****************************************************************************
1737 * SetCommTimeouts (KERNEL32.453)
1739 BOOL32 WINAPI
SetCommTimeouts(INT32 fd
,LPCOMMTIMEOUTS lptimeouts
) {
1740 fprintf(stderr
,"SetCommTimeouts(%x,%p), empty stub.\n",
1746 /***********************************************************************
1747 * EnableCommNotification (USER.246)
1749 BOOL16 WINAPI
EnableCommNotification( INT16 fd
, HWND16 hwnd
,
1750 INT16 cbWriteNotify
, INT16 cbOutQueue
)
1752 fprintf(stderr
, "EnableCommNotification(%d, %x, %d, %d), empty stub.\n", fd
, hwnd
, cbWriteNotify
, cbOutQueue
);