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 WARN(comm
,"Can't use `%s' as %s !\n", temp
, option
);
82 if ((COM
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
83 WARN(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 WARN(comm
,"Can't use `%s' as %s !\n", temp
, option
);
104 if ((LPT
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
105 WARN(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 ERR(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 WARN(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 WARN(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 ERR(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 WARN(comm
,"Couldn't parse %s\n",ptr
);
353 if (!strncmp("stop=",ptr
,5)) {
354 if (!sscanf(ptr
+5,"%ld",&x
))
355 WARN(comm
,"Couldn't parse %s\n",ptr
);
359 if (!strncmp("data=",ptr
,5)) {
360 if (!sscanf(ptr
+5,"%ld",&x
))
361 WARN(comm
,"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 ERR(comm
,"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 ERR(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
;
639 WARN(comm
,"(fd=%d,nFunction=%d): Unknown function\n",
644 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
645 commerror
= WinError();
653 /*****************************************************************************
654 * EscapeCommFunction (KERNEL32.214)
656 BOOL32 WINAPI
EscapeCommFunction32(INT32 fd
,UINT32 nFunction
)
659 struct DosDeviceStruct
*ptr
;
661 TRACE(comm
,"fd=%d, function=%d\n", fd
, nFunction
);
662 if (tcgetattr(fd
,&port
) == -1) {
663 commerror
=WinError();
666 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
667 commerror
= IE_BADID
;
677 port
.c_cflag
&= TIOCM_DTR
;
683 port
.c_cflag
&= TIOCM_RTS
;
689 port
.c_cflag
|= CRTSCTS
;
693 port
.c_cflag
|= CRTSCTS
;
698 port
.c_iflag
|= IXOFF
;
702 port
.c_iflag
|= IXON
;
711 WARN(comm
,"(fd=%d,nFunction=%d): Unknown function\n",
716 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
717 commerror
= WinError();
725 /*****************************************************************************
726 * FlushComm (USER.215)
728 INT16 WINAPI
FlushComm(INT16 fd
,INT16 fnQueue
)
732 TRACE(comm
,"fd=%d, queue=%d\n", fd
, fnQueue
);
734 case 0: queue
= TCOFLUSH
;
736 case 1: queue
= TCIFLUSH
;
738 default:WARN(comm
,"(fd=%d,fnQueue=%d):Unknown queue\n",
742 if (tcflush(fd
, queue
)) {
743 commerror
= WinError();
751 /********************************************************************
752 * PurgeComm (KERNEL32.557)
754 BOOL32 WINAPI
PurgeComm( HANDLE32 hFile
, DWORD flags
)
756 FIXME(comm
, "(%08x %08lx) unimplemented stub\n",
761 /********************************************************************
762 * GetCommError (USER.203)
764 INT16 WINAPI
GetCommError(INT16 fd
,LPCOMSTAT lpStat
)
773 rc
= ioctl(fd
, TIOCOUTQ
, &cnt
);
774 if (rc
) WARN(comm
, "Error !\n");
775 lpStat
->cbOutQue
= cnt
;
777 rc
= ioctl(fd
, TIOCINQ
, &cnt
);
778 if (rc
) WARN(comm
, "Error !\n");
779 lpStat
->cbInQue
= cnt
;
781 TRACE(comm
, "fd %d, error %d, lpStat %d %d %d\n",
782 fd
, commerror
, lpStat
->status
, lpStat
->cbInQue
,
786 TRACE(comm
, "fd %d, error %d, lpStat NULL\n",
790 * [RER] I have no idea what the following is trying to accomplish.
791 * [RER] It is certainly not what the reference manual suggests.
793 temperror
= commerror
;
798 /*****************************************************************************
799 * ClearCommError (KERNEL32.21)
801 BOOL32 WINAPI
ClearCommError(INT32 fd
,LPDWORD errors
,LPCOMSTAT lpStat
)
805 TRACE(comm
, "fd %d (current error %d)\n",
807 temperror
= commerror
;
812 /*****************************************************************************
813 * SetCommEventMask (USER.208)
815 SEGPTR WINAPI
SetCommEventMask(INT16 fd
,UINT16 fuEvtMask
)
821 TRACE(comm
,"fd %d,mask %d\n",fd
,fuEvtMask
);
822 eventmask
|= fuEvtMask
;
823 if ((act
= GetCommPort(fd
)) == -1) {
824 WARN(comm
," fd %d not comm port\n",act
);
828 repid
= ioctl(fd
,TIOCMGET
,&mstat
);
829 TRACE(comm
, " ioctl %d, msr %x at %p %p\n",repid
,mstat
,stol
,unknown
[act
]);
830 if ((mstat
&TIOCM_CAR
)) {*stol
|= 0x80;}
832 TRACE(comm
," modem dcd construct %x\n",*stol
);
833 return SEGPTR_GET(unknown
[act
]);
836 /*****************************************************************************
837 * GetCommEventMask (USER.209)
839 UINT16 WINAPI
GetCommEventMask(INT16 fd
,UINT16 fnEvtClear
)
843 TRACE(comm
, "fd %d, mask %d\n", fd
, fnEvtClear
);
846 * Determine if any characters are available
848 if (fnEvtClear
& EV_RXCHAR
)
853 rc
= ioctl(fd
, TIOCINQ
, &cnt
);
854 if (cnt
) events
|= EV_RXCHAR
;
856 TRACE(comm
, "rxchar %ld\n", cnt
);
860 * There are other events that need to be checked for
864 TRACE(comm
, "return events %d\n", events
);
868 * [RER] The following was gibberish
871 tempmask
= eventmask
;
872 eventmask
&= ~fnEvtClear
;
877 /*****************************************************************************
878 * SetupComm (KERNEL32.676)
880 BOOL32 WINAPI
SetupComm( HANDLE32 hFile
, DWORD insize
, DWORD outsize
)
882 FIXME(comm
, "insize %ld outsize %ld unimplemented stub\n", insize
, outsize
);
886 /*****************************************************************************
887 * GetCommMask (KERNEL32.156)
889 BOOL32 WINAPI
GetCommMask(INT32 fd
,LPDWORD evtmask
)
891 TRACE(comm
, "fd %d, mask %p\n", fd
, evtmask
);
892 *evtmask
= eventmask
;
896 /*****************************************************************************
897 * SetCommMask (KERNEL32.451)
899 BOOL32 WINAPI
SetCommMask(INT32 fd
,DWORD evtmask
)
901 TRACE(comm
, "fd %d, mask %lx\n", fd
, evtmask
);
906 /*****************************************************************************
907 * SetCommState16 (USER.201)
909 INT16 WINAPI
SetCommState16(LPDCB16 lpdcb
)
912 struct DosDeviceStruct
*ptr
;
914 TRACE(comm
, "fd %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
915 if (tcgetattr(lpdcb
->Id
, &port
) == -1) {
916 commerror
= WinError();
921 port
.c_cc
[VTIME
] = 1;
924 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
926 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
928 port
.c_iflag
|= (IGNBRK
);
930 port
.c_oflag
&= ~(OPOST
);
932 port
.c_cflag
&= ~(HUPCL
);
933 port
.c_cflag
|= CLOCAL
| CREAD
;
935 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
936 port
.c_lflag
|= NOFLSH
;
938 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
939 commerror
= IE_BADID
;
942 if (ptr
->baudrate
> 0)
943 lpdcb
->BaudRate
= ptr
->baudrate
;
944 TRACE(comm
,"baudrate %d\n",lpdcb
->BaudRate
);
946 port
.c_cflag
&= ~CBAUD
;
947 switch (lpdcb
->BaudRate
) {
950 port
.c_cflag
|= B110
;
954 port
.c_cflag
|= B300
;
958 port
.c_cflag
|= B600
;
962 port
.c_cflag
|= B1200
;
966 port
.c_cflag
|= B2400
;
970 port
.c_cflag
|= B4800
;
974 port
.c_cflag
|= B9600
;
978 port
.c_cflag
|= B19200
;
982 port
.c_cflag
|= B38400
;
985 port
.c_cflag
|= B57600
;
988 port
.c_cflag
|= B115200
;
991 commerror
= IE_BAUDRATE
;
994 #elif !defined(__EMX__)
995 switch (lpdcb
->BaudRate
) {
998 port
.c_ospeed
= B110
;
1002 port
.c_ospeed
= B300
;
1006 port
.c_ospeed
= B600
;
1010 port
.c_ospeed
= B1200
;
1014 port
.c_ospeed
= B2400
;
1018 port
.c_ospeed
= B4800
;
1022 port
.c_ospeed
= B9600
;
1026 port
.c_ospeed
= B19200
;
1030 port
.c_ospeed
= B38400
;
1033 commerror
= IE_BAUDRATE
;
1036 port
.c_ispeed
= port
.c_ospeed
;
1038 TRACE(comm
,"bytesize %d\n",lpdcb
->ByteSize
);
1039 port
.c_cflag
&= ~CSIZE
;
1040 switch (lpdcb
->ByteSize
) {
1042 port
.c_cflag
|= CS5
;
1045 port
.c_cflag
|= CS6
;
1048 port
.c_cflag
|= CS7
;
1051 port
.c_cflag
|= CS8
;
1054 commerror
= IE_BYTESIZE
;
1058 TRACE(comm
,"parity %d\n",lpdcb
->Parity
);
1059 port
.c_cflag
&= ~(PARENB
| PARODD
);
1061 switch (lpdcb
->Parity
) {
1063 port
.c_iflag
&= ~INPCK
;
1066 port
.c_cflag
|= (PARENB
| PARODD
);
1067 port
.c_iflag
|= INPCK
;
1070 port
.c_cflag
|= PARENB
;
1071 port
.c_iflag
|= INPCK
;
1074 commerror
= IE_BYTESIZE
;
1079 TRACE(comm
,"stopbits %d\n",lpdcb
->StopBits
);
1081 switch (lpdcb
->StopBits
) {
1083 port
.c_cflag
&= ~CSTOPB
;
1086 port
.c_cflag
|= CSTOPB
;
1089 commerror
= IE_BYTESIZE
;
1094 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
1095 port
.c_cflag
|= CRTSCTS
;
1097 if (lpdcb
->fDtrDisable
)
1098 port
.c_cflag
&= ~CRTSCTS
;
1101 port
.c_iflag
|= IXON
;
1103 port
.c_iflag
&= ~IXON
;
1105 port
.c_iflag
|= IXOFF
;
1107 port
.c_iflag
&= ~IXOFF
;
1109 if (tcsetattr(lpdcb
->Id
, TCSADRAIN
, &port
) == -1) {
1110 commerror
= WinError();
1118 /*****************************************************************************
1119 * SetCommState32 (KERNEL32.452)
1121 BOOL32 WINAPI
SetCommState32(INT32 fd
,LPDCB32 lpdcb
)
1123 struct termios port
;
1124 struct DosDeviceStruct
*ptr
;
1126 TRACE(comm
,"fd %d, ptr %p\n",fd
,lpdcb
);
1127 if (tcgetattr(fd
,&port
) == -1) {
1128 commerror
= WinError();
1132 port
.c_cc
[VMIN
] = 0;
1133 port
.c_cc
[VTIME
] = 1;
1136 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
1138 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
1140 port
.c_iflag
|= (IGNBRK
);
1142 port
.c_oflag
&= ~(OPOST
);
1144 port
.c_cflag
&= ~(HUPCL
);
1145 port
.c_cflag
|= CLOCAL
| CREAD
;
1147 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
1148 port
.c_lflag
|= NOFLSH
;
1150 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1151 commerror
= IE_BADID
;
1154 if (ptr
->baudrate
> 0)
1155 lpdcb
->BaudRate
= ptr
->baudrate
;
1156 TRACE(comm
,"baudrate %ld\n",lpdcb
->BaudRate
);
1158 port
.c_cflag
&= ~CBAUD
;
1159 switch (lpdcb
->BaudRate
) {
1162 port
.c_cflag
|= B110
;
1166 port
.c_cflag
|= B300
;
1170 port
.c_cflag
|= B600
;
1174 port
.c_cflag
|= B1200
;
1178 port
.c_cflag
|= B2400
;
1182 port
.c_cflag
|= B4800
;
1186 port
.c_cflag
|= B9600
;
1190 port
.c_cflag
|= B19200
;
1194 port
.c_cflag
|= B38400
;
1197 commerror
= IE_BAUDRATE
;
1200 #elif !defined(__EMX__)
1201 switch (lpdcb
->BaudRate
) {
1204 port
.c_ospeed
= B110
;
1208 port
.c_ospeed
= B300
;
1212 port
.c_ospeed
= B600
;
1216 port
.c_ospeed
= B1200
;
1220 port
.c_ospeed
= B2400
;
1224 port
.c_ospeed
= B4800
;
1228 port
.c_ospeed
= B9600
;
1232 port
.c_ospeed
= B19200
;
1236 port
.c_ospeed
= B38400
;
1239 commerror
= IE_BAUDRATE
;
1242 port
.c_ispeed
= port
.c_ospeed
;
1244 TRACE(comm
,"bytesize %d\n",lpdcb
->ByteSize
);
1245 port
.c_cflag
&= ~CSIZE
;
1246 switch (lpdcb
->ByteSize
) {
1248 port
.c_cflag
|= CS5
;
1251 port
.c_cflag
|= CS6
;
1254 port
.c_cflag
|= CS7
;
1257 port
.c_cflag
|= CS8
;
1260 commerror
= IE_BYTESIZE
;
1264 TRACE(comm
,"parity %d\n",lpdcb
->Parity
);
1265 port
.c_cflag
&= ~(PARENB
| PARODD
);
1267 switch (lpdcb
->Parity
) {
1269 port
.c_iflag
&= ~INPCK
;
1272 port
.c_cflag
|= (PARENB
| PARODD
);
1273 port
.c_iflag
|= INPCK
;
1276 port
.c_cflag
|= PARENB
;
1277 port
.c_iflag
|= INPCK
;
1280 commerror
= IE_BYTESIZE
;
1285 TRACE(comm
,"stopbits %d\n",lpdcb
->StopBits
);
1286 switch (lpdcb
->StopBits
) {
1288 port
.c_cflag
&= ~CSTOPB
;
1291 port
.c_cflag
|= CSTOPB
;
1294 commerror
= IE_BYTESIZE
;
1298 if ( lpdcb
->fOutxCtsFlow
||
1299 lpdcb
->fDtrControl
== DTR_CONTROL_ENABLE
||
1300 lpdcb
->fRtsControl
== RTS_CONTROL_ENABLE
1302 port
.c_cflag
|= CRTSCTS
;
1303 if (lpdcb
->fDtrControl
== DTR_CONTROL_DISABLE
)
1304 port
.c_cflag
&= ~CRTSCTS
;
1308 port
.c_iflag
|= IXON
;
1310 port
.c_iflag
&= ~IXON
;
1312 port
.c_iflag
|= IXOFF
;
1314 port
.c_iflag
&= ~IXOFF
;
1316 if (tcsetattr(fd
,TCSADRAIN
,&port
)==-1) {
1317 commerror
= WinError();
1326 /*****************************************************************************
1327 * GetCommState (USER.202)
1329 INT16 WINAPI
GetCommState16(INT16 fd
, LPDCB16 lpdcb
)
1331 struct termios port
;
1333 TRACE(comm
,"fd %d, ptr %p\n", fd
, lpdcb
);
1334 if (tcgetattr(fd
, &port
) == -1) {
1335 commerror
= WinError();
1341 switch (port
.c_cflag
& CBAUD
) {
1343 switch (port
.c_ospeed
) {
1346 lpdcb
->BaudRate
= 110;
1349 lpdcb
->BaudRate
= 300;
1352 lpdcb
->BaudRate
= 600;
1355 lpdcb
->BaudRate
= 1200;
1358 lpdcb
->BaudRate
= 2400;
1361 lpdcb
->BaudRate
= 4800;
1364 lpdcb
->BaudRate
= 9600;
1367 lpdcb
->BaudRate
= 19200;
1370 lpdcb
->BaudRate
= 38400;
1373 lpdcb
->BaudRate
= 57600;
1376 lpdcb
->BaudRate
= 57601;
1380 switch (port
.c_cflag
& CSIZE
) {
1382 lpdcb
->ByteSize
= 5;
1385 lpdcb
->ByteSize
= 6;
1388 lpdcb
->ByteSize
= 7;
1391 lpdcb
->ByteSize
= 8;
1395 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
1397 lpdcb
->fParity
= NOPARITY
;
1400 lpdcb
->fParity
= EVENPARITY
;
1402 case (PARENB
| PARODD
):
1403 lpdcb
->fParity
= ODDPARITY
;
1407 if (port
.c_cflag
& CSTOPB
)
1408 lpdcb
->StopBits
= TWOSTOPBITS
;
1410 lpdcb
->StopBits
= ONESTOPBIT
;
1412 lpdcb
->RlsTimeout
= 50;
1413 lpdcb
->CtsTimeout
= 50;
1414 lpdcb
->DsrTimeout
= 50;
1418 lpdcb
->fDtrDisable
= 0;
1422 if (port
.c_cflag
& CRTSCTS
) {
1423 lpdcb
->fDtrflow
= 1;
1424 lpdcb
->fRtsflow
= 1;
1425 lpdcb
->fOutxCtsFlow
= 1;
1426 lpdcb
->fOutxDsrFlow
= 1;
1429 lpdcb
->fDtrDisable
= 1;
1431 if (port
.c_iflag
& IXON
)
1436 if (port
.c_iflag
& IXOFF
)
1445 lpdcb
->XoffLim
= 10;
1451 /*****************************************************************************
1452 * GetCommState (KERNEL32.159)
1454 BOOL32 WINAPI
GetCommState32(INT32 fd
, LPDCB32 lpdcb
)
1456 struct termios port
;
1458 TRACE(comm
,"fd %d, ptr %p\n", fd
, lpdcb
);
1459 if (GetDeviceStruct(fd
) == NULL
) return FALSE
;
1460 if (tcgetattr(fd
, &port
) == -1) {
1461 commerror
= WinError();
1466 switch (port
.c_cflag
& CBAUD
) {
1468 switch (port
.c_ospeed
) {
1471 lpdcb
->BaudRate
= 110;
1474 lpdcb
->BaudRate
= 300;
1477 lpdcb
->BaudRate
= 600;
1480 lpdcb
->BaudRate
= 1200;
1483 lpdcb
->BaudRate
= 2400;
1486 lpdcb
->BaudRate
= 4800;
1489 lpdcb
->BaudRate
= 9600;
1492 lpdcb
->BaudRate
= 19200;
1495 lpdcb
->BaudRate
= 38400;
1499 switch (port
.c_cflag
& CSIZE
) {
1501 lpdcb
->ByteSize
= 5;
1504 lpdcb
->ByteSize
= 6;
1507 lpdcb
->ByteSize
= 7;
1510 lpdcb
->ByteSize
= 8;
1514 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
1516 lpdcb
->fParity
= NOPARITY
;
1519 lpdcb
->fParity
= EVENPARITY
;
1521 case (PARENB
| PARODD
):
1522 lpdcb
->fParity
= ODDPARITY
;
1526 if (port
.c_cflag
& CSTOPB
)
1527 lpdcb
->StopBits
= TWOSTOPBITS
;
1529 lpdcb
->StopBits
= ONESTOPBIT
;
1536 if (port
.c_cflag
& CRTSCTS
) {
1537 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1538 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1539 lpdcb
->fOutxCtsFlow
= 1;
1540 lpdcb
->fOutxDsrFlow
= 1;
1544 lpdcb
->fDtrControl
= DTR_CONTROL_DISABLE
;
1545 lpdcb
->fRtsControl
= RTS_CONTROL_DISABLE
;
1547 if (port
.c_iflag
& IXON
)
1552 if (port
.c_iflag
& IXOFF
)
1561 lpdcb
->XoffLim
= 10;
1567 /*****************************************************************************
1568 * TransmitCommChar (USER.206)
1570 INT16 WINAPI
TransmitCommChar16(INT16 fd
,CHAR chTransmit
)
1572 struct DosDeviceStruct
*ptr
;
1574 TRACE(comm
, "fd %d, data %d \n", fd
, chTransmit
);
1575 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1576 commerror
= IE_BADID
;
1580 if (ptr
->suspended
) {
1581 commerror
= IE_HARDWARE
;
1585 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
1586 commerror
= WinError();
1594 /*****************************************************************************
1595 * TransmitCommChar (KERNEL32.535)
1597 BOOL32 WINAPI
TransmitCommChar32(INT32 fd
,CHAR chTransmit
)
1599 struct DosDeviceStruct
*ptr
;
1601 TRACE(comm
,"(%d,'%c')\n",fd
,chTransmit
);
1602 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1603 commerror
= IE_BADID
;
1607 if (ptr
->suspended
) {
1608 commerror
= IE_HARDWARE
;
1611 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
1612 commerror
= WinError();
1620 /*****************************************************************************
1621 * UngetCommChar (USER.212)
1623 INT16 WINAPI
UngetCommChar(INT16 fd
,CHAR chUnget
)
1625 struct DosDeviceStruct
*ptr
;
1627 TRACE(comm
,"fd %d (char %d)\n", fd
, chUnget
);
1628 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1629 commerror
= IE_BADID
;
1633 if (ptr
->suspended
) {
1634 commerror
= IE_HARDWARE
;
1639 ptr
->unget_byte
= chUnget
;
1644 /*****************************************************************************
1645 * ReadComm (USER.204)
1647 INT16 WINAPI
ReadComm(INT16 fd
,LPSTR lpvBuf
,INT16 cbRead
)
1650 struct DosDeviceStruct
*ptr
;
1652 TRACE(comm
, "fd %d, ptr %p, length %d\n", fd
, lpvBuf
, cbRead
);
1653 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1654 commerror
= IE_BADID
;
1658 if (ptr
->suspended
) {
1659 commerror
= IE_HARDWARE
;
1664 *lpvBuf
= ptr
->unget_byte
;
1672 status
= read(fd
, (void *) lpvBuf
, cbRead
);
1675 if (errno
!= EAGAIN
) {
1676 commerror
= WinError();
1683 TRACE(comm
,"%*s\n", length
+status
, lpvBuf
);
1685 return length
+ status
;
1689 /*****************************************************************************
1690 * WriteComm (USER.205)
1692 INT16 WINAPI
WriteComm(INT16 fd
, LPSTR lpvBuf
, INT16 cbWrite
)
1695 struct DosDeviceStruct
*ptr
;
1697 TRACE(comm
,"fd %d, ptr %p, length %d\n",
1698 fd
, lpvBuf
, cbWrite
);
1699 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1700 commerror
= IE_BADID
;
1704 if (ptr
->suspended
) {
1705 commerror
= IE_HARDWARE
;
1709 TRACE(comm
,"%*s\n", cbWrite
, lpvBuf
);
1710 length
= write(fd
, (void *) lpvBuf
, cbWrite
);
1713 commerror
= WinError();
1722 /*****************************************************************************
1723 * GetCommTimeouts (KERNEL32.160)
1725 BOOL32 WINAPI
GetCommTimeouts(INT32 fd
,LPCOMMTIMEOUTS lptimeouts
)
1727 FIXME(comm
,"(%x,%p):stub.\n",fd
,lptimeouts
);
1731 /*****************************************************************************
1732 * SetCommTimeouts (KERNEL32.453)
1734 BOOL32 WINAPI
SetCommTimeouts(INT32 fd
,LPCOMMTIMEOUTS lptimeouts
) {
1735 FIXME(comm
,"(%x,%p):stub.\n",fd
,lptimeouts
);
1739 /***********************************************************************
1740 * EnableCommNotification (USER.246)
1742 BOOL16 WINAPI
EnableCommNotification( INT16 fd
, HWND16 hwnd
,
1743 INT16 cbWriteNotify
, INT16 cbOutQueue
)
1745 FIXME(comm
, "(%d, %x, %d, %d):stub.\n", fd
, hwnd
, cbWriteNotify
, cbOutQueue
);