*** empty log message ***
authorClaus Gittinger <cg@exept.de>
Fri, 03 Feb 2006 16:19:09 +0100
changeset 9088 6ae1b16f69a7
parent 9087 9e28a6168468
child 9089 a4f9be44b52a
*** empty log message ***
Win32OperatingSystem.st
--- a/Win32OperatingSystem.st	Wed Feb 01 12:14:27 2006 +0100
+++ b/Win32OperatingSystem.st	Fri Feb 03 16:19:09 2006 +0100
@@ -65,6 +65,13 @@
 	privateIn:Win32OperatingSystem
 !
 
+Win32OperatingSystem::Win32Handle subclass:#Win32SerialPortHandle
+	instanceVariableNames:''
+	classVariableNames:''
+	poolDictionaries:''
+	privateIn:Win32OperatingSystem
+!
+
 Win32OperatingSystem::Win32Handle subclass:#Win32SocketHandle
 	instanceVariableNames:''
 	classVariableNames:''
@@ -6732,6 +6739,12 @@
     ^ RegistryEntry
 ! !
 
+!Win32OperatingSystem class methodsFor:'serial port support'!
+
+serialPortAccessor
+    ^ Win32SerialPortHandle
+! !
+
 !Win32OperatingSystem class methodsFor:'socket creation'!
 
 socketAccessor
@@ -8715,6 +8728,62 @@
     "
 ! !
 
