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>
27 #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__svr4__)
28 #include <sys/filio.h>
30 #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
);
89 "Comm_Init: %s = %s\n", option
, COM
[x
].devicename
);
92 strcpy(option
, "LPTx");
96 PROFILE_GetWineIniString( "parallelports", option
, "*",
98 if (!strcmp(temp
, "*") || *temp
== '\0')
99 LPT
[x
].devicename
= NULL
;
102 if (!S_ISCHR(st
.st_mode
))
103 fprintf(stderr
,"comm: can't use `%s' as %s !\n", temp
, option
);
105 if ((LPT
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
106 fprintf(stderr
,"comm: can't malloc for device info!\n");
109 strcpy(LPT
[x
].devicename
, temp
);
112 "Comm_Init: %s = %s\n", option
, LPT
[x
].devicename
);
119 struct DosDeviceStruct
*GetDeviceStruct(int fd
)
123 for (x
=0; x
!=MAX_PORTS
; x
++) {
133 int GetCommPort(int fd
)
137 for (x
=0; x
<MAX_PORTS
; x
++) {
145 int ValidCOMPort(int x
)
147 return(x
< MAX_PORTS
? (int) COM
[x
].devicename
: 0);
150 int ValidLPTPort(int x
)
152 return(x
< MAX_PORTS
? (int) LPT
[x
].devicename
: 0);
157 dprintf_comm(stddeb
, "WinError: errno = %d\n", errno
);
164 /**************************************************************************
165 * BuildCommDCB (USER.213)
167 BOOL16 WINAPI
BuildCommDCB16(LPCSTR device
, LPDCB16 lpdcb
)
169 /* "COM1:9600,n,8,1" */
172 char *ptr
, temp
[256];
175 "BuildCommDCB: (%s), ptr %p\n", device
, lpdcb
);
178 if (!lstrncmpi32A(device
,"COM",3)) {
179 port
= device
[3] - '0';
183 fprintf(stderr
, "comm: BUG ! COM0 can't exists!.\n");
184 commerror
= IE_BADID
;
187 if (!ValidCOMPort(port
)) {
188 commerror
= IE_BADID
;
192 memset(lpdcb
, 0, sizeof(DCB16
)); /* initialize */
195 OpenComm(device
, 0, 0);
197 lpdcb
->Id
= COM
[port
].fd
;
202 if (*(device
+4) != ':')
205 strcpy(temp
,device
+5);
206 ptr
= strtok(temp
, ", ");
208 if (COM
[port
].baudrate
> 0)
209 lpdcb
->BaudRate
= COM
[port
].baudrate
;
211 lpdcb
->BaudRate
= atoi(ptr
);
212 dprintf_comm(stddeb
,"BuildCommDCB: baudrate (%d)\n", lpdcb
->BaudRate
);
214 ptr
= strtok(NULL
, ", ");
216 *ptr
= toupper(*ptr
);
218 dprintf_comm(stddeb
,"BuildCommDCB: parity (%c)\n", *ptr
);
222 lpdcb
->Parity
= NOPARITY
;
226 lpdcb
->Parity
= EVENPARITY
;
229 lpdcb
->Parity
= MARKPARITY
;
232 lpdcb
->Parity
= ODDPARITY
;
235 fprintf(stderr
,"comm: unknown parity `%c'!\n", *ptr
);
239 ptr
= strtok(NULL
, ", ");
240 dprintf_comm(stddeb
, "BuildCommDCB: charsize (%c)\n", *ptr
);
241 lpdcb
->ByteSize
= *ptr
- '0';
243 ptr
= strtok(NULL
, ", ");
244 dprintf_comm(stddeb
, "BuildCommDCB: stopbits (%c)\n", *ptr
);
247 lpdcb
->StopBits
= ONESTOPBIT
;
250 lpdcb
->StopBits
= TWOSTOPBITS
;
253 fprintf(stderr
,"comm: unknown # of stopbits `%c'!\n", *ptr
);
261 /**************************************************************************
262 * BuildCommDCBA (KERNEL32.14)
264 BOOL32 WINAPI
BuildCommDCB32A(LPCSTR device
,LPDCB32 lpdcb
)
266 return BuildCommDCBAndTimeouts32A(device
,lpdcb
,NULL
);
269 /**************************************************************************
270 * BuildCommDCBAndTimeoutsA (KERNEL32.15)
272 BOOL32 WINAPI
BuildCommDCBAndTimeouts32A(LPCSTR device
, LPDCB32 lpdcb
,
273 LPCOMMTIMEOUTS lptimeouts
)
278 dprintf_comm(stddeb
,"BuildCommDCBAndTimeouts32A(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
281 if (!lstrncmpi32A(device
,"COM",3)) {
284 fprintf(stderr
,"comm:BUG! COM0 can't exists!.\n");
287 if (!ValidCOMPort(port
))
289 if (*(device
+4)!=':')
291 temp
=(LPSTR
)(device
+5);
295 memset(lpdcb
, 0, sizeof(DCB32
)); /* initialize */
297 lpdcb
->DCBlength
= sizeof(DCB32
);
298 if (strchr(temp
,',')) { /* old style */
301 char last
=temp
[strlen(temp
)-1];
303 ret
=BuildCommDCB16(device
,&dcb16
);
306 lpdcb
->BaudRate
= dcb16
.BaudRate
;
307 lpdcb
->ByteSize
= dcb16
.ByteSize
;
308 lpdcb
->fBinary
= dcb16
.fBinary
;
309 lpdcb
->Parity
= dcb16
.Parity
;
310 lpdcb
->fParity
= dcb16
.fParity
;
311 lpdcb
->fNull
= dcb16
.fNull
;
312 lpdcb
->StopBits
= dcb16
.StopBits
;
316 lpdcb
->fOutxCtsFlow
= FALSE
;
317 lpdcb
->fOutxDsrFlow
= FALSE
;
318 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
319 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
320 } else if (last
=='p') {
322 lpdcb
->fOutX
= FALSE
;
323 lpdcb
->fOutxCtsFlow
= TRUE
;
324 lpdcb
->fOutxDsrFlow
= TRUE
;
325 lpdcb
->fDtrControl
= DTR_CONTROL_HANDSHAKE
;
326 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
329 lpdcb
->fOutX
= FALSE
;
330 lpdcb
->fOutxCtsFlow
= FALSE
;
331 lpdcb
->fOutxDsrFlow
= FALSE
;
332 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
333 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
335 lpdcb
->XonChar
= dcb16
.XonChar
;
336 lpdcb
->XoffChar
= dcb16
.XoffChar
;
337 lpdcb
->ErrorChar
= dcb16
.PeChar
;
338 lpdcb
->fErrorChar
= dcb16
.fPeChar
;
339 lpdcb
->EofChar
= dcb16
.EofChar
;
340 lpdcb
->EvtChar
= dcb16
.EvtChar
;
341 lpdcb
->XonLim
= dcb16
.XonLim
;
342 lpdcb
->XoffLim
= dcb16
.XoffLim
;
345 ptr
=strtok(temp
," ");
350 if (!strncmp("baud=",ptr
,5)) {
351 if (!sscanf(ptr
+5,"%ld",&x
))
352 fprintf(stderr
,"BuildCommDCB32A:Couldn't parse %s\n",ptr
);
356 if (!strncmp("stop=",ptr
,5)) {
357 if (!sscanf(ptr
+5,"%ld",&x
))
358 fprintf(stderr
,"BuildCommDCB32A:Couldn't parse %s\n",ptr
);
362 if (!strncmp("data=",ptr
,5)) {
363 if (!sscanf(ptr
+5,"%ld",&x
))
364 fprintf(stderr
,"BuildCommDCB32A:Couldn't parse %s\n",ptr
);
368 if (!strncmp("parity=",ptr
,7)) {
369 lpdcb
->fParity
= TRUE
;
372 lpdcb
->fParity
= FALSE
;
373 lpdcb
->Parity
= NOPARITY
;
376 lpdcb
->Parity
= EVENPARITY
;
379 lpdcb
->Parity
= ODDPARITY
;
382 lpdcb
->Parity
= MARKPARITY
;
388 fprintf(stderr
,"BuildCommDCB32A: Unhandled specifier '%s', please report.\n",ptr
);
389 ptr
=strtok(NULL
," ");
391 if (lpdcb
->BaudRate
==110)
396 /**************************************************************************
397 * BuildCommDCBAndTimeoutsW (KERNEL32.16)
399 BOOL32 WINAPI
BuildCommDCBAndTimeouts32W( LPCWSTR devid
, LPDCB32 lpdcb
,
400 LPCOMMTIMEOUTS lptimeouts
)
405 dprintf_comm(stddeb
,"BuildCommDCBAndTimeouts32W(%p,%p,%p)\n",devid
,lpdcb
,lptimeouts
);
406 devidA
= HEAP_strdupWtoA( GetProcessHeap(), 0, devid
);
407 ret
=BuildCommDCBAndTimeouts32A(devidA
,lpdcb
,lptimeouts
);
408 HeapFree( GetProcessHeap(), 0, devidA
);
412 /**************************************************************************
413 * BuildCommDCBW (KERNEL32.17)
415 BOOL32 WINAPI
BuildCommDCB32W(LPCWSTR devid
,LPDCB32 lpdcb
)
417 return BuildCommDCBAndTimeouts32W(devid
,lpdcb
,NULL
);
420 /*****************************************************************************
421 * OpenComm (USER.200)
423 INT16 WINAPI
OpenComm(LPCSTR device
,UINT16 cbInQueue
,UINT16 cbOutQueue
)
428 "OpenComm: %s, %d, %d\n", device
, cbInQueue
, cbOutQueue
);
431 if (!lstrncmpi32A(device
,"COM",3)) {
432 port
= device
[3] - '0';
435 fprintf(stderr
, "comm: BUG ! COM0 doesn't exist !\n");
436 commerror
= IE_BADID
;
440 "OpenComm: %s = %s\n", device
, COM
[port
].devicename
);
442 if (!ValidCOMPort(port
)) {
443 commerror
= IE_BADID
;
450 fd
= open(COM
[port
].devicename
, O_RDWR
| O_NONBLOCK
);
452 commerror
= WinError();
455 unknown
[port
] = SEGPTR_ALLOC(40);
456 bzero(unknown
[port
],40);
462 if (!lstrncmpi32A(device
,"LPT",3)) {
463 port
= device
[3] - '0';
465 if (!ValidLPTPort(port
)) {
466 commerror
= IE_BADID
;
474 fd
= open(LPT
[port
].devicename
, O_RDWR
| O_NONBLOCK
, 0);
476 commerror
= WinError();
486 /*****************************************************************************
487 * CloseComm (USER.207)
489 INT16 WINAPI
CloseComm(INT16 fd
)
492 dprintf_comm(stddeb
,"CloseComm: fd %d\n", fd
);
493 if ((port
= GetCommPort(fd
)) !=-1) { /* [LW] */
494 SEGPTR_FREE(unknown
[port
]);
495 COM
[port
].fd
= 0; /* my adaptation of RER's fix */
497 commerror
= IE_BADID
;
501 if (close(fd
) == -1) {
502 commerror
= WinError();
510 /*****************************************************************************
511 * SetCommBreak (USER.210)
513 INT16 WINAPI
SetCommBreak16(INT16 fd
)
515 struct DosDeviceStruct
*ptr
;
517 dprintf_comm(stddeb
,"SetCommBreak: fd: %d\n", fd
);
518 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
519 commerror
= IE_BADID
;
528 /*****************************************************************************
529 * SetCommBreak (KERNEL32.449)
531 BOOL32 WINAPI
SetCommBreak32(INT32 fd
)
534 struct DosDeviceStruct
*ptr
;
536 dprintf_comm(stddeb
,"SetCommBreak: fd: %d\n", fd
);
537 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
538 commerror
= IE_BADID
;
547 /*****************************************************************************
548 * ClearCommBreak (USER.211)
550 INT16 WINAPI
ClearCommBreak16(INT16 fd
)
552 struct DosDeviceStruct
*ptr
;
554 dprintf_comm(stddeb
,"ClearCommBreak: fd: %d\n", fd
);
555 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
556 commerror
= IE_BADID
;
565 /*****************************************************************************
566 * ClearCommBreak (KERNEL32.20)
568 BOOL32 WINAPI
ClearCommBreak32(INT32 fd
)
570 struct DosDeviceStruct
*ptr
;
572 dprintf_comm(stddeb
,"ClearCommBreak: fd: %d\n", fd
);
573 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
574 commerror
= IE_BADID
;
583 /*****************************************************************************
584 * EscapeCommFunction (USER.214)
586 LONG WINAPI
EscapeCommFunction16(UINT16 fd
,UINT16 nFunction
)
591 dprintf_comm(stddeb
,"EscapeCommFunction fd: %d, function: %d\n", fd
, nFunction
);
592 if (tcgetattr(fd
,&port
) == -1) {
593 commerror
=WinError();
602 for (max
= MAX_PORTS
;!COM
[max
].devicename
;max
--)
608 for (max
= MAX_PORTS
;!LPT
[max
].devicename
;max
--)
615 port
.c_cflag
&= TIOCM_DTR
;
621 port
.c_cflag
&= TIOCM_RTS
;
627 port
.c_cflag
|= CRTSCTS
;
631 port
.c_cflag
|= CRTSCTS
;
636 port
.c_iflag
|= IXOFF
;
640 port
.c_iflag
|= IXON
;
645 "EscapeCommFunction fd: %d, unknown function: %d\n",
650 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
651 commerror
= WinError();
659 /*****************************************************************************
660 * EscapeCommFunction (KERNEL32.214)
662 BOOL32 WINAPI
EscapeCommFunction32(INT32 fd
,UINT32 nFunction
)
665 struct DosDeviceStruct
*ptr
;
667 dprintf_comm(stddeb
,"EscapeCommFunction fd: %d, function: %d\n", fd
, nFunction
);
668 if (tcgetattr(fd
,&port
) == -1) {
669 commerror
=WinError();
672 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
673 commerror
= IE_BADID
;
683 port
.c_cflag
&= TIOCM_DTR
;
689 port
.c_cflag
&= TIOCM_RTS
;
695 port
.c_cflag
|= CRTSCTS
;
699 port
.c_cflag
|= CRTSCTS
;
704 port
.c_iflag
|= IXOFF
;
708 port
.c_iflag
|= IXON
;
718 "EscapeCommFunction32 fd: %d, unknown function: %d\n",
723 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
724 commerror
= WinError();
732 /*****************************************************************************
733 * FlushComm (USER.215)
735 INT16 WINAPI
FlushComm(INT16 fd
,INT16 fnQueue
)
739 dprintf_comm(stddeb
,"FlushComm fd: %d, queue: %d\n", fd
, fnQueue
);
741 case 0: queue
= TCOFLUSH
;
743 case 1: queue
= TCIFLUSH
;
745 default:fprintf(stderr
,
746 "FlushComm fd: %d, UNKNOWN queue: %d\n",
750 if (tcflush(fd
, queue
)) {
751 commerror
= WinError();
759 /********************************************************************
760 * PurgeComm (KERNEL32.557)
762 BOOL32 WINAPI
PurgeComm( HANDLE32 hFile
, DWORD flags
)
764 dprintf_comm(stdnimp
, "PurgeComm(%08x %08lx) unimplemented stub\n",
769 /********************************************************************
770 * GetCommError (USER.203)
772 INT16 WINAPI
GetCommError(INT16 fd
,LPCOMSTAT lpStat
)
781 rc
= ioctl(fd
, TIOCOUTQ
, &cnt
);
782 if (rc
) fprintf(stderr
, "Error !\n");
783 lpStat
->cbOutQue
= cnt
;
785 rc
= ioctl(fd
, TIOCINQ
, &cnt
);
786 if (rc
) fprintf(stderr
, "Error !\n");
787 lpStat
->cbInQue
= cnt
;
790 "GetCommError: fd %d, error %d, lpStat %d %d %d\n",
792 lpStat
->status
, lpStat
->cbInQue
, lpStat
->cbOutQue
);
796 "GetCommError: fd %d, error %d, lpStat NULL\n",
800 * [RER] I have no idea what the following is trying to accomplish.
801 * [RER] It is certainly not what the reference manual suggests.
803 temperror
= commerror
;
808 /*****************************************************************************
809 * ClearCommError (KERNEL32.21)
811 BOOL32 WINAPI
ClearCommError(INT32 fd
,LPDWORD errors
,LPCOMSTAT lpStat
)
816 "ClearCommError: fd %d (current error %d)\n", fd
, commerror
);
817 temperror
= commerror
;
822 /*****************************************************************************
823 * SetCommEventMask (USER.208)
825 SEGPTR WINAPI
SetCommEventMask(INT16 fd
,UINT16 fuEvtMask
)
831 dprintf_comm(stddeb
,"SetCommEventMask:fd %d,mask %d\n",fd
,fuEvtMask
);
832 eventmask
|= fuEvtMask
;
833 if ((act
= GetCommPort(fd
)) == -1) {
834 dprintf_comm(stddeb
," fd %d not comm port\n",act
);
838 repid
= ioctl(fd
,TIOCMGET
,&mstat
);
840 " ioctl %d, msr %x at %p %p\n",repid
,mstat
,stol
,unknown
[act
]);
841 if ((mstat
&TIOCM_CAR
)) {*stol
|= 0x80;}
843 dprintf_comm(stddeb
," modem dcd construct %x\n",*stol
);
844 return SEGPTR_GET(unknown
[act
]);
847 /*****************************************************************************
848 * GetCommEventMask (USER.209)
850 UINT16 WINAPI
GetCommEventMask(INT16 fd
,UINT16 fnEvtClear
)
855 "GetCommEventMask: fd %d, mask %d\n", fd
, fnEvtClear
);
858 * Determine if any characters are available
860 if (fnEvtClear
& EV_RXCHAR
)
865 rc
= ioctl(fd
, TIOCINQ
, &cnt
);
866 if (cnt
) events
|= EV_RXCHAR
;
869 "GetCommEventMask: rxchar %ld\n", cnt
);
873 * There are other events that need to be checked for
878 "GetCommEventMask: return events %d\n", events
);
882 * [RER] The following was gibberish
885 tempmask
= eventmask
;
886 eventmask
&= ~fnEvtClear
;
891 /*****************************************************************************
892 * SetupComm (KERNEL32.676)
894 BOOL32 WINAPI
SetupComm( HANDLE32 hFile
, DWORD insize
, DWORD outsize
)
896 dprintf_comm(stdnimp
, "SetupComm: insize %ld outsize %ld unimplemented stub\n", insize
, outsize
);
900 /*****************************************************************************
901 * GetCommMask (KERNEL32.156)
903 BOOL32 WINAPI
GetCommMask(INT32 fd
,LPDWORD evtmask
)
906 "GetCommMask: fd %d, mask %p\n", fd
, evtmask
);
907 *evtmask
= eventmask
;
911 /*****************************************************************************
912 * SetCommMask (KERNEL32.451)
914 BOOL32 WINAPI
SetCommMask(INT32 fd
,DWORD evtmask
)
917 "SetCommMask: fd %d, mask %lx\n", fd
, evtmask
);
922 /*****************************************************************************
923 * SetCommState16 (USER.201)
925 INT16 WINAPI
SetCommState16(LPDCB16 lpdcb
)
928 struct DosDeviceStruct
*ptr
;
931 "SetCommState: fd %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
932 if (tcgetattr(lpdcb
->Id
, &port
) == -1) {
933 commerror
= WinError();
938 port
.c_cc
[VTIME
] = 1;
941 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
943 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
945 port
.c_iflag
|= (IGNBRK
);
947 port
.c_oflag
&= ~(OPOST
);
949 port
.c_cflag
&= ~(HUPCL
);
950 port
.c_cflag
|= CLOCAL
| CREAD
;
952 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
953 port
.c_lflag
|= NOFLSH
;
955 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
956 commerror
= IE_BADID
;
959 if (ptr
->baudrate
> 0)
960 lpdcb
->BaudRate
= ptr
->baudrate
;
961 dprintf_comm(stddeb
,"SetCommState: baudrate %d\n",lpdcb
->BaudRate
);
963 port
.c_cflag
&= ~CBAUD
;
964 switch (lpdcb
->BaudRate
) {
967 port
.c_cflag
|= B110
;
971 port
.c_cflag
|= B300
;
975 port
.c_cflag
|= B600
;
979 port
.c_cflag
|= B1200
;
983 port
.c_cflag
|= B2400
;
987 port
.c_cflag
|= B4800
;
991 port
.c_cflag
|= B9600
;
995 port
.c_cflag
|= B19200
;
999 port
.c_cflag
|= B38400
;
1002 commerror
= IE_BAUDRATE
;
1005 #elif !defined(__EMX__)
1006 switch (lpdcb
->BaudRate
) {
1009 port
.c_ospeed
= B110
;
1013 port
.c_ospeed
= B300
;
1017 port
.c_ospeed
= B600
;
1021 port
.c_ospeed
= B1200
;
1025 port
.c_ospeed
= B2400
;
1029 port
.c_ospeed
= B4800
;
1033 port
.c_ospeed
= B9600
;
1037 port
.c_ospeed
= B19200
;
1041 port
.c_ospeed
= B38400
;
1044 commerror
= IE_BAUDRATE
;
1047 port
.c_ispeed
= port
.c_ospeed
;
1049 dprintf_comm(stddeb
,"SetCommState: bytesize %d\n",lpdcb
->ByteSize
);
1050 port
.c_cflag
&= ~CSIZE
;
1051 switch (lpdcb
->ByteSize
) {
1053 port
.c_cflag
|= CS5
;
1056 port
.c_cflag
|= CS6
;
1059 port
.c_cflag
|= CS7
;
1062 port
.c_cflag
|= CS8
;
1065 commerror
= IE_BYTESIZE
;
1069 dprintf_comm(stddeb
,"SetCommState: parity %d\n",lpdcb
->Parity
);
1070 port
.c_cflag
&= ~(PARENB
| PARODD
);
1072 switch (lpdcb
->Parity
) {
1074 port
.c_iflag
&= ~INPCK
;
1077 port
.c_cflag
|= (PARENB
| PARODD
);
1078 port
.c_iflag
|= INPCK
;
1081 port
.c_cflag
|= PARENB
;
1082 port
.c_iflag
|= INPCK
;
1085 commerror
= IE_BYTESIZE
;
1090 dprintf_comm(stddeb
,"SetCommState: stopbits %d\n",lpdcb
->StopBits
);
1091 switch (lpdcb
->StopBits
) {
1093 port
.c_cflag
&= ~CSTOPB
;
1096 port
.c_cflag
|= CSTOPB
;
1099 commerror
= IE_BYTESIZE
;
1104 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
1105 port
.c_cflag
|= CRTSCTS
;
1107 if (lpdcb
->fDtrDisable
)
1108 port
.c_cflag
&= ~CRTSCTS
;
1111 port
.c_iflag
|= IXON
;
1113 port
.c_iflag
&= ~IXON
;
1115 port
.c_iflag
|= IXOFF
;
1117 port
.c_iflag
&= ~IXOFF
;
1119 if (tcsetattr(lpdcb
->Id
, TCSADRAIN
, &port
) == -1) {
1120 commerror
= WinError();
1128 /*****************************************************************************
1129 * SetCommState32 (KERNEL32.452)
1131 BOOL32 WINAPI
SetCommState32(INT32 fd
,LPDCB32 lpdcb
)
1133 struct termios port
;
1134 struct DosDeviceStruct
*ptr
;
1136 dprintf_comm(stddeb
,"SetCommState: fd %d, ptr %p\n",fd
,lpdcb
);
1137 if (tcgetattr(fd
,&port
) == -1) {
1138 commerror
= WinError();
1142 port
.c_cc
[VMIN
] = 0;
1143 port
.c_cc
[VTIME
] = 1;
1146 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
1148 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
1150 port
.c_iflag
|= (IGNBRK
);
1152 port
.c_oflag
&= ~(OPOST
);
1154 port
.c_cflag
&= ~(HUPCL
);
1155 port
.c_cflag
|= CLOCAL
| CREAD
;
1157 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
1158 port
.c_lflag
|= NOFLSH
;
1160 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1161 commerror
= IE_BADID
;
1164 if (ptr
->baudrate
> 0)
1165 lpdcb
->BaudRate
= ptr
->baudrate
;
1166 dprintf_comm(stddeb
,"SetCommState: baudrate %ld\n",lpdcb
->BaudRate
);
1168 port
.c_cflag
&= ~CBAUD
;
1169 switch (lpdcb
->BaudRate
) {
1172 port
.c_cflag
|= B110
;
1176 port
.c_cflag
|= B300
;
1180 port
.c_cflag
|= B600
;
1184 port
.c_cflag
|= B1200
;
1188 port
.c_cflag
|= B2400
;
1192 port
.c_cflag
|= B4800
;
1196 port
.c_cflag
|= B9600
;
1200 port
.c_cflag
|= B19200
;
1204 port
.c_cflag
|= B38400
;
1207 commerror
= IE_BAUDRATE
;
1210 #elif !defined(__EMX__)
1211 switch (lpdcb
->BaudRate
) {
1214 port
.c_ospeed
= B110
;
1218 port
.c_ospeed
= B300
;
1222 port
.c_ospeed
= B600
;
1226 port
.c_ospeed
= B1200
;
1230 port
.c_ospeed
= B2400
;
1234 port
.c_ospeed
= B4800
;
1238 port
.c_ospeed
= B9600
;
1242 port
.c_ospeed
= B19200
;
1246 port
.c_ospeed
= B38400
;
1249 commerror
= IE_BAUDRATE
;
1252 port
.c_ispeed
= port
.c_ospeed
;
1254 dprintf_comm(stddeb
,"SetCommState: bytesize %d\n",lpdcb
->ByteSize
);
1255 port
.c_cflag
&= ~CSIZE
;
1256 switch (lpdcb
->ByteSize
) {
1258 port
.c_cflag
|= CS5
;
1261 port
.c_cflag
|= CS6
;
1264 port
.c_cflag
|= CS7
;
1267 port
.c_cflag
|= CS8
;
1270 commerror
= IE_BYTESIZE
;
1274 dprintf_comm(stddeb
,"SetCommState: parity %d\n",lpdcb
->Parity
);
1275 port
.c_cflag
&= ~(PARENB
| PARODD
);
1277 switch (lpdcb
->Parity
) {
1279 port
.c_iflag
&= ~INPCK
;
1282 port
.c_cflag
|= (PARENB
| PARODD
);
1283 port
.c_iflag
|= INPCK
;
1286 port
.c_cflag
|= PARENB
;
1287 port
.c_iflag
|= INPCK
;
1290 commerror
= IE_BYTESIZE
;
1295 dprintf_comm(stddeb
,"SetCommState: stopbits %d\n",lpdcb
->StopBits
);
1296 switch (lpdcb
->StopBits
) {
1298 port
.c_cflag
&= ~CSTOPB
;
1301 port
.c_cflag
|= CSTOPB
;
1304 commerror
= IE_BYTESIZE
;
1308 if ( lpdcb
->fOutxCtsFlow
||
1309 lpdcb
->fDtrControl
== DTR_CONTROL_ENABLE
||
1310 lpdcb
->fRtsControl
== RTS_CONTROL_ENABLE
1312 port
.c_cflag
|= CRTSCTS
;
1313 if (lpdcb
->fDtrControl
== DTR_CONTROL_DISABLE
)
1314 port
.c_cflag
&= ~CRTSCTS
;
1318 port
.c_iflag
|= IXON
;
1320 port
.c_iflag
&= ~IXON
;
1322 port
.c_iflag
|= IXOFF
;
1324 port
.c_iflag
&= ~IXOFF
;
1326 if (tcsetattr(fd
,TCSADRAIN
,&port
)==-1) {
1327 commerror
= WinError();
1336 /*****************************************************************************
1337 * GetCommState (USER.202)
1339 INT16 WINAPI
GetCommState16(INT16 fd
, LPDCB16 lpdcb
)
1341 struct termios port
;
1343 dprintf_comm(stddeb
,"GetCommState: fd %d, ptr %p\n", fd
, lpdcb
);
1344 if (tcgetattr(fd
, &port
) == -1) {
1345 commerror
= WinError();
1351 switch (port
.c_cflag
& CBAUD
) {
1353 switch (port
.c_ospeed
) {
1356 lpdcb
->BaudRate
= 110;
1359 lpdcb
->BaudRate
= 300;
1362 lpdcb
->BaudRate
= 600;
1365 lpdcb
->BaudRate
= 1200;
1368 lpdcb
->BaudRate
= 2400;
1371 lpdcb
->BaudRate
= 4800;
1374 lpdcb
->BaudRate
= 9600;
1377 lpdcb
->BaudRate
= 19200;
1380 lpdcb
->BaudRate
= 38400;
1384 switch (port
.c_cflag
& CSIZE
) {
1386 lpdcb
->ByteSize
= 5;
1389 lpdcb
->ByteSize
= 6;
1392 lpdcb
->ByteSize
= 7;
1395 lpdcb
->ByteSize
= 8;
1399 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
1401 lpdcb
->fParity
= NOPARITY
;
1404 lpdcb
->fParity
= EVENPARITY
;
1406 case (PARENB
| PARODD
):
1407 lpdcb
->fParity
= ODDPARITY
;
1411 if (port
.c_cflag
& CSTOPB
)
1412 lpdcb
->StopBits
= TWOSTOPBITS
;
1414 lpdcb
->StopBits
= ONESTOPBIT
;
1416 lpdcb
->RlsTimeout
= 50;
1417 lpdcb
->CtsTimeout
= 50;
1418 lpdcb
->DsrTimeout
= 50;
1422 lpdcb
->fDtrDisable
= 0;
1426 if (port
.c_cflag
& CRTSCTS
) {
1427 lpdcb
->fDtrflow
= 1;
1428 lpdcb
->fRtsflow
= 1;
1429 lpdcb
->fOutxCtsFlow
= 1;
1430 lpdcb
->fOutxDsrFlow
= 1;
1433 lpdcb
->fDtrDisable
= 1;
1435 if (port
.c_iflag
& IXON
)
1440 if (port
.c_iflag
& IXOFF
)
1449 lpdcb
->XoffLim
= 10;
1455 /*****************************************************************************
1456 * GetCommState (KERNEL32.159)
1458 BOOL32 WINAPI
GetCommState32(INT32 fd
, LPDCB32 lpdcb
)
1460 struct termios port
;
1463 dprintf_comm(stddeb
,"GetCommState32: fd %d, ptr %p\n", fd
, lpdcb
);
1464 if (tcgetattr(fd
, &port
) == -1) {
1465 commerror
= WinError();
1470 switch (port
.c_cflag
& CBAUD
) {
1472 switch (port
.c_ospeed
) {
1475 lpdcb
->BaudRate
= 110;
1478 lpdcb
->BaudRate
= 300;
1481 lpdcb
->BaudRate
= 600;
1484 lpdcb
->BaudRate
= 1200;
1487 lpdcb
->BaudRate
= 2400;
1490 lpdcb
->BaudRate
= 4800;
1493 lpdcb
->BaudRate
= 9600;
1496 lpdcb
->BaudRate
= 19200;
1499 lpdcb
->BaudRate
= 38400;
1503 switch (port
.c_cflag
& CSIZE
) {
1505 lpdcb
->ByteSize
= 5;
1508 lpdcb
->ByteSize
= 6;
1511 lpdcb
->ByteSize
= 7;
1514 lpdcb
->ByteSize
= 8;
1518 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
1520 lpdcb
->fParity
= NOPARITY
;
1523 lpdcb
->fParity
= EVENPARITY
;
1525 case (PARENB
| PARODD
):
1526 lpdcb
->fParity
= ODDPARITY
;
1530 if (port
.c_cflag
& CSTOPB
)
1531 lpdcb
->StopBits
= TWOSTOPBITS
;
1533 lpdcb
->StopBits
= ONESTOPBIT
;
1540 if (port
.c_cflag
& CRTSCTS
) {
1541 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1542 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1543 lpdcb
->fOutxCtsFlow
= 1;
1544 lpdcb
->fOutxDsrFlow
= 1;
1548 lpdcb
->fDtrControl
= DTR_CONTROL_DISABLE
;
1549 lpdcb
->fRtsControl
= RTS_CONTROL_DISABLE
;
1551 if (port
.c_iflag
& IXON
)
1556 if (port
.c_iflag
& IXOFF
)
1565 lpdcb
->XoffLim
= 10;
1571 /*****************************************************************************
1572 * TransmitCommChar (USER.206)
1574 INT16 WINAPI
TransmitCommChar16(INT16 fd
,CHAR chTransmit
)
1576 struct DosDeviceStruct
*ptr
;
1578 dprintf_comm(stddeb
,
1579 "TransmitCommChar: fd %d, data %d \n", fd
, chTransmit
);
1580 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1581 commerror
= IE_BADID
;
1585 if (ptr
->suspended
) {
1586 commerror
= IE_HARDWARE
;
1590 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
1591 commerror
= WinError();
1599 /*****************************************************************************
1600 * TransmitCommChar (KERNEL32.535)
1602 BOOL32 WINAPI
TransmitCommChar32(INT32 fd
,CHAR chTransmit
)
1604 struct DosDeviceStruct
*ptr
;
1606 dprintf_comm(stddeb
,"TransmitCommChar32(%d,'%c')\n",fd
,chTransmit
);
1607 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1608 commerror
= IE_BADID
;
1612 if (ptr
->suspended
) {
1613 commerror
= IE_HARDWARE
;
1616 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
1617 commerror
= WinError();
1625 /*****************************************************************************
1626 * UngetCommChar (USER.212)
1628 INT16 WINAPI
UngetCommChar(INT16 fd
,CHAR chUnget
)
1630 struct DosDeviceStruct
*ptr
;
1632 dprintf_comm(stddeb
,"UngetCommChar: fd %d (char %d)\n", fd
, chUnget
);
1633 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1634 commerror
= IE_BADID
;
1638 if (ptr
->suspended
) {
1639 commerror
= IE_HARDWARE
;
1644 ptr
->unget_byte
= chUnget
;
1649 /*****************************************************************************
1650 * ReadComm (USER.204)
1652 INT16 WINAPI
ReadComm(INT16 fd
,LPSTR lpvBuf
,INT16 cbRead
)
1654 int status
, x
, length
;
1655 struct DosDeviceStruct
*ptr
;
1657 dprintf_comm(stddeb
,
1658 "ReadComm: fd %d, ptr %p, length %d\n", fd
, lpvBuf
, cbRead
);
1659 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1660 commerror
= IE_BADID
;
1664 if (ptr
->suspended
) {
1665 commerror
= IE_HARDWARE
;
1670 *lpvBuf
= ptr
->unget_byte
;
1678 status
= read(fd
, (void *) lpvBuf
, cbRead
);
1681 if (errno
!= EAGAIN
) {
1682 commerror
= WinError();
1689 for (x
=0; x
< length
+status
; x
++)
1690 dprintf_comm(stddeb
,"%c",*(lpvBuf
+x
));
1691 dprintf_comm(stddeb
,"\nthus endeth\n");
1693 return length
+ status
;
1697 /*****************************************************************************
1698 * WriteComm (USER.205)
1700 INT16 WINAPI
WriteComm(INT16 fd
, LPSTR lpvBuf
, INT16 cbWrite
)
1703 struct DosDeviceStruct
*ptr
;
1705 dprintf_comm(stddeb
,"WriteComm: fd %d, ptr %p, length %d\n",
1706 fd
, lpvBuf
, cbWrite
);
1707 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1708 commerror
= IE_BADID
;
1712 if (ptr
->suspended
) {
1713 commerror
= IE_HARDWARE
;
1717 for (x
=0; x
!= cbWrite
; x
++)
1718 dprintf_comm(stddeb
,"%c", *(lpvBuf
+ x
) );
1719 dprintf_comm(stddeb
,"\n");
1720 length
= write(fd
, (void *) lpvBuf
, cbWrite
);
1723 commerror
= WinError();
1732 /*****************************************************************************
1733 * GetCommTimeouts (KERNEL32.160)
1735 BOOL32 WINAPI
GetCommTimeouts(INT32 fd
,LPCOMMTIMEOUTS lptimeouts
)
1737 fprintf(stderr
,"GetCommTimeouts(%x,%p), empty stub.\n",
1743 /*****************************************************************************
1744 * SetCommTimeouts (KERNEL32.453)
1746 BOOL32 WINAPI
SetCommTimeouts(INT32 fd
,LPCOMMTIMEOUTS lptimeouts
) {
1747 fprintf(stderr
,"SetCommTimeouts(%x,%p), empty stub.\n",
1753 /***********************************************************************
1754 * EnableCommNotification (USER.246)
1756 BOOL16 WINAPI
EnableCommNotification( INT16 fd
, HWND16 hwnd
,
1757 INT16 cbWriteNotify
, INT16 cbOutQueue
)
1759 fprintf(stderr
, "EnableCommNotification(%d, %x, %d, %d), empty stub.\n", fd
, hwnd
, cbWriteNotify
, cbOutQueue
);