Release 960728

Sun Jul 28 17:57:19 1996  Alexandre Julliard  <julliard@lrc.epfl.ch>

	* [loader/task.c] [include/task.h]
	Implemented SwitchStackTo()/SwitchStackBack().

	* [include/wintypes.h] [loader/main.c]
	Added __winelib variable to distinguish between emulator and
 	library at run-time. Later on, this should avoid some
 	recompilations when building Winelib.

	* [windows/property.c]
	Implemented Win32 functions for window properties.

Fri Jul 26 18:00:00 1996  Alex Korobka <alex@phm30.pharm.sunysb.edu>

	* [controls/listbox.c]
	Implemented LBS_SORT style, WM_COMPAREITEM, and WM_DELETEITEM
	messages.

	* [controls/menu.c]
	Call TranslateMessage() to enable shortcuts (on WM_CHAR).

	* [include/cursoricon.h]
	Moved #pragma pack(1) back to where it belongs.

	* [objects/palette.c]
	RealizeDefaultPalette() maps to system colors only.
	Do not broadcast palette notifications when in TrueColor.

	* [objects/color.c] [include/palette.h]
	Miscellaneous optimizations. Had to fix several
	"improvements" made to my patch for previous release.

	* [objects/dib.c]
	Reverse dib bits order for 24-bit SetDIBits().

	* [objects/dc.c]
	GetDeviceCaps() does not return RC_PALETTE when in TrueColor.

	* [windows/scroll.c]
	Scroll update region too.

	* [windows/message.c]
	Include QS_MOUSE into the event mask for nonclient mouse
	message filter. Fixes problems with Word 6 freezing when
	mouse hits nonclient area.

	* [windows/win.c] 
	Allow top-level windows to be linked as HWND_TOP in CreateWindow().

	* [windows/winpos.c] [windows/mdi.c]
	Attempt to fix control menu duplication.

Fri Jul 26 09:49:35 1996  Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>

	* [files/drive.c]
	GetDriveType32A(): return value for CDROM fixed.

	* [files/file.c]
	SearchPath* added.

	* [if1632/gdi32.spec] [objects/brush.c]
	SetBrushOrgEx() added.

	* [loader/pe_resource.c]
	If even loading the default entry fails, we just use the first
	entry from the resource directory.

	[loader/task.c]
	SetSigHandler() stub added, Paradox 4.5 now starts up.

	* [misc/comm.c] [include/windows.h] [if1632/kernel32.spec]
	COMM functions updated to win32, not complete.

	* [misc/lstr.c]
	FormatMessageA partially implemented.

	* [include/miscemu.h] [memory/selector.c]
	  [memory/global.c] [miscemu/dosmem.c]
	DOS memory handling changed: 1MB preallocated block, real-mode
	segment handling possible, SetSelectorBase into lower physical 1MB
	possible.

	* [miscemu/dpmi.c]
	Real-mode segments changed, real-mode int 21,ax=6506 added.
	AX=0x0303 added.

	* [multimedia/time.c]
	Fixed bug in killTimer.

	* [objects/bitmap.c]
	LoadImageA partially implemented.

Wed Jul 24 18:20:24 1996  Albrecht Kleine  <kleine@ak.sax.de>

	* [include/dde_mem.h][include/dde_proc.h]
	  [ipc/dde_atom.c][ipc/dde_proc.c][windows/message.c]
	  [ipc/generic_hash.h][library/miscstubs.c]
	Changes for error free compilation using "--with-ipc":
	replaced some names with *16-equivalent (e.g. MSG to MSG16),
	modified prototype of function DDE_GlobalFree() .

	* [objects/palette.c]
	Added check for metafile-DC in GDISelectPalette(),
	GDIRealizePalette(),RealizeDefaultPalette() and
	IsDCCurrentPalette().

Tue Jul 23 22:46:53 1996  Andrew Lewycky <plewycky@oise.utoronto.ca>

	* [controls/edit.c]
	EDIT_WM_Create: Don't EDIT_EM_ReplaceSel if created with lParam = "",
	fixes Winhelp.

	* [windows/dialog.c]
	DIALOG_CreateIndirect: Initialise dlgProc before creating children.
diff --git a/misc/comm.c b/misc/comm.c
index a68542a..b628a2b 100644
--- a/misc/comm.c
+++ b/misc/comm.c
@@ -1,5 +1,7 @@
 /*
  * DEC 93 Erik Bos <erik@xs4all.nl>
+ *
+ * Copyright 1996 Marcus Meissner
  */
 
 #include <stdio.h>