+!Win32OperatingSystem::RegistryEntry class methodsFor:'misc queries'!
+
+executableForMimeType:mimeType
+    "given a mimeType, retrieve the path to an application from the registry"
+
+    |k suffix|
+
+    k := self key:'HKEY_CLASSES_ROOT\MIME\Database\Content Type\',mimeType.
+    k notNil ifTrue:[
+        suffix := k valueNamed:'extension'.
+        suffix notNil ifTrue:[
+            ^ self executableForSuffix:suffix
+        ].
+    ].
+    ^ nil 
+
+    "
+     self executableForMimeType:'application/pdf'  
+     self executableForMimeType:'audio/mp3'  
+     self executableForMimeType:'video/avi'  
+     self executableForMimeType:'application/x-zip-compressed'  
+    "
+!
+
+executableForSuffix:suffixArg
+    "given a suffix, retrieve the path to an application from the registry"
+
+    |k fkey cmd suffix|
+
+    suffix := suffixArg.
+    (suffix startsWith:'.') ifTrue:[
+        suffix := suffix copyFrom:2
+    ].
+    k := self key:'HKEY_CLASSES_ROOT\.',suffix.
+
+    k notNil ifTrue:[
+        fkey := (k valueNamed:'').
+    ].
+    fkey isNil ifTrue:[
+        fkey := suffix,'_auto_file'
+    ].
+    fkey notEmptyOrNil ifTrue:[
+        k := Win32OperatingSystem::RegistryEntry key:('HKEY_CLASSES_ROOT\' , fkey , '\shell\open\command').
+        k notNil ifTrue:[
+            cmd := k valueNamed:''
+        ].
+    ].
+
+    ^ cmd 
+
+    "
+     self executableForSuffix:'pdf' 
+     self executableForSuffix:'zip' 
+    "
+! !
+
 !Win32OperatingSystem::RegistryEntry class methodsFor:'registry access'!
 
 stringValueFor:valueName atKey:keyPath
@@ -9396,7 +9465,7 @@
     "some entry has been collected - close it"
 
     handle notNil ifTrue:[
-        self closeKey.
+	self closeKey.
     ]
 
     "Created: / 19.5.1999 / 22:39:52 / cg"
@@ -9446,7 +9515,7 @@
 !
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.191 2006-01-31 09:26:11 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.192 2006-02-03 15:19:09 cg Exp $'
 ! !
 
 !Win32OperatingSystem::Win32FILEHandle methodsFor:'release'!
@@ -9473,7 +9542,7 @@
 !
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.191 2006-01-31 09:26:11 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.192 2006-02-03 15:19:09 cg Exp $'
 ! !
 
 !Win32OperatingSystem::Win32Handle methodsFor:'io'!
@@ -9855,6 +9924,352 @@
     ^ pid
 ! !
 
+!Win32OperatingSystem::Win32SerialPortHandle methodsFor:'opening'!
+
+open:portName baudRate:baudRate stopBitsType:stopBitsType
+		    parityType:parityType dataBits:dataBits
+		    inFlowCtrl:inFlowCtrlType outFlowCtrl:outFlowCtrlType
+		    xOnChar:xOnChar xOffChar:xOffChar
+    "portName: COM%d
+     baudRate: Integer
+     stopBitsType: #stop1, #stop2 or #stop1_5
+     parityType: #odd, #even or #none
+     dataBits: #integer
+     inFlowCtrlType: #xOnOff #hardware
+     outFlowCtrlType: #xOnOff #hardware
+     xOnChar: Character or Integer
+     xOffChar: Character or Integer"
+
+    |errorNumber|
+
+%{
+    HANDLE port;
+    COMMTIMEOUTS timeouts;
+    DCB dcb;
+    char *__portName;
+    int __setBaudRate = 1,
+	__setDataBits = 1,
+	__setXOnChar = 1,
+	__setXOffChar = 1,
+	__setInFlowCtrl = 1,
+	__setOutFlowCtrl = 1,
+	__setStopBits = 1,
+	__setParityType = 1;
+    int __baudRate, __dataBits;
+    int __xOnChar, __xOffChar;
+    int __inFlowCtrl, __outFlowCtrl;
+    int __stopBits, __parityType;
+#   define XONOFF       1
+#   define HARDWARE     2
+#   define STOP1     1
+#   define STOP2     2
+#   define STOP1_5   3
+#   define ODD       1
+#   define EVEN      2
+#   define NONE      3
+
+    if (__isString(portName)) {
+	__portName = __stringVal(portName);
+    } else {
+	goto failure;
+    }
+    if (__isSmallInteger(baudRate)) {
+	__baudRate = __intVal(baudRate);
+    } else if (baudRate == nil) {
+	__setBaudRate = 0;
+    } else {
+	goto failure;
+    }
+
+    if (__isSmallInteger(dataBits)) {
+	__dataBits = __intVal(dataBits);
+    } else if (dataBits == nil) {
+	__setDataBits = 0;
+    } else {
+	goto failure;
+    }
+
+    if (__isSmallInteger(xOnChar)) {
+	__xOnChar = __intVal(xOnChar);
+    } else if (__isCharacter(xOnChar)) {
+	__xOnChar = __intVal(_characterVal(xOnChar));
+    } else if (xOnChar == nil) {
+	__setXOnChar = 0;
+    } else {
+	goto failure;
+    }
+
+    if (__isSmallInteger(xOffChar)) {
+	__xOffChar = __intVal(xOffChar);
+    } else if (__isCharacter(xOffChar)) {
+	__xOffChar = __intVal(_characterVal(xOffChar));
+    } else if (xOffChar == nil) {
+	__setXOffChar = 0;
+    } else {
+	goto failure;
+    }
+
+    if (inFlowCtrlType == @symbol(xOnOff)) {
+	__inFlowCtrl = XONOFF;
+    } else if (inFlowCtrlType == @symbol(hardware)) {
+	__inFlowCtrl = HARDWARE;
+    } else if (inFlowCtrlType == nil) {
+	__setInFlowCtrl = 0;
+    } else {
+	goto failure;
+    }
+
+    if (outFlowCtrlType == @symbol(xOnOff)) {
+	__outFlowCtrl = XONOFF;
+    } else if (outFlowCtrlType == @symbol(hardware)) {
+	__outFlowCtrl = HARDWARE;
+    } else if (outFlowCtrlType == nil) {
+	__setOutFlowCtrl = 0;
+    } else {
+	goto failure;
+    }
+
+    if (stopBitsType == @symbol(stop1)) {
+	__stopBits = STOP1;
+    } else if (stopBitsType == @symbol(stop2)) {
+	__stopBits = STOP2;
+    } else if (stopBitsType == @symbol(stop1_5)) {
+	__stopBits = STOP1_5;
+    } else if (stopBitsType == nil) {
+	__setStopBits = 0;
+    } else {
+	goto failure;
+    }
+
+    port = CreateFile(__portName,
+	      GENERIC_READ | GENERIC_WRITE,
+	      0,             /* comm devices must be opened with exclusive access */
+	      NULL,          /* no security attrs */
+	      OPEN_EXISTING, /* comm devices must use OPEN_EXISTING */
+	      0,             /* no overlapped I/O */
+	      NULL           /* hTemplate must be NULL for comm devices */
+	   );
+    if (port == INVALID_HANDLE_VALUE) {
+	fprintf(stderr, "Win32OS [info]: serial port open failed\n");
+	errorNumber = __mkSmallInteger( __WIN32_ERR(GetLastError()) );
+	goto failure;
+    }
+    /* Flush the driver */
+    PurgeComm( port, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
+
+    /* Set driver buffer sizes */
+    SetupComm( port, 4096 /*SERIAL_IN_QUEUE_SIZE*/, 4096 /*SERIAL_OUT_QUEUE_SIZE*/);
+
+    /* Reset timeout constants */
+    timeouts.ReadIntervalTimeout= 0xFFFFFFFF;
+    timeouts.ReadTotalTimeoutMultiplier = 0;
+    timeouts.ReadTotalTimeoutConstant = 0;
+    timeouts.WriteTotalTimeoutMultiplier = 0;
+    timeouts.WriteTotalTimeoutConstant = 0;
+    SetCommTimeouts( port, &timeouts );
+
+    /* Set communication parameters */
+    ZeroMemory(&dcb, sizeof(dcb));
+    dcb.DCBlength = sizeof(dcb);
+    GetCommState(port, &dcb);
+
+    if (__setBaudRate) dcb.BaudRate = __baudRate;
+    if (__setDataBits) dcb.ByteSize = __dataBits;
+    if (__setXOnChar)  dcb.XonChar = __xOnChar;
+    if (__setXOffChar) dcb.XoffChar = __xOffChar;
+
+    if (__setStopBits) {
+	/* set stop bits */
+	switch(__stopBits) {
+	    case STOP1_5: dcb.StopBits = 1; break; /* 1.5 stop bits */
+	    case STOP1: dcb.StopBits = 0; break; /* 1 stop bit */
+	    case STOP2: dcb.StopBits = 2; break; /* 2 stop bits */
+	    default: goto errExit;
+	}
+    }
+
+    if (__setParityType) {
+	/* set parity */
+	switch(__parityType) {
+	    case NONE: dcb.Parity = NOPARITY; break;
+	    case ODD: dcb.Parity = ODDPARITY; break;
+	    case EVEN: dcb.Parity = EVENPARITY; break;
+	    default: goto errExit;
+	}
+    }
+
+    if (__setInFlowCtrl) {
+	/* set control flow */
+	dcb.fInX = FALSE;
+	dcb.fDtrControl = FALSE;
+	if (__inFlowCtrl == XONOFF) dcb.fInX = TRUE;  /* XOn/XOff handshaking */
+	if (__inFlowCtrl == HARDWARE) dcb.fDtrControl = TRUE;  /* hardware handshaking */
+    }
+    if (__setOutFlowCtrl) {
+	dcb.fOutX = FALSE;
+	dcb.fOutxCtsFlow = FALSE;
+
+	if (__outFlowCtrl == XONOFF) dcb.fOutX = TRUE;  /* XOn/XOff handshaking */
+	if (__outFlowCtrl == HARDWARE) dcb.fOutxCtsFlow = TRUE;  /* hardware handshaking */
+    }
+
+    if (SetCommState(port, &dcb)) {
+	RETURN( true );
+    }
+
+    fprintf(stderr, "Win32OS [info]: serial port comm-setup failed\n");
+    errorNumber = __mkSmallInteger( __WIN32_ERR(GetLastError()) );
+    /* fall into */
+errExit: ;
+    CloseHandle(port);
+
+failure: ;
+#   undef XONOFF
+#   undef HARDWARE
+#   undef STOP1
+#   undef STOP2
+#   undef STOP1_5
+#   undef ODD
+#   undef EVEN
+#   undef NONE
+%}.
+    errorNumber isNil ifTrue:[
+	self error:'invalid argument(s)'.
+    ] ifFalse:[
+	(OperatingSystem errorHolderForNumber:errorNumber) reportError
+    ].
+! !
+
+!Win32OperatingSystem::Win32SerialPortHandle methodsFor:'release'!
+
+closeFile
+    "close the handle"
+
+%{
+    HANDLE port = (HANDLE)(__externalAddressVal(self));
+
+    if (port) {
+	__externalAddressVal(self) = (HANDLE)0;
+	PurgeComm( port, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
+	CloseHandle(port);
+    }
+%}.
+! !
+
+!Win32OperatingSystem::Win32SerialPortHandle methodsFor:'setup'!
+
+baudRate:newRate
+%{
+    HANDLE port = (HANDLE)(__externalAddressVal(self));
+
+    if (port
+     && __isSmallInteger(newRate)) {
+	DCB dcb;
+
+	ZeroMemory(&dcb, sizeof(dcb));
+	dcb.DCBlength = sizeof(dcb);
+	GetCommState(port, &dcb);
+
+	dcb.BaudRate = __intVal(newRate);
+
+	if (! SetCommState(port, &dcb)) {
+	    RETURN(false);
+	}
+	RETURN(true);
+    }
+%}.
+    self primitiveFailed.
+!
+
+dataBits:newNumberOfBits
+%{
+    HANDLE port = (HANDLE)(__externalAddressVal(self));
+
+    if (port
+     && __isSmallInteger(newNumberOfBits)) {
+	DCB dcb;
+
+	ZeroMemory(&dcb, sizeof(dcb));
+	dcb.DCBlength = sizeof(dcb);
+	GetCommState(port, &dcb);
+
+	dcb.ByteSize = __intVal(newNumberOfBits);
+
+	if (! SetCommState(port, &dcb)) {
+	    RETURN(false);
+	}
+	RETURN(true);
+    }
+%}.
+    self primitiveFailed.
+!
+
+parityType:newParityTypeSymbol
+    "newParityTypeSymbol must be one of #odd, #even or #none (or nil)"
+
+%{
+    HANDLE port = (HANDLE)(__externalAddressVal(self));
+
+    if (port) {
+	DCB dcb;
+
+	ZeroMemory(&dcb, sizeof(dcb));
+	dcb.DCBlength = sizeof(dcb);
+	GetCommState(port, &dcb);
+
+
+	if ((newParityTypeSymbol == nil) || (newParityTypeSymbol == @symbol(none))) {
+	    dcb.Parity = NOPARITY;
+	} else if (newParityTypeSymbol == @symbol(odd)) {
+	    dcb.Parity = ODDPARITY;
+	} else if (newParityTypeSymbol == @symbol(even)) {
+	    dcb.Parity = EVENPARITY;
+	} else {
+	    goto failure;
+	}
+
+	if (! SetCommState(port, &dcb)) {
+	    RETURN(false);
+	}
+	RETURN(true);
+    }
+  failure: ;
+%}.
+    self primitiveFailed.
+!
+
+stopBitsType:newStopBitsSymbol
+    "newParityTypeSymbol must be one of #stop1, #stop2 or #stop1_5"
+%{
+    HANDLE port = (HANDLE)(__externalAddressVal(self));
+
+    if (port) {
+	DCB dcb;
+
+	ZeroMemory(&dcb, sizeof(dcb));
+	dcb.DCBlength = sizeof(dcb);
+	GetCommState(port, &dcb);
+
+	if (newStopBitsSymbol == @symbol(stop1)) {
+	    dcb.Parity = 0 /* STOP1 */;
+	} else if (newStopBitsSymbol == @symbol(stop2)) {
+	    dcb.Parity = 2 /* STOP2 */;
+	} else if (newStopBitsSymbol == @symbol(stop1_5)) {
+	    dcb.Parity = 1 /* STOP1_5 */;
+	} else {
+	    goto failure;
+	}
+
+	if (! SetCommState(port, &dcb)) {
+	    RETURN(false);
+	}
+	RETURN(true);
+    }
+  failure: ;
+%}.
+    self primitiveFailed.
+! !
+
 !Win32OperatingSystem::Win32SocketHandle class methodsFor:'constants'!
 
 protocolCodeOf:aNameOrNumber
@@ -10493,7 +10908,7 @@
 !Win32OperatingSystem class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.191 2006-01-31 09:26:11 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libbasic/Win32OperatingSystem.st,v 1.192 2006-02-03 15:19:09 cg Exp $'
 ! !
 
 Win32OperatingSystem initialize!