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>
40 #define TIOCINQ FIONREAD
42 #define msr 35 /* offset in unknown structure commMask */
44 * [RER] These are globals are wrong. They should be in DosDeviceStruct
45 * on a per port basis.
47 int commerror
= 0, eventmask
= 0;
49 struct DosDeviceStruct COM
[MAX_PORTS
];
50 struct DosDeviceStruct LPT
[MAX_PORTS
];
51 LPCVOID
*unknown
[MAX_PORTS
];
56 char option
[10], temp
[256], *btemp
;
59 for (x
=0; x
!=MAX_PORTS
; x
++) {
60 strcpy(option
,"COMx");
64 PROFILE_GetWineIniString( "serialports", option
, "*",
66 if (!strcmp(temp
, "*") || *temp
== '\0')
67 COM
[x
].devicename
= NULL
;
69 btemp
= strchr(temp
,',');
72 COM
[x
].baudrate
= atoi(btemp
);
77 if (!S_ISCHR(st
.st_mode
))
78 fprintf(stderr
,"comm: can't use `%s' as %s !\n", temp
, option
);
80 if ((COM
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
81 fprintf(stderr
,"comm: can't malloc for device info!\n");
84 strcpy(COM
[x
].devicename
, temp
);
87 "Comm_Init: %s = %s\n", option
, COM
[x
].devicename
);
90 strcpy(option
, "LPTx");
94 PROFILE_GetWineIniString( "parallelports", option
, "*",
96 if (!strcmp(temp
, "*") || *temp
== '\0')
97 LPT
[x
].devicename
= NULL
;
100 if (!S_ISCHR(st
.st_mode
))
101 fprintf(stderr
,"comm: can't use `%s' as %s !\n", temp
, option
);
103 if ((LPT
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
104 fprintf(stderr
,"comm: can't malloc for device info!\n");
107 strcpy(LPT
[x
].devicename
, temp
);
110 "Comm_Init: %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 dprintf_info(comm
, "WinError: 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];
173 "BuildCommDCB: (%s), ptr %p\n", device
, lpdcb
);
176 if (!lstrncmpi32A(device
,"COM",3)) {
177 port
= device
[3] - '0';
181 fprintf(stderr
, "comm: BUG ! COM0 can't exists!.\n");
182 commerror
= IE_BADID
;
185 if (!ValidCOMPort(port
)) {
186 commerror
= IE_BADID
;
190 memset(lpdcb
, 0, sizeof(DCB16
)); /* initialize */
193 OpenComm(device
, 0, 0);
195 lpdcb
->Id
= COM
[port
].fd
;
200 if (*(device
+4) != ':')
203 strcpy(temp
,device
+5);
204 ptr
= strtok(temp
, ", ");
206 if (COM
[port
].baudrate
> 0)
207 lpdcb
->BaudRate
= COM
[port
].baudrate
;
209 lpdcb
->BaudRate
= atoi(ptr
);
210 dprintf_info(comm
,"BuildCommDCB: baudrate (%d)\n", lpdcb
->BaudRate
);
212 ptr
= strtok(NULL
, ", ");
214 *ptr
= toupper(*ptr
);
216 dprintf_info(comm
,"BuildCommDCB: parity (%c)\n", *ptr
);
220 lpdcb
->Parity
= NOPARITY
;
224 lpdcb
->Parity
= EVENPARITY
;
227 lpdcb
->Parity
= MARKPARITY
;
230 lpdcb
->Parity
= ODDPARITY
;
233 fprintf(stderr
,"comm: unknown parity `%c'!\n", *ptr
);
237 ptr
= strtok(NULL
, ", ");
238 dprintf_info(comm
, "BuildCommDCB: charsize (%c)\n", *ptr
);
239 lpdcb
->ByteSize
= *ptr
- '0';
241 ptr
= strtok(NULL
, ", ");
242 dprintf_info(comm
, "BuildCommDCB: stopbits (%c)\n", *ptr
);
245 lpdcb
->StopBits
= ONESTOPBIT
;
248 lpdcb
->StopBits
= TWOSTOPBITS
;
251 fprintf(stderr
,"comm: unknown # of stopbits `%c'!\n", *ptr
);
259 /**************************************************************************
260 * BuildCommDCBA (KERNEL32.14)
262 BOOL32 WINAPI
BuildCommDCB32A(LPCSTR device
,LPDCB32 lpdcb
)
264 return BuildCommDCBAndTimeouts32A(device
,lpdcb
,NULL
);
267 /**************************************************************************
268 * BuildCommDCBAndTimeoutsA (KERNEL32.15)
270 BOOL32 WINAPI
BuildCommDCBAndTimeouts32A(LPCSTR device
, LPDCB32 lpdcb
,
271 LPCOMMTIMEOUTS lptimeouts
)
276 dprintf_info(comm
,"BuildCommDCBAndTimeouts32A(%s,%p,%p)\n",device
,lpdcb
,lptimeouts
);
279 if (!lstrncmpi32A(device
,"COM",3)) {
282 fprintf(stderr
,"comm:BUG! COM0 can't exists!.\n");
285 if (!ValidCOMPort(port
))
287 if (*(device
+4)!=':')
289 temp
=(LPSTR
)(device
+5);
293 memset(lpdcb
, 0, sizeof(DCB32
)); /* initialize */
295 lpdcb
->DCBlength
= sizeof(DCB32
);
296 if (strchr(temp
,',')) { /* old style */
299 char last
=temp
[strlen(temp
)-1];
301 ret
=BuildCommDCB16(device
,&dcb16
);
304 lpdcb
->BaudRate
= dcb16
.BaudRate
;
305 lpdcb
->ByteSize
= dcb16
.ByteSize
;
306 lpdcb
->fBinary
= dcb16
.fBinary
;
307 lpdcb
->Parity
= dcb16
.Parity
;
308 lpdcb
->fParity
= dcb16
.fParity
;
309 lpdcb
->fNull
= dcb16
.fNull
;
310 lpdcb
->StopBits
= dcb16
.StopBits
;
314 lpdcb
->fOutxCtsFlow
= FALSE
;
315 lpdcb
->fOutxDsrFlow
= FALSE
;
316 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
317 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
318 } else if (last
=='p') {
320 lpdcb
->fOutX
= FALSE
;
321 lpdcb
->fOutxCtsFlow
= TRUE
;
322 lpdcb
->fOutxDsrFlow
= TRUE
;
323 lpdcb
->fDtrControl
= DTR_CONTROL_HANDSHAKE
;
324 lpdcb
->fRtsControl
= RTS_CONTROL_HANDSHAKE
;
327 lpdcb
->fOutX
= FALSE
;
328 lpdcb
->fOutxCtsFlow
= FALSE
;
329 lpdcb
->fOutxDsrFlow
= FALSE
;
330 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
331 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
333 lpdcb
->XonChar
= dcb16
.XonChar
;
334 lpdcb
->XoffChar
= dcb16
.XoffChar
;
335 lpdcb
->ErrorChar
= dcb16
.PeChar
;
336 lpdcb
->fErrorChar
= dcb16
.fPeChar
;
337 lpdcb
->EofChar
= dcb16
.EofChar
;
338 lpdcb
->EvtChar
= dcb16
.EvtChar
;
339 lpdcb
->XonLim
= dcb16
.XonLim
;
340 lpdcb
->XoffLim
= dcb16
.XoffLim
;
343 ptr
=strtok(temp
," ");
348 if (!strncmp("baud=",ptr
,5)) {
349 if (!sscanf(ptr
+5,"%ld",&x
))
350 fprintf(stderr
,"BuildCommDCB32A:Couldn't parse %s\n",ptr
);
354 if (!strncmp("stop=",ptr
,5)) {
355 if (!sscanf(ptr
+5,"%ld",&x
))
356 fprintf(stderr
,"BuildCommDCB32A:Couldn't parse %s\n",ptr
);
360 if (!strncmp("data=",ptr
,5)) {
361 if (!sscanf(ptr
+5,"%ld",&x
))
362 fprintf(stderr
,"BuildCommDCB32A:Couldn't parse %s\n",ptr
);
366 if (!strncmp("parity=",ptr
,7)) {
367 lpdcb
->fParity
= TRUE
;
370 lpdcb
->fParity
= FALSE
;
371 lpdcb
->Parity
= NOPARITY
;
374 lpdcb
->Parity
= EVENPARITY
;
377 lpdcb
->Parity
= ODDPARITY
;
380 lpdcb
->Parity
= MARKPARITY
;
386 fprintf(stderr
,"BuildCommDCB32A: Unhandled specifier '%s', please report.\n",ptr
);
387 ptr
=strtok(NULL
," ");
389 if (lpdcb
->BaudRate
==110)
394 /**************************************************************************
395 * BuildCommDCBAndTimeoutsW (KERNEL32.16)
397 BOOL32 WINAPI
BuildCommDCBAndTimeouts32W( LPCWSTR devid
, LPDCB32 lpdcb
,
398 LPCOMMTIMEOUTS lptimeouts
)
403 dprintf_info(comm
,"BuildCommDCBAndTimeouts32W(%p,%p,%p)\n",devid
,lpdcb
,lptimeouts
);
404 devidA
= HEAP_strdupWtoA( GetProcessHeap(), 0, devid
);
405 ret
=BuildCommDCBAndTimeouts32A(devidA
,lpdcb
,lptimeouts
);
406 HeapFree( GetProcessHeap(), 0, devidA
);
410 /**************************************************************************
411 * BuildCommDCBW (KERNEL32.17)
413 BOOL32 WINAPI
BuildCommDCB32W(LPCWSTR devid
,LPDCB32 lpdcb
)
415 return BuildCommDCBAndTimeouts32W(devid
,lpdcb
,NULL
);
418 /*****************************************************************************
419 * OpenComm (USER.200)
421 INT16 WINAPI
OpenComm(LPCSTR device
,UINT16 cbInQueue
,UINT16 cbOutQueue
)
426 "OpenComm: %s, %d, %d\n", device
, cbInQueue
, cbOutQueue
);
429 if (!lstrncmpi32A(device
,"COM",3)) {
430 port
= device
[3] - '0';
433 fprintf(stderr
, "comm: BUG ! COM0 doesn't exist !\n");
434 commerror
= IE_BADID
;
438 "OpenComm: %s = %s\n", device
, COM
[port
].devicename
);
440 if (!ValidCOMPort(port
)) {
441 commerror
= IE_BADID
;
448 fd
= open(COM
[port
].devicename
, O_RDWR
| O_NONBLOCK
);
450 commerror
= WinError();
453 unknown
[port
] = SEGPTR_ALLOC(40);
454 bzero(unknown
[port
],40);
460 if (!lstrncmpi32A(device
,"LPT",3)) {
461 port
= device
[3] - '0';
463 if (!ValidLPTPort(port
)) {
464 commerror
= IE_BADID
;
472 fd
= open(LPT
[port
].devicename
, O_RDWR
| O_NONBLOCK
, 0);
474 commerror
= WinError();
484 /*****************************************************************************
485 * CloseComm (USER.207)
487 INT16 WINAPI
CloseComm(INT16 fd
)
490 dprintf_info(comm
,"CloseComm: fd %d\n", fd
);
491 if ((port
= GetCommPort(fd
)) !=-1) { /* [LW] */
492 SEGPTR_FREE(unknown
[port
]);
493 COM
[port
].fd
= 0; /* my adaptation of RER's fix */
495 commerror
= IE_BADID
;
499 if (close(fd
) == -1) {
500 commerror
= WinError();
508 /*****************************************************************************
509 * SetCommBreak (USER.210)
511 INT16 WINAPI
SetCommBreak16(INT16 fd
)
513 struct DosDeviceStruct
*ptr
;
515 dprintf_info(comm
,"SetCommBreak: fd: %d\n", fd
);
516 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
517 commerror
= IE_BADID
;
526 /*****************************************************************************
527 * SetCommBreak (KERNEL32.449)
529 BOOL32 WINAPI
SetCommBreak32(INT32 fd
)
532 struct DosDeviceStruct
*ptr
;
534 dprintf_info(comm
,"SetCommBreak: fd: %d\n", fd
);
535 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
536 commerror
= IE_BADID
;
545 /*****************************************************************************
546 * ClearCommBreak (USER.211)
548 INT16 WINAPI
ClearCommBreak16(INT16 fd
)
550 struct DosDeviceStruct
*ptr
;
552 dprintf_info(comm
,"ClearCommBreak: fd: %d\n", fd
);
553 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
554 commerror
= IE_BADID
;
563 /*****************************************************************************
564 * ClearCommBreak (KERNEL32.20)
566 BOOL32 WINAPI
ClearCommBreak32(INT32 fd
)
568 struct DosDeviceStruct
*ptr
;
570 dprintf_info(comm
,"ClearCommBreak: fd: %d\n", fd
);
571 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
572 commerror
= IE_BADID
;
581 /*****************************************************************************
582 * EscapeCommFunction (USER.214)
584 LONG WINAPI
EscapeCommFunction16(UINT16 fd
,UINT16 nFunction
)
589 dprintf_info(comm
,"EscapeCommFunction fd: %d, function: %d\n", fd
, nFunction
);
590 if (tcgetattr(fd
,&port
) == -1) {
591 commerror
=WinError();
600 for (max
= MAX_PORTS
;!COM
[max
].devicename
;max
--)
606 for (max
= MAX_PORTS
;!LPT
[max
].devicename
;max
--)
613 port
.c_cflag
&= TIOCM_DTR
;
619 port
.c_cflag
&= TIOCM_RTS
;
625 port
.c_cflag
|= CRTSCTS
;
629 port
.c_cflag
|= CRTSCTS
;
634 port
.c_iflag
|= IXOFF
;
638 port
.c_iflag
|= IXON
;
643 "EscapeCommFunction fd: %d, unknown function: %d\n",
648 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
649 commerror
= WinError();
657 /*****************************************************************************
658 * EscapeCommFunction (KERNEL32.214)
660 BOOL32 WINAPI
EscapeCommFunction32(INT32 fd
,UINT32 nFunction
)
663 struct DosDeviceStruct
*ptr
;
665 dprintf_info(comm
,"EscapeCommFunction fd: %d, function: %d\n", fd
, nFunction
);
666 if (tcgetattr(fd
,&port
) == -1) {
667 commerror
=WinError();
670 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
671 commerror
= IE_BADID
;
681 port
.c_cflag
&= TIOCM_DTR
;
687 port
.c_cflag
&= TIOCM_RTS
;
693 port
.c_cflag
|= CRTSCTS
;
697 port
.c_cflag
|= CRTSCTS
;
702 port
.c_iflag
|= IXOFF
;
706 port
.c_iflag
|= IXON
;
716 "EscapeCommFunction32 fd: %d, unknown function: %d\n",
721 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
722 commerror
= WinError();
730 /*****************************************************************************
731 * FlushComm (USER.215)
733 INT16 WINAPI
FlushComm(INT16 fd
,INT16 fnQueue
)
737 dprintf_info(comm
,"FlushComm fd: %d, queue: %d\n", fd
, fnQueue
);
739 case 0: queue
= TCOFLUSH
;
741 case 1: queue
= TCIFLUSH
;
743 default:fprintf(stderr
,
744 "FlushComm fd: %d, UNKNOWN queue: %d\n",
748 if (tcflush(fd
, queue
)) {
749 commerror
= WinError();
757 /********************************************************************
758 * PurgeComm (KERNEL32.557)
760 BOOL32 WINAPI
PurgeComm( HANDLE32 hFile
, DWORD flags
)
762 dprintf_fixme(comm
, "PurgeComm(%08x %08lx) unimplemented stub\n",
767 /********************************************************************
768 * GetCommError (USER.203)
770 INT16 WINAPI
GetCommError(INT16 fd
,LPCOMSTAT lpStat
)
779 rc
= ioctl(fd
, TIOCOUTQ
, &cnt
);
780 if (rc
) fprintf(stderr
, "Error !\n");
781 lpStat
->cbOutQue
= cnt
;
783 rc
= ioctl(fd
, TIOCINQ
, &cnt
);
784 if (rc
) fprintf(stderr
, "Error !\n");
785 lpStat
->cbInQue
= cnt
;
788 "GetCommError: fd %d, error %d, lpStat %d %d %d\n",
789 fd
, commerror
, lpStat
->status
, lpStat
->cbInQue
,
794 "GetCommError: fd %d, error %d, lpStat NULL\n",
798 * [RER] I have no idea what the following is trying to accomplish.
799 * [RER] It is certainly not what the reference manual suggests.
801 temperror
= commerror
;
806 /*****************************************************************************
807 * ClearCommError (KERNEL32.21)
809 BOOL32 WINAPI
ClearCommError(INT32 fd
,LPDWORD errors
,LPCOMSTAT lpStat
)
813 dprintf_info(comm
, "ClearCommError: fd %d (current error %d)\n",
815 temperror
= commerror
;
820 /*****************************************************************************
821 * SetCommEventMask (USER.208)
823 SEGPTR WINAPI
SetCommEventMask(INT16 fd
,UINT16 fuEvtMask
)
829 dprintf_info(comm
,"SetCommEventMask:fd %d,mask %d\n",fd
,fuEvtMask
);
830 eventmask
|= fuEvtMask
;
831 if ((act
= GetCommPort(fd
)) == -1) {
832 dprintf_warn(comm
," fd %d not comm port\n",act
);
836 repid
= ioctl(fd
,TIOCMGET
,&mstat
);
837 dprintf_info(comm
, " ioctl %d, msr %x at %p %p\n",repid
,mstat
,stol
,unknown
[act
]);
838 if ((mstat
&TIOCM_CAR
)) {*stol
|= 0x80;}
840 dprintf_info(comm
," modem dcd construct %x\n",*stol
);
841 return SEGPTR_GET(unknown
[act
]);
844 /*****************************************************************************
845 * GetCommEventMask (USER.209)
847 UINT16 WINAPI
GetCommEventMask(INT16 fd
,UINT16 fnEvtClear
)
852 "GetCommEventMask: fd %d, mask %d\n", fd
, fnEvtClear
);
855 * Determine if any characters are available
857 if (fnEvtClear
& EV_RXCHAR
)
862 rc
= ioctl(fd
, TIOCINQ
, &cnt
);
863 if (cnt
) events
|= EV_RXCHAR
;
866 "GetCommEventMask: rxchar %ld\n", cnt
);
870 * There are other events that need to be checked for
875 "GetCommEventMask: return events %d\n", events
);
879 * [RER] The following was gibberish
882 tempmask
= eventmask
;
883 eventmask
&= ~fnEvtClear
;
888 /*****************************************************************************
889 * SetupComm (KERNEL32.676)
891 BOOL32 WINAPI
SetupComm( HANDLE32 hFile
, DWORD insize
, DWORD outsize
)
893 dprintf_fixme(comm
, "SetupComm: insize %ld outsize %ld unimplemented stub\n", insize
, outsize
);
897 /*****************************************************************************
898 * GetCommMask (KERNEL32.156)
900 BOOL32 WINAPI
GetCommMask(INT32 fd
,LPDWORD evtmask
)
903 "GetCommMask: fd %d, mask %p\n", fd
, evtmask
);
904 *evtmask
= eventmask
;
908 /*****************************************************************************
909 * SetCommMask (KERNEL32.451)
911 BOOL32 WINAPI
SetCommMask(INT32 fd
,DWORD evtmask
)
914 "SetCommMask: fd %d, mask %lx\n", fd
, evtmask
);
919 /*****************************************************************************
920 * SetCommState16 (USER.201)
922 INT16 WINAPI
SetCommState16(LPDCB16 lpdcb
)
925 struct DosDeviceStruct
*ptr
;
928 "SetCommState16: fd %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
929 if (tcgetattr(lpdcb
->Id
, &port
) == -1) {
930 commerror
= WinError();
935 port
.c_cc
[VTIME
] = 1;
938 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
940 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
942 port
.c_iflag
|= (IGNBRK
);
944 port
.c_oflag
&= ~(OPOST
);
946 port
.c_cflag
&= ~(HUPCL
);
947 port
.c_cflag
|= CLOCAL
| CREAD
;
949 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
950 port
.c_lflag
|= NOFLSH
;
952 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
953 commerror
= IE_BADID
;
956 if (ptr
->baudrate
> 0)
957 lpdcb
->BaudRate
= ptr
->baudrate
;
958 dprintf_info(comm
,"SetCommState: baudrate %d\n",lpdcb
->BaudRate
);
960 port
.c_cflag
&= ~CBAUD
;
961 switch (lpdcb
->BaudRate
) {
964 port
.c_cflag
|= B110
;
968 port
.c_cflag
|= B300
;
972 port
.c_cflag
|= B600
;
976 port
.c_cflag
|= B1200
;
980 port
.c_cflag
|= B2400
;
984 port
.c_cflag
|= B4800
;
988 port
.c_cflag
|= B9600
;
992 port
.c_cflag
|= B19200
;
996 port
.c_cflag
|= B38400
;
999 port
.c_cflag
|= B57600
;
1002 port
.c_cflag
|= B115200
;
1005 commerror
= IE_BAUDRATE
;
1008 #elif !defined(__EMX__)
1009 switch (lpdcb
->BaudRate
) {
1012 port
.c_ospeed
= B110
;
1016 port
.c_ospeed
= B300
;
1020 port
.c_ospeed
= B600
;
1024 port
.c_ospeed
= B1200
;
1028 port
.c_ospeed
= B2400
;
1032 port
.c_ospeed
= B4800
;
1036 port
.c_ospeed
= B9600
;
1040 port
.c_ospeed
= B19200
;
1044 port
.c_ospeed
= B38400
;
1047 commerror
= IE_BAUDRATE
;
1050 port
.c_ispeed
= port
.c_ospeed
;
1052 dprintf_info(comm
,"SetCommState: bytesize %d\n",lpdcb
->ByteSize
);
1053 port
.c_cflag
&= ~CSIZE
;
1054 switch (lpdcb
->ByteSize
) {
1056 port
.c_cflag
|= CS5
;
1059 port
.c_cflag
|= CS6
;
1062 port
.c_cflag
|= CS7
;
1065 port
.c_cflag
|= CS8
;
1068 commerror
= IE_BYTESIZE
;
1072 dprintf_info(comm
,"SetCommState: parity %d\n",lpdcb
->Parity
);
1073 port
.c_cflag
&= ~(PARENB
| PARODD
);
1075 switch (lpdcb
->Parity
) {
1077 port
.c_iflag
&= ~INPCK
;
1080 port
.c_cflag
|= (PARENB
| PARODD
);
1081 port
.c_iflag
|= INPCK
;
1084 port
.c_cflag
|= PARENB
;
1085 port
.c_iflag
|= INPCK
;
1088 commerror
= IE_BYTESIZE
;
1093 dprintf_info(comm
,"SetCommState: stopbits %d\n",lpdcb
->StopBits
);
1095 switch (lpdcb
->StopBits
) {
1097 port
.c_cflag
&= ~CSTOPB
;
1100 port
.c_cflag
|= CSTOPB
;
1103 commerror
= IE_BYTESIZE
;
1108 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
1109 port
.c_cflag
|= CRTSCTS
;
1111 if (lpdcb
->fDtrDisable
)
1112 port
.c_cflag
&= ~CRTSCTS
;
1115 port
.c_iflag
|= IXON
;
1117 port
.c_iflag
&= ~IXON
;
1119 port
.c_iflag
|= IXOFF
;
1121 port
.c_iflag
&= ~IXOFF
;
1123 if (tcsetattr(lpdcb
->Id
, TCSADRAIN
, &port
) == -1) {
1124 commerror
= WinError();
1132 /*****************************************************************************
1133 * SetCommState32 (KERNEL32.452)
1135 BOOL32 WINAPI
SetCommState32(INT32 fd
,LPDCB32 lpdcb
)
1137 struct termios port
;
1138 struct DosDeviceStruct
*ptr
;
1140 dprintf_info(comm
,"SetCommState32: fd %d, ptr %p\n",fd
,lpdcb
);
1141 if (tcgetattr(fd
,&port
) == -1) {
1142 commerror
= WinError();
1146 port
.c_cc
[VMIN
] = 0;
1147 port
.c_cc
[VTIME
] = 1;
1150 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
1152 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
1154 port
.c_iflag
|= (IGNBRK
);
1156 port
.c_oflag
&= ~(OPOST
);
1158 port
.c_cflag
&= ~(HUPCL
);
1159 port
.c_cflag
|= CLOCAL
| CREAD
;
1161 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
1162 port
.c_lflag
|= NOFLSH
;
1164 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1165 commerror
= IE_BADID
;
1168 if (ptr
->baudrate
> 0)
1169 lpdcb
->BaudRate
= ptr
->baudrate
;
1170 dprintf_info(comm
,"SetCommState: baudrate %ld\n",lpdcb
->BaudRate
);
1172 port
.c_cflag
&= ~CBAUD
;
1173 switch (lpdcb
->BaudRate
) {
1176 port
.c_cflag
|= B110
;
1180 port
.c_cflag
|= B300
;
1184 port
.c_cflag
|= B600
;
1188 port
.c_cflag
|= B1200
;
1192 port
.c_cflag
|= B2400
;
1196 port
.c_cflag
|= B4800
;
1200 port
.c_cflag
|= B9600
;
1204 port
.c_cflag
|= B19200
;
1208 port
.c_cflag
|= B38400
;
1211 commerror
= IE_BAUDRATE
;
1214 #elif !defined(__EMX__)
1215 switch (lpdcb
->BaudRate
) {
1218 port
.c_ospeed
= B110
;
1222 port
.c_ospeed
= B300
;
1226 port
.c_ospeed
= B600
;
1230 port
.c_ospeed
= B1200
;
1234 port
.c_ospeed
= B2400
;
1238 port
.c_ospeed
= B4800
;
1242 port
.c_ospeed
= B9600
;
1246 port
.c_ospeed
= B19200
;
1250 port
.c_ospeed
= B38400
;
1253 commerror
= IE_BAUDRATE
;
1256 port
.c_ispeed
= port
.c_ospeed
;
1258 dprintf_info(comm
,"SetCommState: bytesize %d\n",lpdcb
->ByteSize
);
1259 port
.c_cflag
&= ~CSIZE
;
1260 switch (lpdcb
->ByteSize
) {
1262 port
.c_cflag
|= CS5
;
1265 port
.c_cflag
|= CS6
;
1268 port
.c_cflag
|= CS7
;
1271 port
.c_cflag
|= CS8
;
1274 commerror
= IE_BYTESIZE
;
1278 dprintf_info(comm
,"SetCommState: parity %d\n",lpdcb
->Parity
);
1279 port
.c_cflag
&= ~(PARENB
| PARODD
);
1281 switch (lpdcb
->Parity
) {
1283 port
.c_iflag
&= ~INPCK
;
1286 port
.c_cflag
|= (PARENB
| PARODD
);
1287 port
.c_iflag
|= INPCK
;
1290 port
.c_cflag
|= PARENB
;
1291 port
.c_iflag
|= INPCK
;
1294 commerror
= IE_BYTESIZE
;
1299 dprintf_info(comm
,"SetCommState: stopbits %d\n",lpdcb
->StopBits
);
1300 switch (lpdcb
->StopBits
) {
1302 port
.c_cflag
&= ~CSTOPB
;
1305 port
.c_cflag
|= CSTOPB
;
1308 commerror
= IE_BYTESIZE
;
1312 if ( lpdcb
->fOutxCtsFlow
||
1313 lpdcb
->fDtrControl
== DTR_CONTROL_ENABLE
||
1314 lpdcb
->fRtsControl
== RTS_CONTROL_ENABLE
1316 port
.c_cflag
|= CRTSCTS
;
1317 if (lpdcb
->fDtrControl
== DTR_CONTROL_DISABLE
)
1318 port
.c_cflag
&= ~CRTSCTS
;
1322 port
.c_iflag
|= IXON
;
1324 port
.c_iflag
&= ~IXON
;
1326 port
.c_iflag
|= IXOFF
;
1328 port
.c_iflag
&= ~IXOFF
;
1330 if (tcsetattr(fd
,TCSADRAIN
,&port
)==-1) {
1331 commerror
= WinError();
1340 /*****************************************************************************
1341 * GetCommState (USER.202)
1343 INT16 WINAPI
GetCommState16(INT16 fd
, LPDCB16 lpdcb
)
1345 struct termios port
;
1347 dprintf_info(comm
,"GetCommState16: fd %d, ptr %p\n", fd
, lpdcb
);
1348 if (tcgetattr(fd
, &port
) == -1) {
1349 commerror
= WinError();
1355 switch (port
.c_cflag
& CBAUD
) {
1357 switch (port
.c_ospeed
) {
1360 lpdcb
->BaudRate
= 110;
1363 lpdcb
->BaudRate
= 300;
1366 lpdcb
->BaudRate
= 600;
1369 lpdcb
->BaudRate
= 1200;
1372 lpdcb
->BaudRate
= 2400;
1375 lpdcb
->BaudRate
= 4800;
1378 lpdcb
->BaudRate
= 9600;
1381 lpdcb
->BaudRate
= 19200;
1384 lpdcb
->BaudRate
= 38400;
1387 lpdcb
->BaudRate
= 57600;
1390 lpdcb
->BaudRate
= 57601;
1394 switch (port
.c_cflag
& CSIZE
) {
1396 lpdcb
->ByteSize
= 5;
1399 lpdcb
->ByteSize
= 6;
1402 lpdcb
->ByteSize
= 7;
1405 lpdcb
->ByteSize
= 8;
1409 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
1411 lpdcb
->fParity
= NOPARITY
;
1414 lpdcb
->fParity
= EVENPARITY
;
1416 case (PARENB
| PARODD
):
1417 lpdcb
->fParity
= ODDPARITY
;
1421 if (port
.c_cflag
& CSTOPB
)
1422 lpdcb
->StopBits
= TWOSTOPBITS
;
1424 lpdcb
->StopBits
= ONESTOPBIT
;
1426 lpdcb
->RlsTimeout
= 50;
1427 lpdcb
->CtsTimeout
= 50;
1428 lpdcb
->DsrTimeout
= 50;
1432 lpdcb
->fDtrDisable
= 0;
1436 if (port
.c_cflag
& CRTSCTS
) {
1437 lpdcb
->fDtrflow
= 1;
1438 lpdcb
->fRtsflow
= 1;
1439 lpdcb
->fOutxCtsFlow
= 1;
1440 lpdcb
->fOutxDsrFlow
= 1;
1443 lpdcb
->fDtrDisable
= 1;
1445 if (port
.c_iflag
& IXON
)
1450 if (port
.c_iflag
& IXOFF
)
1459 lpdcb
->XoffLim
= 10;
1465 /*****************************************************************************
1466 * GetCommState (KERNEL32.159)
1468 BOOL32 WINAPI
GetCommState32(INT32 fd
, LPDCB32 lpdcb
)
1470 struct termios port
;
1472 dprintf_info(comm
,"GetCommState32: fd %d, ptr %p\n", fd
, lpdcb
);
1473 if (GetDeviceStruct(fd
) == NULL
) return FALSE
;
1474 if (tcgetattr(fd
, &port
) == -1) {
1475 commerror
= WinError();
1480 switch (port
.c_cflag
& CBAUD
) {
1482 switch (port
.c_ospeed
) {
1485 lpdcb
->BaudRate
= 110;
1488 lpdcb
->BaudRate
= 300;
1491 lpdcb
->BaudRate
= 600;
1494 lpdcb
->BaudRate
= 1200;
1497 lpdcb
->BaudRate
= 2400;
1500 lpdcb
->BaudRate
= 4800;
1503 lpdcb
->BaudRate
= 9600;
1506 lpdcb
->BaudRate
= 19200;
1509 lpdcb
->BaudRate
= 38400;
1513 switch (port
.c_cflag
& CSIZE
) {
1515 lpdcb
->ByteSize
= 5;
1518 lpdcb
->ByteSize
= 6;
1521 lpdcb
->ByteSize
= 7;
1524 lpdcb
->ByteSize
= 8;
1528 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
1530 lpdcb
->fParity
= NOPARITY
;
1533 lpdcb
->fParity
= EVENPARITY
;
1535 case (PARENB
| PARODD
):
1536 lpdcb
->fParity
= ODDPARITY
;
1540 if (port
.c_cflag
& CSTOPB
)
1541 lpdcb
->StopBits
= TWOSTOPBITS
;
1543 lpdcb
->StopBits
= ONESTOPBIT
;
1550 if (port
.c_cflag
& CRTSCTS
) {
1551 lpdcb
->fDtrControl
= DTR_CONTROL_ENABLE
;
1552 lpdcb
->fRtsControl
= RTS_CONTROL_ENABLE
;
1553 lpdcb
->fOutxCtsFlow
= 1;
1554 lpdcb
->fOutxDsrFlow
= 1;
1558 lpdcb
->fDtrControl
= DTR_CONTROL_DISABLE
;
1559 lpdcb
->fRtsControl
= RTS_CONTROL_DISABLE
;
1561 if (port
.c_iflag
& IXON
)
1566 if (port
.c_iflag
& IXOFF
)
1575 lpdcb
->XoffLim
= 10;
1581 /*****************************************************************************
1582 * TransmitCommChar (USER.206)
1584 INT16 WINAPI
TransmitCommChar16(INT16 fd
,CHAR chTransmit
)
1586 struct DosDeviceStruct
*ptr
;
1589 "TransmitCommChar: fd %d, data %d \n", fd
, chTransmit
);
1590 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1591 commerror
= IE_BADID
;
1595 if (ptr
->suspended
) {
1596 commerror
= IE_HARDWARE
;
1600 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
1601 commerror
= WinError();
1609 /*****************************************************************************
1610 * TransmitCommChar (KERNEL32.535)
1612 BOOL32 WINAPI
TransmitCommChar32(INT32 fd
,CHAR chTransmit
)
1614 struct DosDeviceStruct
*ptr
;
1616 dprintf_info(comm
,"TransmitCommChar32(%d,'%c')\n",fd
,chTransmit
);
1617 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1618 commerror
= IE_BADID
;
1622 if (ptr
->suspended
) {
1623 commerror
= IE_HARDWARE
;
1626 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
1627 commerror
= WinError();
1635 /*****************************************************************************
1636 * UngetCommChar (USER.212)
1638 INT16 WINAPI
UngetCommChar(INT16 fd
,CHAR chUnget
)
1640 struct DosDeviceStruct
*ptr
;
1642 dprintf_info(comm
,"UngetCommChar: fd %d (char %d)\n", fd
, chUnget
);
1643 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1644 commerror
= IE_BADID
;
1648 if (ptr
->suspended
) {
1649 commerror
= IE_HARDWARE
;
1654 ptr
->unget_byte
= chUnget
;
1659 /*****************************************************************************
1660 * ReadComm (USER.204)
1662 INT16 WINAPI
ReadComm(INT16 fd
,LPSTR lpvBuf
,INT16 cbRead
)
1665 struct DosDeviceStruct
*ptr
;
1668 "ReadComm: fd %d, ptr %p, length %d\n", fd
, lpvBuf
, cbRead
);
1669 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1670 commerror
= IE_BADID
;
1674 if (ptr
->suspended
) {
1675 commerror
= IE_HARDWARE
;
1680 *lpvBuf
= ptr
->unget_byte
;
1688 status
= read(fd
, (void *) lpvBuf
, cbRead
);
1691 if (errno
!= EAGAIN
) {
1692 commerror
= WinError();
1699 dprintf_info(comm
,"%*s\n", length
+status
, lpvBuf
);
1701 return length
+ status
;
1705 /*****************************************************************************
1706 * WriteComm (USER.205)
1708 INT16 WINAPI
WriteComm(INT16 fd
, LPSTR lpvBuf
, INT16 cbWrite
)
1711 struct DosDeviceStruct
*ptr
;
1713 dprintf_info(comm
,"WriteComm: fd %d, ptr %p, length %d\n",
1714 fd
, lpvBuf
, cbWrite
);
1715 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
1716 commerror
= IE_BADID
;
1720 if (ptr
->suspended
) {
1721 commerror
= IE_HARDWARE
;
1725 dprintf_info(comm
,"%*s\n", cbWrite
, lpvBuf
);
1726 length
= write(fd
, (void *) lpvBuf
, cbWrite
);
1729 commerror
= WinError();
1738 /*****************************************************************************
1739 * GetCommTimeouts (KERNEL32.160)
1741 BOOL32 WINAPI
GetCommTimeouts(INT32 fd
,LPCOMMTIMEOUTS lptimeouts
)
1743 fprintf(stderr
,"GetCommTimeouts(%x,%p), empty stub.\n",
1749 /*****************************************************************************
1750 * SetCommTimeouts (KERNEL32.453)
1752 BOOL32 WINAPI
SetCommTimeouts(INT32 fd
,LPCOMMTIMEOUTS lptimeouts
) {
1753 fprintf(stderr
,"SetCommTimeouts(%x,%p), empty stub.\n",
1759 /***********************************************************************
1760 * EnableCommNotification (USER.246)
1762 BOOL16 WINAPI
EnableCommNotification( INT16 fd
, HWND16 hwnd
,
1763 INT16 cbWriteNotify
, INT16 cbOutQueue
)
1765 fprintf(stderr
, "EnableCommNotification(%d, %x, %d, %d), empty stub.\n", fd
, hwnd
, cbWriteNotify
, cbOutQueue
);