@@ -11,7 +13,6 @@
 #include <ctype.h>
 #include <sys/stat.h>
 #if defined(__NetBSD__) || defined(__FreeBSD__)
-#include <errno.h>
 #include <sys/ioctl.h>
 #endif
 #include <unistd.h>
@@ -20,9 +21,9 @@
 #include "comm.h"
 #include "options.h"
 #include "stddebug.h"
-/* #define DEBUG_COMM */
-/* #undef  DEBUG_COMM */
 #include "debug.h"
+#include "handle32.h"
+#include "string32.h"
 
 int commerror = 0, eventmask = 0;
 
@@ -126,11 +127,13 @@
 		}
 }
 
-BOOL BuildCommDCB(LPCSTR device, LPDCB lpdcb)
+/**************************************************************************
+ *         BuildCommDCB		(USER.213)
+ */
+BOOL16 BuildCommDCB16(LPCSTR device, LPDCB16 lpdcb)
 {
 	/* "COM1:9600,n,8,1"	*/
 	/*  012345		*/
-
 	int port;
 	char *ptr, temp[256];
 
@@ -177,14 +180,12 @@
 			*ptr = toupper(*ptr);
 
         	dprintf_comm(stddeb,"BuildCommDCB: parity (%c)\n", *ptr);
+		lpdcb->fParity = 1;
 		switch (*ptr) {
 			case 'N':
 				lpdcb->Parity = NOPARITY;
 				lpdcb->fParity = 0;
 				break;			
-			
-			lpdcb->fParity = 1;
-			
 			case 'E':
 				lpdcb->Parity = EVENPARITY;
 				break;			
@@ -221,7 +222,162 @@
 	return 0;
 }
 
-int OpenComm(LPCSTR device, UINT cbInQueue, UINT cbOutQueue)
+/**************************************************************************
+ *         BuildCommDCBA		(KERNEL32.14)
+ */
+BOOL32 BuildCommDCB32A(LPCSTR device,LPDCB32 lpdcb) {
+	return BuildCommDCBAndTimeouts32A(device,lpdcb,NULL);
+}
+
+/**************************************************************************
+ *         BuildCommDCBAndTimeoutsA	(KERNEL32.15)
+ */
+BOOL32 BuildCommDCBAndTimeouts32A(LPCSTR device, LPDCB32 lpdcb,LPCOMMTIMEOUTS lptimeouts) {
+	int	port;
+	char	*ptr,*temp;
+
+	dprintf_comm(stddeb,"BuildCommDCBAndTimeouts32A(%s,%p,%p)\n",device,lpdcb,lptimeouts);
+	commerror = 0;
+
+	if (!lstrncmpi32A(device,"COM",3)) {
+		port=device[3]-'0';
+		if (port--==0) {
+			fprintf(stderr,"comm:BUG! COM0 can't exists!.\n");
+			return FALSE;
+		}
+		if (!ValidCOMPort(port))
+			return FALSE;
+		if (*(device+4)!=':')
+			return FALSE;
+		temp=(LPSTR)(device+5);
+	} else
+		temp=(LPSTR)device;
+	lpdcb->DCBlength	= sizeof(DCB32);
+	if (strchr(temp,',')) {	/* old style */
+		DCB16	dcb16;
+		BOOL16	ret;
+		char	last=temp[strlen(temp)-1];
+
+		ret=BuildCommDCB16(device,&dcb16);
+		if (!ret)
+			return FALSE;
+		lpdcb->BaudRate		= dcb16.BaudRate;
+		lpdcb->ByteSize		= dcb16.ByteSize;
+		lpdcb->fBinary		= dcb16.fBinary;
+		lpdcb->Parity		= dcb16.Parity;
+		lpdcb->fParity		= dcb16.fParity;
+		lpdcb->fNull		= dcb16.fNull;
+		lpdcb->StopBits		= dcb16.StopBits;
+		if (last == 'x') {
+			lpdcb->fInX		= TRUE;
+			lpdcb->fOutX		= TRUE;
+			lpdcb->fOutxCtsFlow	= FALSE;
+			lpdcb->fOutxDsrFlow	= FALSE;
+			lpdcb->fDtrControl	= DTR_CONTROL_ENABLE;
+			lpdcb->fRtsControl	= RTS_CONTROL_ENABLE;
+		} else if (last=='p') {
+			lpdcb->fInX		= FALSE;
+			lpdcb->fOutX		= FALSE;
+			lpdcb->fOutxCtsFlow	= TRUE;
+			lpdcb->fOutxDsrFlow	= TRUE;
+			lpdcb->fDtrControl	= DTR_CONTROL_HANDSHAKE;
+			lpdcb->fRtsControl	= RTS_CONTROL_HANDSHAKE;
+		} else {
+			lpdcb->fInX		= FALSE;
+			lpdcb->fOutX		= FALSE;
+			lpdcb->fOutxCtsFlow	= FALSE;
+			lpdcb->fOutxDsrFlow	= FALSE;
+			lpdcb->fDtrControl	= DTR_CONTROL_ENABLE;
+			lpdcb->fRtsControl	= RTS_CONTROL_ENABLE;
+		}
+		lpdcb->XonChar	= dcb16.XonChar;
+		lpdcb->XoffChar	= dcb16.XoffChar;
+		lpdcb->ErrorChar= dcb16.PeChar;
+		lpdcb->fErrorChar= dcb16.fPeChar;
+		lpdcb->EofChar	= dcb16.EofChar;
+		lpdcb->EvtChar	= dcb16.EvtChar;
+		lpdcb->XonLim	= dcb16.XonLim;
+		lpdcb->XoffLim	= dcb16.XoffLim;
+		return TRUE;
+	}
+	ptr=strtok(temp," "); 
+	while (ptr) {
+		DWORD	flag,x;
+
+		flag=0;
+		if (!strncmp("baud=",ptr,5)) {
+			if (!sscanf(ptr+5,"%ld",&x))
+				fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
+			lpdcb->BaudRate = x;
+			flag=1;
+		}
+		if (!strncmp("stop=",ptr,5)) {
+			if (!sscanf(ptr+5,"%ld",&x))
+				fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
+			lpdcb->StopBits = x;
+			flag=1;
+		}
+		if (!strncmp("data=",ptr,5)) {
+			if (!sscanf(ptr+5,"%ld",&x))
+				fprintf(stderr,"BuildCommDCB32A:Couldn't parse %s\n",ptr);
+			lpdcb->ByteSize = x;
+			flag=1;
+		}
+		if (!strncmp("parity=",ptr,7)) {
+			lpdcb->fParity	= TRUE;
+			switch (ptr[8]) {
+			case 'N':case 'n':
+				lpdcb->fParity	= FALSE;
+				lpdcb->Parity	= NOPARITY;
+				break;
+			case 'E':case 'e':
+				lpdcb->Parity	= EVENPARITY;
+				break;
+			case 'O':case 'o':
+				lpdcb->Parity	= ODDPARITY;
+				break;
+			case 'M':case 'm':
+				lpdcb->Parity	= MARKPARITY;
+				break;
+			}
+			flag=1;
+		}
+		if (!flag)
+			fprintf(stderr,"BuildCommDCB32A: Unhandled specifier '%s', please report.\n",ptr);
+		ptr=strtok(NULL," ");
+	}
+	if (lpdcb->BaudRate==110)
+		lpdcb->StopBits = 2;
+	return TRUE;
+}
+
+/**************************************************************************
+ *         BuildCommDCBAndTimeoutsW		(KERNEL32.16)
+ */
+BOOL32 BuildCommDCBAndTimeouts32W(
+	LPCWSTR devid,LPDCB32 lpdcb,LPCOMMTIMEOUTS lptimeouts
+) {
+	LPSTR	devidA;
+	BOOL32	ret;
+
+	dprintf_comm(stddeb,"BuildCommDCBAndTimeouts32W(%p,%p,%p)\n",devid,lpdcb,lptimeouts);
+	devidA = STRING32_DupUniToAnsi(devid);
+	ret=BuildCommDCBAndTimeouts32A(devidA,lpdcb,lptimeouts);
+	free(devidA);
+	return ret;
+}
+
+/**************************************************************************
+ *         BuildCommDCBW		(KERNEL32.17)
+ */
+BOOL32 BuildCommDCB32W(LPCWSTR devid,LPDCB32 lpdcb) {
+	return BuildCommDCBAndTimeouts32W(devid,lpdcb,NULL);
+}
+
+/*****************************************************************************
+ *	OpenComm		(USER.200)
+ */
+INT16 OpenComm(LPCSTR device,UINT16 cbInQueue,UINT16 cbOutQueue)
 {
 	int port, fd;
 
@@ -282,7 +438,10 @@
 	return 0;
 }
 
-int CloseComm(int fd)
+/*****************************************************************************
+ *	CloseComm		(USER.207)
+ */
+INT16 CloseComm(INT16 fd)
 {
     	dprintf_comm(stddeb,"CloseComm: fd %d\n", fd);
 	if (close(fd) == -1) {
@@ -294,7 +453,10 @@
 	}
 }
 
-int SetCommBreak(int fd)
+/*****************************************************************************
+ *	SetCommBreak		(USER.210)
+ */
+INT16 SetCommBreak16(INT16 fd)
 {
 	struct DosDeviceStruct *ptr;
 
@@ -309,7 +471,31 @@
 	return 0;
 }
 
-int ClearCommBreak(int fd)
+/*****************************************************************************
+ *	SetCommBreak		(KERNEL32.449)
+ */
+BOOL32 SetCommBreak32(HANDLE32 hfile)
+{
+	FILE_OBJECT	*fob = (FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+
+	struct DosDeviceStruct *ptr;
+
+	dprintf_comm(stddeb,"SetCommBreak: fd: %d\n", fd);
+	if ((ptr = GetDeviceStruct(fd)) == NULL) {
+		commerror = IE_BADID;
+		return FALSE;
+	}
+
+	ptr->suspended = 1;
+	commerror = 0;
+	return TRUE;
+}
+
+/*****************************************************************************
+ *	ClearCommBreak		(USER.211)
+ */
+INT16 ClearCommBreak16(INT16 fd)
 {
 	struct DosDeviceStruct *ptr;
 
@@ -324,15 +510,37 @@
 	return 0;
 }
 
-LONG EscapeCommFunction(int fd, int nFunction)
+/*****************************************************************************
+ *	ClearCommBreak		(KERNEL32.20)
+ */
+BOOL32 ClearCommBreak32(HANDLE32 hfile)
 {
-	int max;
+	FILE_OBJECT	*fob = (FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+	struct DosDeviceStruct *ptr;
+
+    	dprintf_comm(stddeb,"ClearCommBreak: fd: %d\n", fd);
+	if ((ptr = GetDeviceStruct(fd)) == NULL) {
+		commerror = IE_BADID;
+		return FALSE;
+	}
+
+	ptr->suspended = 0;
+	commerror = 0;
+	return TRUE;
+}
+
+/*****************************************************************************
+ *	EscapeCommFunction	(USER.214)
+ */
+LONG EscapeCommFunction16(UINT16 fd,UINT16 nFunction)
+{
+	int	max;
 	struct termios port;
 
-    	dprintf_comm(stddeb,
-		"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
-	if (tcgetattr(fd, &port) == -1) {
-		commerror = WinError();	
+    	dprintf_comm(stddeb,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
+	if (tcgetattr(fd,&port) == -1) {
+		commerror=WinError();	
 		return -1;
 	}
 
@@ -342,13 +550,13 @@
 
 		case GETMAXCOM:
 			for (max = MAX_PORTS;!COM[max].devicename;max--)
-				;		
+				;
 			return max;
 			break;
 
 		case GETMAXLPT:
 			for (max = MAX_PORTS;!LPT[max].devicename;max--)
-				;		
+				;
 			return 0x80 + max;
 			break;
 
@@ -398,25 +606,99 @@
 	}
 }
 
-int FlushComm(int fd, int fnQueue)
+/*****************************************************************************
+ *	EscapeCommFunction	(KERNEL32.214)
+ */
+BOOL32 EscapeCommFunction32(HANDLE32 hfile,UINT32 nFunction)
+{
+	FILE_OBJECT	*fob = (FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+	struct termios	port;
+	struct DosDeviceStruct *ptr;
+
+    	dprintf_comm(stddeb,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
+	if (tcgetattr(fd,&port) == -1) {
+		commerror=WinError();	
+		return FALSE;
+	}
+	if ((ptr = GetDeviceStruct(fd)) == NULL) {
+		commerror = IE_BADID;
+		return FALSE;
+	}
+
+	switch (nFunction) {
+		case RESETDEV:
+			break;					
+
+#ifdef TIOCM_DTR
+		case CLRDTR:
+			port.c_cflag &= TIOCM_DTR;
+			break;
+#endif
+
+#ifdef TIOCM_RTS
+		case CLRRTS:
+			port.c_cflag &= TIOCM_RTS;
+			break;
+#endif
+	
+#ifdef CRTSCTS
+		case SETDTR:
+			port.c_cflag |= CRTSCTS;
+			break;
+
+		case SETRTS:
+			port.c_cflag |= CRTSCTS;
+			break;
+#endif
+
+		case SETXOFF:
+			port.c_iflag |= IXOFF;
+			break;
+
+		case SETXON:
+			port.c_iflag |= IXON;
+			break;
+		case SETBREAK:
+			ptr->suspended = 1;
+			break;
+		case CLRBREAK:
+			ptr->suspended = 0;
+			break;
+		default:
+			fprintf(stderr,
+			"EscapeCommFunction32 fd: %d, unknown function: %d\n", 
+			fd, nFunction);
+			break;				
+	}
+	
+	if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
+		commerror = WinError();
+		return FALSE;	
+	} else {
+		commerror = 0;
+		return TRUE;
+	}
+}
+
+/*****************************************************************************
+ *	FlushComm	(USER.215)
+ */
+INT16 FlushComm(INT16 fd,INT16 fnQueue)
 {
 	int queue;
 
     	dprintf_comm(stddeb,"FlushComm fd: %d, queue: %d\n", fd, fnQueue);
 	switch (fnQueue) {
-		case 0:
-			queue = TCOFLUSH;
+		case 0:	queue = TCOFLUSH;
 			break;
-		case 1:
-			queue = TCIFLUSH;
+		case 1:	queue = TCIFLUSH;
 			break;
-		default:
-			fprintf(stderr,
+		default:fprintf(stderr,
 				"FlushComm fd: %d, UNKNOWN queue: %d\n", 
 				fd, fnQueue);
 			return -1;
 		}
-	
 	if (tcflush(fd, fnQueue)) {
 		commerror = WinError();
 		return -1;	
@@ -426,7 +708,10 @@
 	}
 }  
 
-int GetCommError(int fd, COMSTAT *lpStat)
+/*****************************************************************************
+ *	GetCommError	(USER.203)
+ */
+INT16 GetCommError(INT16 fd,LPCOMSTAT lpStat)
 {
 	int temperror;
 
@@ -437,15 +722,36 @@
 	return(temperror);
 }
 
-UINT * SetCommEventMask(int fd, UINT fuEvtMask)
+/*****************************************************************************
+ *	ClearCommError	(KERNEL32.21)
+ */
+BOOL32 ClearCommError(HANDLE32 hfile,LPDWORD errors,LPCOMSTAT lpStat)
 {
+	int temperror;
+	FILE_OBJECT	*fob=(FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+
     	dprintf_comm(stddeb,
-		"SetCommEventMask: fd %d, mask %d\n", fd, fuEvtMask);
-	eventmask |= fuEvtMask;
-	return (UINT *)&eventmask;
+		"ClearCommError: fd %d (current error %d)\n", fd, commerror);
+	temperror = commerror;
+	commerror = 0;
+	return TRUE;
 }
 
-UINT GetCommEventMask(int fd, int fnEvtClear)
+/*****************************************************************************
+ *	SetCommEventMask	(USER.208)
+ */
+UINT16	*SetCommEventMask(INT16 fd,UINT16 fuEvtMask)
+{
+    	dprintf_comm(stddeb,"SetCommEventMask:fd %d,mask %d\n",fd,fuEvtMask);
+	eventmask |= fuEvtMask;
+	return (UINT *)&eventmask;	/* FIXME, should be SEGPTR */
+}
+
+/*****************************************************************************
+ *	GetCommEventMask	(USER.209)
+ */
+UINT16 GetCommEventMask(INT16 fd,UINT16 fnEvtClear)
 {
     	dprintf_comm(stddeb,
 		"GetCommEventMask: fd %d, mask %d\n", fd, fnEvtClear);
@@ -453,7 +759,38 @@
 	return eventmask;
 }
 
-int SetCommState(DCB *lpdcb)
+/*****************************************************************************
+ *	GetCommMask	(KERNEL32.156)
+ */
+BOOL32 GetCommMask(HANDLE32 hfile,LPDWORD evtmask)
+{
+	FILE_OBJECT	*fob=(FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+
+    	dprintf_comm(stddeb,
+		"GetCommMask: fd %d, mask %p\n", fd, evtmask);
+	*evtmask = eventmask;
+	return TRUE;
+}
+
+/*****************************************************************************
+ *	SetCommMask	(KERNEL32.451)
+ */
+BOOL32 SetCommMask(HANDLE32 hfile,DWORD evtmask)
+{
+	FILE_OBJECT	*fob=(FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+
+    	dprintf_comm(stddeb,
+		"SetCommMask: fd %d, mask %lx\n", fd, evtmask);
+	eventmask = evtmask;
+	return TRUE;
+}
+
+/*****************************************************************************
+ *	SetCommState16	(USER.201)
+ */
+INT16 SetCommState16(LPDCB16 lpdcb)
 {
 	struct termios port;
 	struct DosDeviceStruct *ptr;
@@ -652,7 +989,216 @@
 	}
 }
 
-int GetCommState(int fd, DCB *lpdcb)
+/*****************************************************************************
+ *	SetCommState32	(KERNEL32.452)
+ */
+BOOL32 SetCommState32(HANDLE32 hfile,LPDCB32 lpdcb)
+{
+	FILE_OBJECT	*fob = (FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+	struct termios port;
+	struct DosDeviceStruct *ptr;
+
+    	dprintf_comm(stddeb,"SetCommState: fd %d, ptr %p\n",fd,lpdcb);
+	if (tcgetattr(fd,&port) == -1) {
+		commerror = WinError();	
+		return FALSE;
+	}
+
+	port.c_cc[VMIN] = 0;
+	port.c_cc[VTIME] = 1;
+
+#ifdef IMAXBEL
+	port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR|IMAXBEL);
+#else
+	port.c_iflag &= ~(ISTRIP|BRKINT|IGNCR|ICRNL|INLCR);
+#endif
+	port.c_iflag |= (IGNBRK);
+
+	port.c_oflag &= ~(OPOST);
+
+	port.c_cflag &= ~(HUPCL);
+	port.c_cflag |= CLOCAL | CREAD;
+
+	port.c_lflag &= ~(ICANON|ECHO|ISIG);
+	port.c_lflag |= NOFLSH;
+
+	if ((ptr = GetDeviceStruct(fd)) == NULL) {
+		commerror = IE_BADID;
+		return FALSE;
+	}
+	if (ptr->baudrate > 0)
+	  	lpdcb->BaudRate = ptr->baudrate;
+    	dprintf_comm(stddeb,"SetCommState: baudrate %ld\n",lpdcb->BaudRate);
+#ifdef CBAUD
+	port.c_cflag &= ~CBAUD;
+	switch (lpdcb->BaudRate) {
+		case 110:
+		case CBR_110:
+			port.c_cflag |= B110;
+			break;		
+		case 300:
+		case CBR_300:
+			port.c_cflag |= B300;
+			break;		
+		case 600:
+		case CBR_600:
+			port.c_cflag |= B600;
+			break;		
+		case 1200:
+		case CBR_1200:
+			port.c_cflag |= B1200;
+			break;		
+		case 2400:
+		case CBR_2400:
+			port.c_cflag |= B2400;
+			break;		
+		case 4800:
+		case CBR_4800:
+			port.c_cflag |= B4800;
+			break;		
+		case 9600:
+		case CBR_9600:
+			port.c_cflag |= B9600;
+			break;		
+		case 19200:
+		case CBR_19200:
+			port.c_cflag |= B19200;
+			break;		
+		case 38400:
+		case CBR_38400:
+			port.c_cflag |= B38400;
+			break;		
+		default:
+			commerror = IE_BAUDRATE;
+			return FALSE;
+	}
+#else
+        switch (lpdcb->BaudRate) {
+                case 110:
+                case CBR_110:
+                        port.c_ospeed = B110;
+                        break;
+                case 300:
+                case CBR_300:
+                        port.c_ospeed = B300;
+                        break;
+                case 600:
+                case CBR_600:
+                        port.c_ospeed = B600;
+                        break;
+                case 1200:
+                case CBR_1200:
+                        port.c_ospeed = B1200;
+                        break;
+                case 2400:
+                case CBR_2400:
+                        port.c_ospeed = B2400;
+                        break;
+                case 4800:
+                case CBR_4800:
+                        port.c_ospeed = B4800;
+                        break;
+                case 9600:
+                case CBR_9600:
+                        port.c_ospeed = B9600;
+                        break;
+                case 19200:
+                case CBR_19200:
+                        port.c_ospeed = B19200;
+                        break;
+                case 38400:
+                case CBR_38400:
+                        port.c_ospeed = B38400;
+                        break;
+                default:
+                        commerror = IE_BAUDRATE;
+                        return FALSE;
+        }
+        port.c_ispeed = port.c_ospeed;
+#endif
+    	dprintf_comm(stddeb,"SetCommState: bytesize %d\n",lpdcb->ByteSize);
+	port.c_cflag &= ~CSIZE;
+	switch (lpdcb->ByteSize) {
+		case 5:
+			port.c_cflag |= CS5;
+			break;
+		case 6:
+			port.c_cflag |= CS6;
+			break;
+		case 7:
+			port.c_cflag |= CS7;
+			break;
+		case 8:
+			port.c_cflag |= CS8;
+			break;
+		default:
+			commerror = IE_BYTESIZE;
+			return FALSE;
+	}
+
+    	dprintf_comm(stddeb,"SetCommState: parity %d\n",lpdcb->Parity);
+	port.c_cflag &= ~(PARENB | PARODD);
+	if (lpdcb->fParity)
+		switch (lpdcb->Parity) {
+			case NOPARITY:
+				port.c_iflag &= ~INPCK;
+				break;
+			case ODDPARITY:
+				port.c_cflag |= (PARENB | PARODD);
+				port.c_iflag |= INPCK;
+				break;
+			case EVENPARITY:
+				port.c_cflag |= PARENB;
+				port.c_iflag |= INPCK;
+				break;
+			default:
+				commerror = IE_BYTESIZE;
+				return FALSE;
+		}
+	
+
+    	dprintf_comm(stddeb,"SetCommState: stopbits %d\n",lpdcb->StopBits);
+	switch (lpdcb->StopBits) {
+		case ONESTOPBIT:
+				port.c_cflag &= ~CSTOPB;
+				break;
+		case TWOSTOPBITS:
+				port.c_cflag |= CSTOPB;
+				break;
+		default:
+			commerror = IE_BYTESIZE;
+			return FALSE;
+	}
+#ifdef CRTSCTS
+	if (	lpdcb->fOutxCtsFlow 			||
+		lpdcb->fDtrControl == DTR_CONTROL_ENABLE||
+		lpdcb->fRtsControl == RTS_CONTROL_ENABLE
+	)
+		port.c_cflag |= CRTSCTS;
+	if (lpdcb->fDtrControl == DTR_CONTROL_DISABLE)
+		port.c_cflag &= ~CRTSCTS;
+
+#endif	
+	if (lpdcb->fInX)
+		port.c_iflag |= IXON;
+	if (lpdcb->fOutX)
+		port.c_iflag |= IXOFF;
+
+	if (tcsetattr(fd,TCSADRAIN,&port)==-1) {
+		commerror = WinError();	
+		return FALSE;
+	} else {
+		commerror = 0;
+		return TRUE;
+	}
+}
+
+
+/*****************************************************************************
+ *	GetCommState	(USER.202)
+ */
+INT16 GetCommState16(INT16 fd, LPDCB16 lpdcb)
 {
 	struct termios port;
 
@@ -661,9 +1207,7 @@
 		commerror = WinError();	
 		return -1;
 	}
-
 	lpdcb->Id = fd;
-
 #ifdef CBAUD
         switch (port.c_cflag & CBAUD) {
 #else
@@ -769,7 +1313,127 @@
 	return 0;
 }
 
-int TransmitCommChar(int fd, char chTransmit)
+/*****************************************************************************
+ *	GetCommState	(KERNEL32.159)
+ */
+BOOL32 GetCommState32(HANDLE32 hfile, LPDCB32 lpdcb)
+{
+	FILE_OBJECT	*fob = (FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+	struct termios	port;
+
+
+    	dprintf_comm(stddeb,"GetCommState32: fd %d, ptr %p\n", fd, lpdcb);
+	if (tcgetattr(fd, &port) == -1) {
+		commerror = WinError();	
+		return FALSE;
+	}
+#ifdef CBAUD
+        switch (port.c_cflag & CBAUD) {
+#else
+        switch (port.c_ospeed) {
+#endif
+		case B110:
+			lpdcb->BaudRate = 110;
+			break;
+		case B300:
+			lpdcb->BaudRate = 300;
+			break;
+		case B600:
+			lpdcb->BaudRate = 600;
+			break;
+		case B1200:
+			lpdcb->BaudRate = 1200;
+			break;
+		case B2400:
+			lpdcb->BaudRate = 2400;
+			break;
+		case B4800:
+			lpdcb->BaudRate = 4800;
+			break;
+		case B9600:
+			lpdcb->BaudRate = 9600;
+			break;
+		case B19200:
+			lpdcb->BaudRate = 19200;
+			break;
+		case B38400:
+			lpdcb->BaudRate = 38400;
+			break;
+	}
+
+	switch (port.c_cflag & CSIZE) {
+		case CS5:
+			lpdcb->ByteSize = 5;
+			break;
+		case CS6:
+			lpdcb->ByteSize = 6;
+			break;
+		case CS7:
+			lpdcb->ByteSize = 7;
+			break;
+		case CS8:
+			lpdcb->ByteSize = 8;
+			break;
+	}	
+	
+	switch (port.c_cflag & ~(PARENB | PARODD)) {
+		case 0:
+			lpdcb->fParity = NOPARITY;
+			break;
+		case PARENB:
+			lpdcb->fParity = EVENPARITY;
+			break;
+		case (PARENB | PARODD):
+			lpdcb->fParity = ODDPARITY;		
+			break;
+	}
+
+	if (port.c_cflag & CSTOPB)
+		lpdcb->StopBits = TWOSTOPBITS;
+	else
+		lpdcb->StopBits = ONESTOPBIT;
+
+	lpdcb->fNull = 0;
+	lpdcb->fBinary = 1;
+
+#ifdef CRTSCTS
+
+	if (port.c_cflag & CRTSCTS) {
+		lpdcb->fDtrControl = DTR_CONTROL_ENABLE;
+		lpdcb->fRtsControl = RTS_CONTROL_ENABLE;
+		lpdcb->fOutxCtsFlow = 1;
+		lpdcb->fOutxDsrFlow = 1;
+	} else 
+#endif
+	{
+		lpdcb->fDtrControl = DTR_CONTROL_DISABLE;
+		lpdcb->fRtsControl = RTS_CONTROL_DISABLE;
+	}
+	if (port.c_iflag & IXON)
+		lpdcb->fInX = 1;
+	else
+		lpdcb->fInX = 0;
+
+	if (port.c_iflag & IXOFF)
+		lpdcb->fOutX = 1;
+	else
+		lpdcb->fOutX = 0;
+/*
+	lpdcb->XonChar = 
+	lpdcb->XoffChar = 
+ */
+	lpdcb->XonLim = 10;
+	lpdcb->XoffLim = 10;
+
+	commerror = 0;
+	return TRUE;
+}
+
+/*****************************************************************************
+ *	TransmitCommChar	(USER.206)
+ */
+INT16 TransmitCommChar16(INT16 fd,CHAR chTransmit)
 {
 	struct DosDeviceStruct *ptr;
 
@@ -794,7 +1458,38 @@
 	}
 }
 
-int UngetCommChar(int fd, char chUnget)
+/*****************************************************************************
+ *	TransmitCommChar	(KERNEL32.535)
+ */
+BOOL32 TransmitCommChar32(HANDLE32 hfile,CHAR chTransmit)
+{
+	FILE_OBJECT	*fob = (FILE_OBJECT*)hfile;
+	int		fd = fob->fd;
+	struct DosDeviceStruct *ptr;
+
+    	dprintf_comm(stddeb,"TransmitCommChar32(%d,'%c')\n",fd,chTransmit);
+	if ((ptr = GetDeviceStruct(fd)) == NULL) {
+		commerror = IE_BADID;
+		return FALSE;
+	}
+
+	if (ptr->suspended) {
+		commerror = IE_HARDWARE;
+		return FALSE;
+	}
+	if (write(fd, (void *) &chTransmit, 1) == -1) {
+		commerror = WinError();
+		return FALSE;
+	}  else {
+		commerror = 0;
+		return TRUE;
+	}
+}
+
+/*****************************************************************************
+ *	UngetCommChar	(USER.212)
+ */
+INT16 UngetCommChar(INT16 fd,CHAR chUnget)
 {
 	struct DosDeviceStruct *ptr;
 
@@ -811,12 +1506,14 @@
 
 	ptr->unget = 1;
 	ptr->unget_byte = chUnget;
-	
 	commerror = 0;
 	return 0;
 }
 
-int ReadComm(int fd, LPSTR lpvBuf, int cbRead)
+/*****************************************************************************
+ *	ReadComm	(USER.204)
+ */
+INT16 ReadComm(INT16 fd,LPSTR lpvBuf,INT16 cbRead)
 {
 	int status, length;
 	struct DosDeviceStruct *ptr;
@@ -858,7 +1555,10 @@
 	}
 }
 
-int WriteComm(int fd, LPSTR lpvBuf, int cbWrite)
+/*****************************************************************************
+ *	WriteComm	(USER.205)
+ */
+INT16 WriteComm(INT16 fd, LPSTR lpvBuf, INT16 cbWrite)
 {
 	int x, length;
 	struct DosDeviceStruct *ptr;
@@ -888,3 +1588,24 @@
 		return length;
 	}
 }
+
+
+/*****************************************************************************
+ *	GetCommTimeouts		(KERNEL32.160)
+ */
+BOOL32 GetCommTimeouts(HANDLE32 hfile,LPCOMMTIMEOUTS lptimeouts) {
+	dprintf_comm(stddeb,"GetCommTimeouts(%lx,%p), empty stub.\n",
+		(DWORD)hfile,lptimeouts
+	);
+	return TRUE;
+}
+
+/*****************************************************************************
+ *	SetCommTimeouts		(KERNEL32.453)
+ */
+BOOL32 SetCommTimeouts(HANDLE32 hfile,LPCOMMTIMEOUTS lptimeouts) {
+	dprintf_comm(stddeb,"SetCommTimeouts(%lx,%p), empty stub.\n",
+		(DWORD)hfile,lptimeouts
+	);
+	return TRUE;
+}