DTR/RTS fixes in {G|S}etCommState: take 2
Rein Klazes
rklazes at xs4all.nl
Mon Apr 12 03:03:35 CDT 2004
Hi,
Mike McCormack noted that it is better to change the control lines after
setting the comm attributes, so flow control does not interfere.
Changelog:
dlls/kernel : comm.c
Fix GetCommState and SetCommState, so that these functions
can be used to set/clear/read the DTR and RTS lines
Rein.
--
Rein Klazes
rklazes at xs4all.nl
-------------- next part --------------
--- wine/dlls/kernel/comm.c 2004-01-16 03:21:01.000000000 +0100
+++ mywine/dlls/kernel/comm.c 2004-04-12 09:49:27.000000000 +0200
@@ -1084,6 +1084,7 @@
{
struct termios port;
int fd, bytesize, stopbits;
+ BOOL ret;
TRACE("handle %p, ptr %p\n", handle, lpdcb);
TRACE("bytesize %d baudrate %ld fParity %d Parity %d stopbits %d\n",
@@ -1092,6 +1093,11 @@
(lpdcb->StopBits == TWOSTOPBITS)?2:0);
TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
(lpdcb->fOutX)?"IXOFF":"~IXOFF");
+ TRACE("fOutxCtsFlow %d fRtsControl %d\n", lpdcb->fOutxCtsFlow,
+ lpdcb->fRtsControl);
+ TRACE("fOutxDsrFlow %d fDtrControl%d\n", lpdcb->fOutxDsrFlow,
+ lpdcb->fDtrControl);
+
fd = get_comm_fd( handle, GENERIC_READ );
if (fd < 0) return FALSE;
@@ -1385,11 +1391,6 @@
}
#endif
- if (lpdcb->fDtrControl == DTR_CONTROL_HANDSHAKE)
- {
- WARN("DSR/DTR flow control not supported\n");
- }
-
if (lpdcb->fInX)
port.c_iflag |= IXON;
else
@@ -1400,16 +1401,39 @@
port.c_iflag &= ~IXOFF;
if (tcsetattr(fd,TCSANOW,&port)==-1) { /* otherwise it hangs with pending input*/
- int save_error=errno;
+ ERR("tcsetattr error '%s'\n", strerror(errno));
COMM_SetCommError(handle,CE_IOE);
- release_comm_fd( handle, fd );
- ERR("tcsetattr error '%s'\n", strerror(save_error));
- return FALSE;
+ ret = FALSE;
} else {
COMM_SetCommError(handle,0);
- release_comm_fd( handle, fd );
- return TRUE;
+ ret = TRUE;
}
+
+ /* note: change DTR/RTS lines after setting the comm attributes,
+ * so flow control does not interfere. */
+#ifdef TIOCM_DTR
+ if (lpdcb->fDtrControl == DTR_CONTROL_HANDSHAKE)
+ {
+ WARN("DSR/DTR flow control not supported\n");
+ } else if(lpdcb->fDtrControl == DTR_CONTROL_DISABLE)
+ COMM_WhackModem(fd, ~TIOCM_DTR, 0);
+ else
+ COMM_WhackModem(fd, 0, TIOCM_DTR);
+#endif
+#ifdef TIOCM_RTS
+ if(!lpdcb->fOutxCtsFlow )
+ {
+ if(lpdcb->fRtsControl == RTS_CONTROL_DISABLE)
+ COMM_WhackModem(fd, ~TIOCM_RTS, 0);
+ else
+ COMM_WhackModem(fd, 0, TIOCM_RTS);
+ }
+#endif
+ if(lpdcb->fRtsControl == RTS_CONTROL_TOGGLE)
+ FIXME("RTS_CONTROL_TOGGLE is not supported.\n");
+ release_comm_fd( handle, fd );
+ return ret;
+
}
@@ -1432,14 +1456,19 @@
{
struct termios port;
int fd,speed;
+ int stat = DTR_CONTROL_ENABLE | RTS_CONTROL_ENABLE;
TRACE("handle %p, ptr %p\n", handle, lpdcb);
fd = get_comm_fd( handle, GENERIC_READ );
if (fd < 0) return FALSE;
- if (tcgetattr(fd, &port) == -1) {
+ if (tcgetattr(fd, &port) == -1
+#ifdef TIOCMGET
+ || ioctl(fd, TIOCMGET, &stat) == -1
+#endif
+ ) {
int save_error=errno;
- ERR("tcgetattr error '%s'\n", strerror(save_error));
+ ERR("tcgetattr or ioctl error '%s'\n", strerror(save_error));
COMM_SetCommError(handle,CE_IOE);
release_comm_fd( handle, fd );
return FALSE;
@@ -1562,7 +1591,11 @@
/* termios does not support DTR/DSR flow control */
lpdcb->fOutxDsrFlow = 0;
- lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
+ lpdcb->fDtrControl =
+#ifdef TIOCM_DTR
+ !(stat & TIOCM_DTR) ? DTR_CONTROL_DISABLE:
+#endif
+ DTR_CONTROL_ENABLE ;
#ifdef CRTSCTS
@@ -1572,7 +1605,11 @@
} else
#endif
{
- lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
+ lpdcb->fRtsControl =
+#ifdef TIOCM_RTS
+ !(stat & TIOCM_RTS) ? RTS_CONTROL_DISABLE :
+#endif
+ RTS_CONTROL_ENABLE ;
lpdcb->fOutxCtsFlow = 0;
}
if (port.c_iflag & IXON)
@@ -1601,6 +1638,10 @@
(lpdcb->StopBits == TWOSTOPBITS)?2:0);
TRACE("%s %s\n",(lpdcb->fInX)?"IXON":"~IXON",
(lpdcb->fOutX)?"IXOFF":"~IXOFF");
+ TRACE("fOutxCtsFlow %d fRtsControl %d\n", lpdcb->fOutxCtsFlow,
+ lpdcb->fRtsControl);
+ TRACE("fOutxDsrFlow %d fDtrControl%d\n", lpdcb->fOutxDsrFlow,
+ lpdcb->fDtrControl);
#ifdef CRTSCTS
if ( lpdcb->fOutxCtsFlow ||
lpdcb->fRtsControl == RTS_CONTROL_HANDSHAKE
@@ -1609,7 +1650,6 @@
else
TRACE("~CRTSCTS\n");
-
#endif
return TRUE;
}
More information about the wine-patches
mailing list