Tue Feb 1 21:14:47 1994 Bob Amstadt (bob@pooh) * [loader/selector.c] Added function CreateNewSegments(). Modified IPCCopySelector to allow aliasing to any arbitrary memory space. * [memory/global.c] Fixed potential bug in GlobalGetFreeSegments(). * [memory/linear.c] Created functions GlobalLinearLock() and GlobalLinearUnlock(). Tue Feb 1 05:51:43 1994 julliard@di.epfl.ch (Alexandre Julliard) * [controls/widgets.c] Removed CAPTION window class. * [loader/cursor.c] Bug fix in LoadCursor(): don't allocate memory every time for built-in cursors. * [windows/clipping.c] Invalidate child windows in InvalidateRgn(). * [windows/defwnd.c] Added repaint of the caption when changing window text. * [windows/event.c] Modified SetCapture() to allow keyboard events while capturing. * [windows/message.c] New function MSG_GetHardwareMessage(), to do mouse tracking without returning control to the Windows program. * [windows/nonclient.c] A couple of changes in frame drawing for DLGMODALFRAME windows. Rewritten window moving code, to use MSG_GetHardwareMessage() instead of non-client mouse events (this is the way Windows does it), and to send WM_ENTERSIZEMOVE messages. Removed WM_NCBUTTONUP and WM_NCMOUSEMOVE handlers. * [windows/win.c] Allocate temporary structures on the USER heap instead of using GlobalAlloc(). * [windows/winpos.c] Added function WINPOS_GetMinMaxInfo() to get sizing informations. Jan 31, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [windows/nonclient.c] Call to StdDrawScrollBar() during NC's drawing. Call to NC_ScrollBarButtonDown() on NC mouse events WM_LBUTTONDOWN. Call to NC_ScrollBarButtonUp() on NC mouse events WM_LBUTTONUP. Call to NC_ScrollBarMouseMove() on NC mouse events WM_MOUSEMOVE. * [controls/menu.c] New GetSubMenu() function. Move GetMenu() & SetMenu() functions from 'windows/win.c'. * [controls/listbox.c] Start changes to satisfy recent changes in scrollbars/windows. * [loader/resource.c] Put some code in LoadAccelerators() stub. New TranslateAccelerator() function. * [windows/win.c] Remove GetMenu() & SetMenu() functions. Call to NC_CreateScrollBars() if required by CreateWindow(). Mon Jan 24 10:40:10 EST 1994 John Richardson (jrichard@cs.uml.edu) * [window/win.c] Added functions EnumWindows, EnumChildWindows, and helper WIN_EnumChildWin. EnumWindows won't list all wine windows because GetDesktopWindow isn't complete. However, the code is in place for it to work correctly and only needs GetDesktopWindow to do so. Tue Jan 25 05:51:47 1994 julliard@di.epfl.ch (Alexandre Julliard) * [windows/defwnd.c] Added handling of activation messages (WM_ACTIVATE, WM_NCACTIVATE, WM_MOUSEACTIVATE) * [windows/event.c] De-activate the window when losing input focus. * [windows/focus.c] Bug fix in SetFocus(). * [windows/message.c] Added activation of the window on mouse-clicks. * [windows/nonclient.c] Changed non-client area painting to use the correct colors depending upon the activation state. Added WM_NCACTIVATE message handling. Fixed a couple of bugs in window moving and resizing. * [windows/winpos.c] Implemented Get/SetActiveWindow(). Implemented SWP_NOACTIVATE flag in SetWindowPos(). Jan 17, 94 martin2@trgcorp.solucorp.qc.ca (Martin Ayotte) * [misc/message.c] MessageBox has a CaptionBar for his title except for MB_SYSTEMMODAL with MB_ICONHAND. * [windows/nonclient.c] Call to NC_TrackSysMenu on SysMenu button mouse click. * [windows/defwnd.c] Call to NC_TrackSysMenu on Alt key (VK_MENU). * [controls/menu.c] New GetSystemMenu() function. New CopySystemMenu() internal function. New NC_TrackSysMenu() internal function. * [include/windows.h] New WM_INITMENU, WM_INITMENUPOPUP, WM_MENUSELECT & WM_MENUCHAR defines.
883 lines
16 KiB
C
883 lines
16 KiB
C
/*
|
|
* DEC 93 Erik Bos (erik@trashcan.hacktic.nl)
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <termios.h>
|
|
#include <fcntl.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#if defined(__NetBSD__) || defined(__FreeBSD__)
|
|
#include <errno.h>
|
|
#include <sys/ioctl.h>
|
|
#endif
|
|
#include "wine.h"
|
|
#include "windows.h"
|
|
|
|
#define DEBUG_COMM
|
|
|
|
#define MAX_PORTS 16
|
|
|
|
int commerror = 0, eventmask = 0;
|
|
|
|
struct DosDeviceStruct {
|
|
char *devicename; /* /dev/cua1 */
|
|
int fd;
|
|
int suspended;
|
|
int unget;
|
|
int unget_byte;
|
|
};
|
|
|
|
struct DosDeviceStruct COM[MAX_PORTS];
|
|
struct DosDeviceStruct LPT[MAX_PORTS];
|
|
|
|
void Comm_DeInit(void);
|
|
|
|
void Comm_Init(void)
|
|
{
|
|
int x, serial = 0, parallel = 0;
|
|
char option[10], temp[256], *ptr;
|
|
struct stat st;
|
|
|
|
for (x=0; x!=MAX_PORTS; x++) {
|
|
strcpy(option,"COMx");
|
|
option[3] = '0' + x;
|
|
option[4] = '\0';
|
|
|
|
GetPrivateProfileString("serialports", option, "*", temp, sizeof(temp), WINE_INI);
|
|
if (!strcmp(temp, "*") || *temp == '\0')
|
|
COM[serial].devicename = NULL;
|
|
else {
|
|
stat(temp, &st);
|
|
if (!S_ISCHR(st.st_mode))
|
|
fprintf(stderr,"comm: can 't use `%s' as COM%d !\n", temp, x);
|
|
else
|
|
if ((ptr = malloc(strlen(temp)+1)) == NULL)
|
|
fprintf(stderr,"comm: can't malloc for device info!\n");
|
|
else {
|
|
COM[serial].fd = 0;
|
|
COM[serial].devicename = ptr;
|
|
strcpy(COM[serial++].devicename, temp);
|
|
}
|
|
}
|
|
|
|
strcpy(option, "LPTx");
|
|
option[3] = '0' + x;
|
|
option[4] = '\0';
|
|
|
|
GetPrivateProfileString("parallelports", option, "*", temp, sizeof(temp), WINE_INI);
|
|
if (!strcmp(temp, "*") || *temp == '\0')
|
|
LPT[parallel].devicename = NULL;
|
|
else {
|
|
stat(temp, &st);
|
|
if (!S_ISCHR(st.st_mode))
|
|
fprintf(stderr,"comm: can 't use `%s' as LPT%d !\n", temp, x);
|
|
else
|
|
if ((ptr = malloc(strlen(temp)+1)) == NULL)
|
|
fprintf(stderr,"comm: can't malloc for device info!\n");
|
|
else {
|
|
LPT[serial].fd = 0;
|
|
LPT[serial].devicename = ptr;
|
|
strcpy(LPT[serial++].devicename, temp);
|
|
}
|
|
}
|
|
|
|
}
|
|
atexit(Comm_DeInit);
|
|
}
|
|
|
|
void Comm_DeInit(void)
|
|
{
|
|
int x;
|
|
|
|
for (x=0; x!=MAX_PORTS; x++) {
|
|
|
|
if (COM[x].devicename) {
|
|
if (COM[x].fd)
|
|
close(COM[x].fd);
|
|
free(COM[x].devicename);
|
|
}
|
|
if (LPT[x].devicename) {
|
|
if (LPT[x].fd)
|
|
close(LPT[x].fd);
|
|
free(LPT[x].devicename);
|
|
}
|
|
}
|
|
}
|
|
|
|
struct DosDeviceStruct *GetDeviceStruct(int fd)
|
|
{
|
|
int x;
|
|
|
|
for (x=0; x!=MAX_PORTS; x++) {
|
|
if (COM[x].fd == fd)
|
|
return &COM[x];
|
|
if (LPT[x].fd == fd)
|
|
return &LPT[x];
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int ValidCOMPort(int x)
|
|
{
|
|
return(x < MAX_PORTS ? (int) COM[x].devicename : 0);
|
|
}
|
|
|
|
int ValidLPTPort(int x)
|
|
{
|
|
return(x < MAX_PORTS ? (int) LPT[x].devicename : 0);
|
|
}
|
|
|
|
int WinError(void)
|
|
{
|
|
perror("comm");
|
|
switch (errno) {
|
|
default:
|
|
return CE_IOE;
|
|
}
|
|
}
|
|
|
|
int BuildCommDCB(LPSTR device, DCB FAR *lpdcb)
|
|
{
|
|
/* "COM1:9600,n,8,1" */
|
|
/* 012345 */
|
|
|
|
int port;
|
|
char *ptr, *ptr2, temp[256],temp2[10];
|
|
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"BuildCommDCB: (%s), ptr %d\n", device, lpdcb);
|
|
#endif
|
|
commerror = 0;
|
|
|
|
if (!strncmp(device,"COM",3)) {
|
|
port = device[3] - '0';
|
|
|
|
if (!ValidCOMPort(port)) {
|
|
commerror = IE_BADID;
|
|
return -1;
|
|
}
|
|
|
|
if (!COM[port].fd) {
|
|
commerror = IE_NOPEN;
|
|
return -1;
|
|
}
|
|
lpdcb->Id = COM[port].fd;
|
|
|
|
if (!*(device+4))
|
|
return 0;
|
|
|
|
if (*(device+4) != ':')
|
|
return -1;
|
|
|
|
strcpy(temp,device+5);
|
|
ptr = strtok(temp, ",");
|
|
|
|
fprintf(stderr,"BuildCommDCB: baudrate (%s)\n", ptr);
|
|
lpdcb->BaudRate = atoi(ptr);
|
|
|
|
ptr = strtok(NULL, ",");
|
|
if (islower(*ptr))
|
|
*ptr = toupper(*ptr);
|
|
|
|
fprintf(stderr,"BuildCommDCB: parity (%c)\n", *ptr);
|
|
switch (*ptr) {
|
|
case 'N':
|
|
lpdcb->Parity = NOPARITY;
|
|
lpdcb->fParity = 0;
|
|
break;
|
|
|
|
lpdcb->fParity = 1;
|
|
|
|
case 'E':
|
|
lpdcb->Parity = EVENPARITY;
|
|
break;
|
|
case 'M':
|
|
lpdcb->Parity = MARKPARITY;
|
|
break;
|
|
case 'O':
|
|
lpdcb->Parity = ODDPARITY;
|
|
break;
|
|
default:
|
|
fprintf(stderr,"comm: unknown parity `%c'!\n", *ptr);
|
|
return -1;
|
|
}
|
|
|
|
ptr = strtok(NULL, ",");
|
|
fprintf(stderr, "BuildCommDCB: charsize (%c)\n", *ptr);
|
|
lpdcb->ByteSize = *ptr - '0';
|
|
|
|
ptr = strtok(NULL, ",");
|
|
fprintf(stderr, "BuildCommDCB: stopbits (%c)\n", *ptr);
|
|
switch (*ptr) {
|
|
case '1':
|
|
lpdcb->StopBits = ONESTOPBIT;
|
|
break;
|
|
case '2':
|
|
lpdcb->StopBits = TWOSTOPBITS;
|
|
break;
|
|
default:
|
|
fprintf(stderr,"comm: unknown # of stopbits `%c'!\n", *ptr);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int OpenComm(LPSTR device, UINT cbInQueue, UINT cbOutQueue)
|
|
{
|
|
int port, fd;
|
|
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"OpenComm: %s, %d, %d\n", device, cbInQueue, cbOutQueue);
|
|
#endif
|
|
|
|
commerror = 0;
|
|
|
|
if (!strncmp(device,"COM",3)) {
|
|
port = device[3] - '0';
|
|
|
|
if (!ValidCOMPort(port)) {
|
|
commerror = IE_BADID;
|
|
return -1;
|
|
}
|
|
if (COM[port].fd) {
|
|
commerror = IE_OPEN;
|
|
return -1;
|
|
}
|
|
|
|
fd = open(COM[port].devicename, O_RDWR | O_NONBLOCK, 0);
|
|
if (fd == -1) {
|
|
commerror = WinError();
|
|
return -1;
|
|
} else {
|
|
COM[port].fd = fd;
|
|
return fd;
|
|
}
|
|
}
|
|
else
|
|
if (!strncmp(device,"LPT",3)) {
|
|
port = device[3] - '0';
|
|
|
|
if (!ValidLPTPort(port)) {
|
|
commerror = IE_BADID;
|
|
return -1;
|
|
}
|
|
if (LPT[port].fd) {
|
|
commerror = IE_OPEN;
|
|
return -1;
|
|
}
|
|
|
|
fd = open(LPT[port].devicename, O_RDWR | O_NONBLOCK, 0);
|
|
if (fd == -1) {
|
|
commerror = WinError();
|
|
return -1;
|
|
} else {
|
|
LPT[port].fd = fd;
|
|
return fd;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int CloseComm(int fd)
|
|
{
|
|
int status;
|
|
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"CloseComm: fd %d\n", fd);
|
|
#endif
|
|
|
|
if (close(fd) == -1) {
|
|
commerror = WinError();
|
|
return -1;
|
|
} else {
|
|
commerror = 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int SetCommBreak(int fd)
|
|
{
|
|
struct DosDeviceStruct *ptr;
|
|
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"SetCommBreak: fd: %d\n", fd);
|
|
#endif
|
|
|
|
if ((ptr = GetDeviceStruct(fd)) == NULL) {
|
|
commerror = IE_BADID;
|
|
return -1;
|
|
}
|
|
|
|
ptr->suspended = 1;
|
|
commerror = 0;
|
|
return 0;
|
|
}
|
|
|
|
int ClearCommBreak(int fd)
|
|
{
|
|
struct DosDeviceStruct *ptr;
|
|
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"ClearCommBreak: fd: %d\n", fd);
|
|
#endif
|
|
|
|
if ((ptr = GetDeviceStruct(fd)) == NULL) {
|
|
commerror = IE_BADID;
|
|
return -1;
|
|
}
|
|
|
|
ptr->suspended = 0;
|
|
commerror = 0;
|
|
return 0;
|
|
}
|
|
|
|
LONG EscapeCommFunction(int fd, int nFunction)
|
|
{
|
|
int max;
|
|
struct termios port;
|
|
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"EscapeCommFunction fd: %d, function: %d\n", fd, nFunction);
|
|
#endif
|
|
|
|
if (tcgetattr(fd, &port) == -1) {
|
|
commerror = WinError();
|
|
return -1;
|
|
}
|
|
|
|
switch (nFunction) {
|
|
case RESETDEV:
|
|
break;
|
|
|
|
case GETMAXCOM:
|
|
for (max = 0;COM[max].devicename;max++)
|
|
;
|
|
return max;
|
|
break;
|
|
|
|
case GETMAXLPT:
|
|
for (max = 0;LPT[max].devicename;max++)
|
|
;
|
|
return 0x80 + max;
|
|
break;
|
|
|
|
case CLRDTR:
|
|
port.c_cflag &= TIOCM_DTR;
|
|
break;
|
|
|
|
case CLRRTS:
|
|
port.c_cflag &= TIOCM_RTS;
|
|
break;
|
|
|
|
case SETDTR:
|
|
port.c_cflag |= CRTSCTS;
|
|
break;
|
|
|
|
case SETRTS:
|
|
port.c_cflag |= CRTSCTS;
|
|
break;
|
|
|
|
case SETXOFF:
|
|
port.c_iflag |= IXOFF;
|
|
break;
|
|
|
|
case SETXON:
|
|
port.c_iflag |= IXON;
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr,"EscapeCommFunction fd: %d, unknown function: %d\n", fd, nFunction);
|
|
break;
|
|
}
|
|
|
|
if (tcsetattr(fd, TCSADRAIN, &port) == -1) {
|
|
commerror = WinError();
|
|
return -1;
|
|
} else {
|
|
commerror = 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int FlushComm(int fd, int fnQueue)
|
|
{
|
|
int queue;
|
|
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"FlushComm fd: %d, queue: %d\n", fd, fnQueue);
|
|
#endif
|
|
|
|
switch (fnQueue) {
|
|
case 0:
|
|
queue = TCOFLUSH;
|
|
break;
|
|
case 1:
|
|
queue = TCIFLUSH;
|
|
break;
|
|
default:
|
|
fprintf(stderr,"FlushComm fd: %d, UNKNOWN queue: %d\n", fd, fnQueue);
|
|
return -1;
|
|
}
|
|
|
|
if (tcflush(fd, fnQueue)) {
|
|
commerror = WinError();
|
|
return -1;
|
|
} else {
|
|
commerror = 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int GetCommError(int fd, COMSTAT FAR *lpStat)
|
|
{
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"GetCommError: fd %d (current error %d)\n", fd, commerror);
|
|
#endif
|
|
|
|
return(commerror);
|
|
}
|
|
|
|
UINT FAR* SetCommEventMask(int fd, UINT fuEvtMask)
|
|
{
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"SetCommEventMask: fd %d, mask %d\n", fd, fuEvtMask);
|
|
#endif
|
|
|
|
eventmask |= fuEvtMask;
|
|
return (UINT *)&eventmask;
|
|
}
|
|
|
|
UINT GetCommEventMask(int fd, int fnEvtClear)
|
|
{
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"GetCommEventMask: fd %d, mask %d\n", fd, fnEvtClear);
|
|
#endif
|
|
eventmask &= ~fnEvtClear;
|
|
return eventmask;
|
|
}
|
|
|
|
int SetCommState(DCB FAR *lpdcb)
|
|
{
|
|
struct termios port;
|
|
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"SetCommState: fd %d, ptr %d\n", lpdcb->Id, lpdcb);
|
|
#endif
|
|
|
|
if (tcgetattr(lpdcb->Id, &port) == -1) {
|
|
commerror = WinError();
|
|
return -1;
|
|
}
|
|
cfmakeraw(&port);
|
|
port.c_cc[VMIN] = 0;
|
|
port.c_cc[VTIME] = 0;
|
|
|
|
fprintf(stderr,"SetCommState: baudrate %d\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 -1;
|
|
}
|
|
#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 -1;
|
|
}
|
|
port.c_ispeed = port.c_ospeed;
|
|
#endif
|
|
fprintf(stderr,"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 -1;
|
|
}
|
|
|
|
fprintf(stderr,"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 -1;
|
|
}
|
|
|
|
|
|
fprintf(stderr,"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 -1;
|
|
}
|
|
|
|
if (lpdcb->fDtrflow || lpdcb->fRtsflow || lpdcb->fOutxCtsFlow)
|
|
port.c_cflag |= CRTSCTS;
|
|
|
|
if (lpdcb->fDtrDisable)
|
|
port.c_cflag &= ~CRTSCTS;
|
|
|
|
if (lpdcb->fInX)
|
|
port.c_iflag |= IXON;
|
|
if (lpdcb->fOutX)
|
|
port.c_iflag |= IXOFF;
|
|
|
|
if (tcsetattr(lpdcb->Id, TCSADRAIN, &port) == -1) {
|
|
commerror = WinError();
|
|
return -1;
|
|
} else {
|
|
commerror = 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int GetCommState(int fd, DCB FAR *lpdcb)
|
|
{
|
|
struct termios port;
|
|
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"GetCommState: fd %d, ptr %d\n", fd, lpdcb);
|
|
#endif
|
|
|
|
if (tcgetattr(fd, &port) == -1) {
|
|
commerror = WinError();
|
|
return -1;
|
|
}
|
|
|
|
lpdcb->Id = fd;
|
|
|
|
#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->RlsTimeout = 50;
|
|
lpdcb->CtsTimeout = 50;
|
|
lpdcb->DsrTimeout = 50;
|
|
lpdcb->fNull = 0;
|
|
lpdcb->fChEvt = 0;
|
|
lpdcb->fBinary = 1;
|
|
|
|
lpdcb->fDtrDisable = 0;
|
|
if (port.c_cflag & CRTSCTS) {
|
|
lpdcb->fDtrflow = 1;
|
|
lpdcb->fRtsflow = 1;
|
|
lpdcb->fOutxCtsFlow = 1;
|
|
lpdcb->fOutxDsrFlow = 1;
|
|
} else
|
|
lpdcb->fDtrDisable = 1;
|
|
|
|
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 0;
|
|
}
|
|
|
|
int TransmitCommChar(int fd, char chTransmit)
|
|
{
|
|
struct DosDeviceStruct *ptr;
|
|
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"TransmitCommChar: fd %d, data %d \n", fd, chTransmit);
|
|
#endif
|
|
|
|
if ((ptr = GetDeviceStruct(fd)) == NULL) {
|
|
commerror = IE_BADID;
|
|
return -1;
|
|
}
|
|
|
|
if (ptr->suspended) {
|
|
commerror = IE_HARDWARE;
|
|
return -1;
|
|
}
|
|
|
|
if (write(fd, (void *) &chTransmit, 1) == -1) {
|
|
commerror = WinError();
|
|
return -1;
|
|
} else {
|
|
commerror = 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
int UngetCommChar(int fd, char chUnget)
|
|
{
|
|
struct DosDeviceStruct *ptr;
|
|
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"UngetCommChar: fd %d (char %d)\n", fd, chUnget);
|
|
#endif
|
|
|
|
if ((ptr = GetDeviceStruct(fd)) == NULL) {
|
|
commerror = IE_BADID;
|
|
return -1;
|
|
}
|
|
|
|
if (ptr->suspended) {
|
|
commerror = IE_HARDWARE;
|
|
return -1;
|
|
}
|
|
|
|
ptr->unget = 1;
|
|
ptr->unget_byte = chUnget;
|
|
|
|
commerror = 0;
|
|
return 0;
|
|
}
|
|
|
|
int ReadComm(int fd, LPSTR lpvBuf, int cbRead)
|
|
{
|
|
int status, length;
|
|
struct DosDeviceStruct *ptr;
|
|
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"ReadComm: fd %d, ptr %d, length %d\n", fd, lpvBuf, cbRead);
|
|
#endif
|
|
|
|
if ((ptr = GetDeviceStruct(fd)) == NULL) {
|
|
commerror = IE_BADID;
|
|
return -1;
|
|
}
|
|
|
|
if (ptr->suspended) {
|
|
commerror = IE_HARDWARE;
|
|
return -1;
|
|
}
|
|
|
|
if (ptr->unget) {
|
|
*lpvBuf = ptr->unget_byte;
|
|
lpvBuf++;
|
|
ptr->unget = 0;
|
|
|
|
length = 1;
|
|
} else
|
|
length = 0;
|
|
|
|
status = read(fd, (void *) lpvBuf, cbRead);
|
|
|
|
if (status == -1) {
|
|
commerror = WinError();
|
|
return -1 - length;
|
|
} else {
|
|
commerror = 0;
|
|
return length + status;
|
|
}
|
|
}
|
|
|
|
int WriteComm(int fd, LPSTR lpvBuf, int cbWrite)
|
|
{
|
|
int x, length;
|
|
struct DosDeviceStruct *ptr;
|
|
|
|
#ifdef DEBUG_COMM
|
|
fprintf(stderr,"WriteComm: fd %d, ptr %d, length %d\n", fd, lpvBuf, cbWrite);
|
|
#endif
|
|
|
|
if ((ptr = GetDeviceStruct(fd)) == NULL) {
|
|
commerror = IE_BADID;
|
|
return -1;
|
|
}
|
|
|
|
if (ptr->suspended) {
|
|
commerror = IE_HARDWARE;
|
|
return -1;
|
|
}
|
|
|
|
#ifdef DEBUG_COMM
|
|
for (x=0; x != cbWrite ; x++)
|
|
fprintf(stderr,"%c", *(lpvBuf + x) );
|
|
#endif
|
|
|
|
length = write(fd, (void *) lpvBuf, cbWrite);
|
|
|
|
if (length == -1) {
|
|
commerror = WinError();
|
|
return -1;
|
|
} else {
|
|
commerror = 0;
|
|
return length;
|
|
}
|
|
}
|