175 lines
7.3 KiB
Scheme
175 lines
7.3 KiB
Scheme
(define-c-library libc '("stdlib.h") #f '())
|
|
(define-c-procedure c-perror libc 'perror 'void '(pointer))
|
|
|
|
(define-c-library c-gi
|
|
'("girepository/girepository.h")
|
|
"girepository-2.0"
|
|
'((additional-versions ("0"))))
|
|
|
|
|
|
(define-c-procedure c-gi-repository-new c-gi 'gi_repository_new 'pointer '())
|
|
(define-c-procedure c-gi-repository-require c-gi 'gi_repository_require 'pointer '(pointer pointer pointer int pointer))
|
|
(define-c-procedure c-gi-repository-find-by-name c-gi 'gi_repository_find_by_name 'pointer '(pointer pointer pointer))
|
|
|
|
(define-c-procedure c-gi-base-info-get-name c-gi 'gi_base_info_get_name 'pointer '(pointer))
|
|
(define-c-procedure c-gi-base-info-get-namespace c-gi 'gi_base_info_get_namespace 'pointer '(pointer))
|
|
(define-c-procedure c-gi-base-info-get-typelib c-gi 'gi_base_info_get_typelib 'pointer '(pointer))
|
|
(define-c-procedure c-gi-base-info-get-attribute c-gi 'gi_base_info_get_attribute 'pointer '(pointer pointer))
|
|
(define-c-procedure c-gi-base-info-get-namespace c-gi 'gi_base_info_get_namespace 'pointer '(pointer))
|
|
|
|
(define-c-procedure c-gi-function-info-invoke c-gi 'gi_function_info_invoke 'int '(pointer pointer int pointer int pointer pointer))
|
|
|
|
(define-c-procedure c-gi-callable-info-get-return-type c-gi 'gi_callable_info_get_return_type 'pointer '(pointer))
|
|
(define-c-procedure c-gi-callable-info-get-n-args c-gi 'gi_callable_info_get_n_args 'uint '(pointer))
|
|
(define-c-procedure c-gi-callable-info-get-arg c-gi 'gi_callable_info_get_arg 'pointer '(pointer uint))
|
|
|
|
(define-c-procedure c-gi-arg-info-get-type-info c-gi 'gi_arg_info_get_type_info 'pointer '(pointer))
|
|
|
|
(define-c-procedure c-gi-type-info-get-tag c-gi 'gi_type_info_get_tag 'uint '(pointer))
|
|
(define-c-procedure c-gi-type-info-get-interface c-gi 'gi_type_info_get_interface 'pointer '(pointer))
|
|
|
|
|
|
|
|
(define-c-procedure c-gi-object-info-find-method c-gi 'gi_object_info_find_method 'pointer '(pointer pointer))
|
|
|
|
(define-c-struct-type gerror '((domain u32) (code int) (message pointer)))
|
|
|
|
(define GI-TYPE-TAG-UTF8 13)
|
|
(define GI-TYPE-TAG-INTERFACE 16)
|
|
|
|
(define (gi-repository name version)
|
|
(let ((repository (c-gi-repository-new))
|
|
(err (c-bytevector-null)))
|
|
(call-with-address-of
|
|
err
|
|
(lambda (err-address)
|
|
(c-gi-repository-require repository
|
|
(string->c-bytevector name)
|
|
(string->c-bytevector version)
|
|
0
|
|
err-address)))
|
|
(when (not (c-bytevector-null? err))
|
|
(let* ((error-list (c-bytevector->list pointer gerror))
|
|
(msg (c-bytevector->string (cdr (assoc 'message error-list)))))
|
|
(c-bytevector-free (cdr (assoc 'message error-list)))
|
|
(c-bytevector-free repository)
|
|
;(c-bytevector-free err)
|
|
(error (string-append "load-gi-repository: " msg)
|
|
(car error-list)
|
|
(cadr error-list))))
|
|
repository))
|
|
|
|
(define (gi-object repository namespace name)
|
|
(let ((base-info
|
|
(c-gi-repository-find-by-name repository
|
|
(string->c-bytevector namespace)
|
|
(string->c-bytevector name))))
|
|
(when (c-bytevector-null? base-info)
|
|
(c-perror (string->c-bytevector "(C perror) gi-object"))
|
|
(error "gi-object: ERROR" namespace name base-info))
|
|
base-info))
|
|
|
|
(define (gi-info-namespace info)
|
|
(c-bytevector->string (c-gi-base-info-get-namespace info)))
|
|
(define gi-object-namespace gi-info-namespace)
|
|
|
|
(define (gi-info-name info)
|
|
(c-bytevector->string (c-gi-base-info-get-name info)))
|
|
(define gi-object-name gi-info-name)
|
|
|
|
(define (gi-type->foreign-c-type type-info)
|
|
(let ((tag (c-gi-type-info-get-tag type-info)))
|
|
(cond
|
|
((= tag GI-TYPE-TAG-UTF8) 'pointer)
|
|
((= tag GI-TYPE-TAG-INTERFACE)
|
|
(display "HERE: ")
|
|
(write (c-bytevector->string (c-gi-base-info-get-namespace (c-gi-type-info-get-interface type-info))))
|
|
(newline)
|
|
(write (c-bytevector->string (c-gi-base-info-get-name (c-gi-type-info-get-interface type-info))))
|
|
(newline)
|
|
'int) ;; FIXME
|
|
)))
|
|
|
|
|
|
(define (gi-object-invoke object method-name . args)
|
|
(letrec*
|
|
((method-info (c-gi-object-info-find-method object method-name))
|
|
(method-return-info (c-gi-callable-info-get-return-type method-info))
|
|
(return-type (gi-type->foreign-c-type method-return-info))
|
|
(n-args (let ((n-args (c-gi-callable-info-get-n-args method-info)))
|
|
(when (not (= n-args (length args)))
|
|
(error
|
|
(string-append "gi-object-invoke: Argument count mismatch, got "
|
|
(number->string (length args))
|
|
", wanted "
|
|
(number->string n-args))
|
|
(gi-object-namespace object)
|
|
(gi-object-name object)
|
|
method-name))
|
|
n-args))
|
|
(arg-info-looper
|
|
(lambda (index result)
|
|
(if (= index n-args)
|
|
result
|
|
(arg-info-looper
|
|
(+ index 1)
|
|
(append
|
|
result
|
|
(list
|
|
(let* ((arg-info (c-gi-callable-info-get-arg method-info index))
|
|
(type-info (c-gi-arg-info-get-type-info arg-info))
|
|
(type (gi-type->foreign-c-type type-info)))
|
|
(cons type (list-ref args index)))))))))
|
|
(arg-info (arg-info-looper 0 '()))
|
|
(arg-cbv (make-c-bytevector 1024))
|
|
(arg-cbv-offset 0)
|
|
(invoke-error (c-bytevector-null))
|
|
(return-value (make-c-bytevector 1024)))
|
|
(for-each
|
|
(lambda (arg)
|
|
(c-bytevector-set! arg-cbv
|
|
(car arg)
|
|
arg-cbv-offset
|
|
(if (string? (cdr arg))
|
|
(string->c-bytevector (cdr arg))
|
|
(cdr arg)))
|
|
(set! arg-cbv-offset (+ arg-cbv-offset (c-type-size (car arg)))))
|
|
arg-info)
|
|
(c-gi-function-info-invoke method-info
|
|
arg-cbv
|
|
n-args
|
|
(c-bytevector-null)
|
|
0
|
|
return-value
|
|
invoke-error)
|
|
(display "HERE: return-type ")
|
|
(write return-type)
|
|
(newline)
|
|
return-value))
|
|
|
|
|
|
|
|
|
|
|
|
(define (gi-repository-find-by-name repository namespace name)
|
|
(let ((base-info
|
|
(c-gi-repository-find-by-name repository
|
|
(string->c-bytevector namespace)
|
|
(string->c-bytevector name))))
|
|
(when (c-bytevector-null? base-info)
|
|
(c-perror (string->c-bytevector "(C perror) find-gi-function"))
|
|
(error "find-gi-function: ERROR" namespace name base-info))
|
|
base-info))
|
|
|
|
(define (gi-invoke function-info argv argc return-type)
|
|
(let ((return-value (make-c-bytevector 1024))
|
|
(invoke-error (c-bytevector-null)))
|
|
(c-gi-function-info-invoke function-info
|
|
argv
|
|
argc
|
|
(c-bytevector-null)
|
|
0
|
|
return-value
|
|
invoke-error)
|
|
(c-bytevector-ref return-value return-type 0)))
|