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