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);