(module ddeclient mzscheme
(require (lib "foreign.ss" "mzlib"))
(require (only (lib "contract.ss") provide/contract natural-number/c or/c any))
(require (rename (lib "contract.ss") --> ->))
(unsafe!)
(provide/contract
(dde-connect (--> string? string? any))
(dde-disconnect (--> natural-number/c any))
(dde-cmd (--> natural-number/c
(lambda (in)
(or (string=? in "execute")
(string=? in "poke")
(string=? in "request")
))
(lambda (in) (and (string? in) (< (string-length in) 256)))
string?
string?
natural-number/c
(lambda (in)
(or (string=? in "byte")
(string=? in "string")
(string=? in "")
))
any))
(dde-request (--> natural-number/c
(lambda (in) (and (string? in) (< (string-length in) 256)))
string? natural-number/c any))
(dde-request-string (--> natural-number/c
(lambda (in) (and (string? in)
(< (string-length in) 256)))
natural-number/c any))
(dde-execute (--> natural-number/c
(lambda (in) (and (string? in) (< (string-length in) 256)))
natural-number/c any))
(dde-poke (--> natural-number/c
(lambda (in) (and (string? in) (< (string-length in) 256)))
string? natural-number/c any))
(dde-data-pointer (--> natural-number/c))
(dde-data-length (--> natural-number/c))
(dde-data-string (--> natural-number/c))
(dde-data-id-trans (--> natural-number/c))
(dc-dde-disconnect (--> natural-number/c any))
(dc-dde-cmd (--> natural-number/c
(lambda (in)
(or (string=? in "execute")
(string=? in "poke")
(string=? in "request")
))
string?
string?
string?
natural-number/c
(lambda (in)
(or (string=? in "byte")
(string=? in "string")
(string=? in "")
))
any))
(dc-dde-request (--> natural-number/c string? string? natural-number/c any))
(dc-dde-request-string (--> natural-number/c string? natural-number/c any))
(dc-dde-asynch-transaction-completed (--> natural-number/c natural-number/c boolean? any))
(dc-dde-abandon-transaction (--> natural-number/c natural-number/c any))
(dc-dde-free-mem (--> natural-number/c any))
)
(provide
dde-init
dde-uninit
dde-error-head
dc-dde-init
dc-dde-uninit
dc-dde-connect
dc-dde-finalize
dc-dde-version
dc-dde-last-error
)
(define _bytebool
(make-ctype _byte
(lambda (bool) (if bool 1 0))
(lambda (byte) (not (zero? byte)))))
(define *dir*
(let-syntax ((current-module-directory
(lambda (stx)
(datum->syntax-object
stx (current-load-relative-directory)))))
(current-module-directory)))
(define dde-client-dll (ffi-lib (build-path *dir* "dll" "DDEClient")))
(define dc-dde-init (get-ffi-obj "DCInit" dde-client-dll
(_fun -> _bytebool)))
(define dc-dde-uninit (get-ffi-obj "DCUninit" dde-client-dll
(_fun -> _bytebool)))
(define dc-dde-connect (get-ffi-obj "DCConnect" dde-client-dll
(_fun _pointer _string _string -> _bytebool)))
(define dc-dde-disconnect (get-ffi-obj "DCDisconnect" dde-client-dll
(_fun _word -> _bytebool)))
(define dc-dde-cmd (get-ffi-obj "DCTransaction" dde-client-dll
(_fun _word _string _string _string
_string _uint32 _string -> _bytebool)
)
)
(define dc-dde-request (get-ffi-obj "DCRequest" dde-client-dll
(_fun _word _string _string _int -> _bytebool)
)
)
(define dc-dde-request-string (get-ffi-obj "DCRequestString" dde-client-dll
(_fun _word _string _int -> _bytebool)
)
)
(define dc-dde-asynch-transaction-completed
(get-ffi-obj "DCAsynchTransactionCompleted" dde-client-dll
(_fun _word _uint32 _bool -> _bytebool)))
(define dc-dde-free-mem (get-ffi-obj "DCFreeDdeMem" dde-client-dll
(_fun _word -> _bytebool)))
(define dc-dde-finalize (get-ffi-obj "DCFinalize" dde-client-dll
(_fun -> _void)))
(define dc-dde-abandon-transaction
(get-ffi-obj "DCAbandonTransaction" dde-client-dll
(_fun _word _uint32 -> _bytebool)))
(define dc-dde-version (get-ffi-obj "DCVersion" dde-client-dll
(_fun -> _string)))
(define dc-dde-last-error (get-ffi-obj "DCLastError" dde-client-dll
(_fun -> _string)))
(define dc-dde-import-errors? (get-ffi-obj "bDCErrorExport" dde-client-dll _bytebool))
(define-cstruct _dde-struct ((ptr _pointer)(len _uint32)(str _string)
(id-trans _uint32)(id-trans-cb _uint32)
(access _string)))
(define dde-conv-pointer (get-ffi-obj "DCDA" dde-client-dll _pointer))
(define (dde-struct-pointer conv)
(ptr-ref (ptr-ref dde-conv-pointer _pointer conv) _dde-struct))
(define (dde-data-pointer conv)
(dde-struct-ptr (dde-struct-pointer conv)))
(define (dde-data-length conv)
(dde-struct-len (dde-struct-pointer conv)))
(define (dde-data-string conv)
(dde-struct-str (dde-struct-pointer conv)))
(define (dde-data-id-trans conv)
(dde-struct-id-trans (dde-struct-pointer conv)))
(define dde-error-head "DDE Client DLL Error:")
(define (dde-error)
(raise-user-error dde-error-head (dc-dde-last-error))
)
(define (dde-error-in-cmd conv)
(let((error-message (dc-dde-last-error)))
(dc-dde-disconnect conv)
(dc-dde-uninit)
(raise-user-error dde-error-head error-message)
)
)
(set-ffi-obj! "bDCErrorExport" dde-client-dll _bytebool #t)
(define (dde-init)
(if(not(dc-dde-init))
(dde-error)
)
)
(define (dde-uninit)
(if(not(dc-dde-uninit))
(dde-error)
)
)
(define (dde-connect service topic)
(let((conversation-ptr (malloc _word))
(conversation-no 0)
)
(if (dc-dde-connect conversation-ptr service topic)
(begin
(set! conversation-no (ptr-ref conversation-ptr _word))
(free conversation-ptr)
conversation-no
)
(raise-user-error dde-error-head (dc-dde-last-error)) )
)
)
(define (dde-disconnect conv)
(if(not(dc-dde-disconnect conv))
(dde-error)
)
)
(define (access-dde-data-bytes conv)
(let ((dde-data (bytes-copy (make-sized-byte-string
(dde-data-pointer conv)
(- (dde-data-length conv) 1))))
)
(dc-dde-free-mem conv)
dde-data
)
)
(define (access-dde-data-string conv)
(let ((dde-data (string-copy (dde-data-string conv))))
(dc-dde-free-mem conv)
dde-data
)
)
(define (access-dde-data conv format)
(if (string=? format "string")
(access-dde-data-string conv)
(access-dde-data-bytes conv)
)
)
(define (dde-cmd conv type item data format timeout access)
(if (dc-dde-cmd conv type item data format timeout access)
(cond ((string=? type "request")
(cond ((> timeout 0)
(access-dde-data conv access)
)
((= timeout 0)
(if (dc-dde-asynch-transaction-completed
conv (dde-data-id-trans conv) #t)
(access-dde-data conv access)
(dde-error-in-cmd conv)
)
)
)
)
((or (string=? type "execute")
(string=? type "poke"))
(if (= timeout 0)
(if (dc-dde-asynch-transaction-completed conv (dde-data-id-trans conv) #t)
#t
(dde-error-in-cmd conv)
)
)
)
)
(dde-error-in-cmd conv)
)
)
(define (dde-request conv item format timeout)
(if (dc-dde-request conv item format timeout)
(cond ((> timeout 0)
(access-dde-data-bytes conv)
)
((= timeout 0)
(if (dc-dde-asynch-transaction-completed
conv (dde-data-id-trans conv) #t)
(access-dde-data-bytes conv)
(dde-error-in-cmd conv)
)
)
)
(dde-error-in-cmd conv)
)
)
(define (dde-request-string conv item timeout)
(if (dc-dde-request-string conv item timeout)
(cond ((> timeout 0)
(access-dde-data-string conv)
)
((= timeout 0)
(if (dc-dde-asynch-transaction-completed
conv (dde-data-id-trans conv) #t)
(access-dde-data-string conv)
(dde-error-in-cmd conv)
)
)
)
(dde-error-in-cmd conv)
)
)
(define (dde-execute conv item timeout)
(if (dc-dde-cmd conv "execute" item "" "CF_TEXT" timeout "")
(if (= timeout 0)
(if (not(dc-dde-asynch-transaction-completed conv (dde-data-id-trans conv) #t))
(dde-error-in-cmd conv)
)
)
(dde-error-in-cmd conv)
)
)
(define (dde-poke conv item data timeout)
(if (dc-dde-cmd conv "poke" item data "CF_TEXT" timeout "")
(if (= timeout 0)
(if (not (dc-dde-asynch-transaction-completed conv (dde-data-id-trans conv) #t))
(dde-error-in-cmd conv)
)
)
(dde-error-in-cmd conv)
)
)
)