diff options
author | David Pirotte <david@altosw.be> | 2023-02-08 23:54:38 -0300 |
---|---|---|
committer | David Pirotte <david@altosw.be> | 2023-02-08 23:54:38 -0300 |
commit | a4e9fc569cd7968896358518e8c23747cefffcc9 (patch) | |
tree | a2f6dc12a0f6359e31d1f864b8c8bf7a680b53b2 | |
parent | 6a9e1801d158d40c9a355d7fd3925cb736f753df (diff) | |
parent | 482da16aab02184dffff1f25f29e7d3c379b9c85 (diff) |
Prepare 0.8.0-a.3v0.8.0-a.3
* Merge branch 'devel'.
-rw-r--r-- | INSTALL | 8 | ||||
-rw-r--r-- | NEWS | 75 | ||||
-rw-r--r-- | README | 4 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rwxr-xr-x | examples/gtk-4/clipboard.scm | 4 | ||||
-rwxr-xr-x | examples/gtk-4/css-basics.scm | 4 | ||||
-rwxr-xr-x | examples/gtk-4/drawing-widget.scm | 2 | ||||
-rwxr-xr-x | examples/gtk-4/hello-world.scm | 4 | ||||
-rwxr-xr-x | examples/gtk-4/peg-solitaire.scm | 19 | ||||
-rwxr-xr-x | examples/gtk-4/revealer.scm | 4 | ||||
-rwxr-xr-x | examples/gtk-4/search-bar.scm | 4 | ||||
-rw-r--r-- | g-golf/hl-api/argument.scm | 11 | ||||
-rw-r--r-- | g-golf/hl-api/callable.scm | 234 | ||||
-rw-r--r-- | g-golf/hl-api/callback.scm | 115 | ||||
-rw-r--r-- | g-golf/hl-api/ccc.scm | 6 | ||||
-rw-r--r-- | g-golf/hl-api/function.scm | 6 | ||||
-rw-r--r-- | g-golf/override/gtk.scm | 6 | ||||
-rw-r--r-- | g-golf/override/override.scm | 4 | ||||
-rw-r--r-- | g-golf/support/ffi.scm | 206 | ||||
-rw-r--r-- | g-golf/support/libg-golf.scm | 32 | ||||
-rw-r--r-- | libg-golf/gg-ffi.c | 41 | ||||
-rw-r--r-- | libg-golf/gg-ffi.h | 16 |
22 files changed, 671 insertions, 136 deletions
@@ -39,8 +39,8 @@ GNU G-Golf needs the following software to run: G-Golf release are [[http://ftp.gnu.org/gnu/g-golf/][here]]. The latest tarballs are: - g-golf-0.8.0-a.2.tar.gz - g-golf-0.8.0-a.2.tar.gz.sig + g-golf-0.8.0-a.3.tar.gz + g-golf-0.8.0-a.3.tar.gz.sig [ GPG Key: A3057AD7 [ gpg --keyserver keys.gnupg.net --recv-keys A3057AD7 @@ -49,8 +49,8 @@ Assuming you have satisfied the dependencies, open a terminal and proceed with the following steps: cd <download-path> - tar zxf g-golf-0.8.0-a.2.tar.gz - cd g-golf-0.8.0-a.2 + tar zxf g-golf-0.8.0-a.3.tar.gz + cd g-golf-0.8.0-a.3 ./configure [--prefix=/your/prefix] [--with-guile-site=yes] make make install @@ -26,6 +26,77 @@ warranty. * Latest News +** February 2023 + +[[http://www.gnu.org/software/g-golf][GNU G-Golf]] version 0.8.0-a.3 is released. + +This is the third release of the upcoming 0.8.0 release, now available +for testing. + +*** Changes since 0.8.0-a.2 + +Here is a summary of the noteworthy changes since version 0.8.0-a.2. See +G-Golf [[http://git.savannah.gnu.org/cgit/g-golf.git][git summary]] and [[http://git.savannah.gnu.org/cgit/g-golf.git/log/][git log]] for a complete list and description. + +**** Enhancement + +Skip Array Length Argument(s) + +This release implements skip array-length argument mechanism. This +affects all functions and methods of any upstream (type)lib that accept +one or more array argument(s), for which the function or method also +expect an array length argument. + +Starting with this release, users don't have to pass those array length +arg(s) (more accurately, users may not pass those arg(s) anymore), as +G-Golf will supply those automatically. Note that this is also valid for +arrays of uint8 - those arg(s) are 'array of chars', that users must +provide as a string (as opposed to a list) - for example, see the +peg-solitaire example, updated accordingly, so that the +gtk-css-provider-load-from-data call does no longer provide the 'data' +array length argument. + +**** Examples + +All + +Updated, wrt the above enhancement, to call the g-application-run method +'without' the args length argument. + +Peg Solitaire + +In addition, updating the call to gtk-css-provider-load-from-data, +removing the 'data' array length argument. + +**** Bug fixing + +Callback and VFunc + +In G-Golf, both Callback and VFunc use one (identical) marshal +procedure, g-golf-callback-closure-marshal, entirely written in scheme, +which implements, in short, the foreign function interface (ffi) arg +retrieval and transfornmation into their scheme representation, then +call the callback of vfunc (user provided) scheme code, then sets the GI +argument to the return value (if any). + +To obtain the ffi arg scheme representation values, G-Golf was calling +gi-type-info-extract-ffi-return-value (a GI function, in the girffi +module, not a G-Golf procedure) - but that function has some bug. + +G-Golf has now been updated so g-golf-callback-closure-marshal calls a +'self made' ffi-args->scm (see commit 6a30a12dd) for further details on +this). + +Peg Solitaire + +The peg-solitaire example has been updated, as the Callback and VFunc +bug fixed its snapshot-vfunc method. More specifically its width and +height argument values are now correct, we no longer need to explicitly +call get-intrinsic-width and get-intrinsic-height. + + +* Older News + ** January 2023 [[http://www.gnu.org/software/g-golf][GNU G-Golf]] version 0.8.0-a.2 is released. @@ -86,6 +157,4 @@ GObject.TypeInstance GObject.TypeInstance fundamental class support fix. They must inherit <gtype-instance> and specify <gtype-class> as their metaclass. -* Older News - -For older News, see [[http://www.gnu.org/software/g-golf/news.html][here]]. +** For older News, see [[http://www.gnu.org/software/g-golf/news.html][here]]. @@ -81,9 +81,9 @@ points to its source code, in the G-Golf sources [[http://git.savannah.gnu.org/c ** Latest News -January 2023 +February 2023 -GNU G-Golf version 0.8.0-a.2 is released. +GNU G-Golf version 0.8.0-a.3 is released. Visit the NEWS file or see the [[http://git.savannah.gnu.org/cgit/g-golf.git/tree/NEWS][News]] page for the list of visible changes since the last release, as well as older news. diff --git a/configure.ac b/configure.ac index 6887c75..65a049a 100644 --- a/configure.ac +++ b/configure.ac @@ -31,7 +31,7 @@ AC_PREREQ(2.69) AC_INIT( [g-golf], - [0.8.0-a.2], + [0.8.0-a.3], [bug-g-golf@gnu.org]) AC_CONFIG_AUX_DIR([build-aux]) diff --git a/examples/gtk-4/clipboard.scm b/examples/gtk-4/clipboard.scm index 9318cc8..614fd15 100755 --- a/examples/gtk-4/clipboard.scm +++ b/examples/gtk-4/clipboard.scm @@ -5,7 +5,7 @@ exec guile -e main -s "$0" "$@" ;;;; -;;;; Copyright (C) 2022 +;;;; Copyright (C) 2022 - 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -161,5 +161,5 @@ exec guile -e main -s "$0" "$@" (let ((app (make <gtk-application> #:application-id "org.gtk.example"))) (connect app 'activate activate) - (let ((status (g-application-run app (length args) args))) + (let ((status (g-application-run app args))) (exit status)))) diff --git a/examples/gtk-4/css-basics.scm b/examples/gtk-4/css-basics.scm index d20acfc..a53d976 100755 --- a/examples/gtk-4/css-basics.scm +++ b/examples/gtk-4/css-basics.scm @@ -5,7 +5,7 @@ exec guile -e main -s "$0" "$@" ;;;; -;;;; Copyright (C) 2022 +;;;; Copyright (C) 2022 - 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -96,5 +96,5 @@ exec guile -e main -s "$0" "$@" (let ((app (make <gtk-application> #:application-id "org.gtk.example"))) (connect app 'activate activate) - (let ((status (g-application-run app (length args) args))) + (let ((status (g-application-run app args))) (exit status)))) diff --git a/examples/gtk-4/drawing-widget.scm b/examples/gtk-4/drawing-widget.scm index e9610fd..015c727 100755 --- a/examples/gtk-4/drawing-widget.scm +++ b/examples/gtk-4/drawing-widget.scm @@ -87,5 +87,5 @@ exec guile -e main -s "$0" "$@" (let ((app (make <gtk-application> #:application-id "org.gtk.example"))) (connect app 'activate activate) - (let ((status (g-application-run app (length args) args))) + (let ((status (g-application-run app args))) (exit status)))) diff --git a/examples/gtk-4/hello-world.scm b/examples/gtk-4/hello-world.scm index 7b5735c..70b5c55 100755 --- a/examples/gtk-4/hello-world.scm +++ b/examples/gtk-4/hello-world.scm @@ -5,7 +5,7 @@ exec guile -e main -s "$0" "$@" ;;;; -;;;; Copyright (C) 2022 +;;;; Copyright (C) 2022 - 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -82,5 +82,5 @@ exec guile -e main -s "$0" "$@" (let ((app (make <gtk-application> #:application-id "org.gtk.example"))) (connect app 'activate activate) - (let ((status (g-application-run app (length args) args))) + (let ((status (g-application-run app args))) (exit status)))) diff --git a/examples/gtk-4/peg-solitaire.scm b/examples/gtk-4/peg-solitaire.scm index 6c4c30e..c5943c2 100755 --- a/examples/gtk-4/peg-solitaire.scm +++ b/examples/gtk-4/peg-solitaire.scm @@ -5,7 +5,7 @@ exec guile -e main -s "$0" "$@" ;;;; -;;;; Copyright (C) 2022 +;;;; Copyright (C) 2022 - 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -73,22 +73,13 @@ exec guile -e main -s "$0" "$@" (define-vfunc (get-intrinsic-height-vfunc (self <solitaire-peg>)) 32) -;; For some unknown reason(s) still, the snapshot vfunc is not called with the -;; the intrinsic width and height values. However both the get-intrinsic-width -;; and get-intrinsic-height methods work fine, they call their corresponding -;; vfunc, that we override here above. Till I find out why, let's call those -;; method explicitly and temporarily comment the width height args. - (define-vfunc (snapshot-vfunc (self <solitaire-peg>) snapshot width height) (receive (outline outline:bounds) (allocate-c-struct gsk-rounded-rect bounds) (gsk-rounded-rect-init-from-rect outline (graphene-rect-init (graphene-rect-alloc) - 0 0 - ;; width height - (get-intrinsic-width self) - (get-intrinsic-height self)) - 3.5) ;; px - approx. 0.3em [default fontsize] + 0 0 width height) + 3.5) ;; px - approx. 0.3em [default fontsize] (push-rounded-clip snapshot outline) (append-color snapshot '(0.61 0.1 0.47 1.0) ;; vocaloid @@ -270,7 +261,7 @@ exec guile -e main -s "$0" "$@" #:row-spacing 6 #:row-homogeneous #t)) (css-provider (let ((provider (make <gtk-css-provider>))) - (gtk-css-provider-load-from-data provider %css-data -1) + (gtk-css-provider-load-from-data provider %css-data) provider))) (set-child window grid) (do ((i 0 @@ -331,5 +322,5 @@ exec guile -e main -s "$0" "$@" (let ((app (make <gtk-application> #:application-id "org.gtk.example"))) (connect app 'activate activate) - (let ((status (g-application-run app (length args) args))) + (let ((status (g-application-run app args))) (exit status)))) diff --git a/examples/gtk-4/revealer.scm b/examples/gtk-4/revealer.scm index 84c0928..7a12ed8 100755 --- a/examples/gtk-4/revealer.scm +++ b/examples/gtk-4/revealer.scm @@ -5,7 +5,7 @@ exec guile -e main -s "$0" "$@" ;;;; -;;;; Copyright (C) 2022 +;;;; Copyright (C) 2022 - 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -99,5 +99,5 @@ exec guile -e main -s "$0" "$@" (let ((app (make <gtk-application> #:application-id "org.gtk.example"))) (connect app 'activate activate) - (let ((status (g-application-run app (length args) args))) + (let ((status (g-application-run app args))) (exit status)))) diff --git a/examples/gtk-4/search-bar.scm b/examples/gtk-4/search-bar.scm index b758feb..1d746c0 100755 --- a/examples/gtk-4/search-bar.scm +++ b/examples/gtk-4/search-bar.scm @@ -5,7 +5,7 @@ exec guile -e main -s "$0" "$@" ;;;; -;;;; Copyright (C) 2022 +;;;; Copyright (C) 2022 - 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -108,5 +108,5 @@ exec guile -e main -s "$0" "$@" (let ((app (make <gtk-application> #:application-id "org.gtk.example"))) (connect app 'activate activate) - (let ((status (g-application-run app (length args) args))) + (let ((status (g-application-run app args))) (exit status)))) diff --git a/g-golf/hl-api/argument.scm b/g-golf/hl-api/argument.scm index 84c7b2c..8faeb6a 100644 --- a/g-golf/hl-api/argument.scm +++ b/g-golf/hl-api/argument.scm @@ -1,7 +1,7 @@ ;; -*- mode: scheme; coding: utf-8 -*- ;;;; -;;;; Copyright (C) 2022 +;;;; Copyright (C) 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -67,6 +67,8 @@ !scope !type-tag !type-desc + !is-enum? + !al-arg? !array-type-desc !forced-type !string-pointer @@ -101,6 +103,8 @@ (scope #:accessor !scope) (type-tag #:accessor !type-tag #:init-keyword #:type-tag) (type-desc #:accessor !type-desc #:init-keyword #:type-desc) + (is-enum? #:accessor !is-enum? #:init-keyword #:is-enum?) + (al-arg? #:accessor !al-arg? #:init-value #f) (array-type-desc #:accessor !array-type-desc) (forced-type #:accessor !forced-type #:init-keyword #:forced-type) (string-pointer #:accessor !string-pointer) @@ -160,6 +164,11 @@ 'scope scope 'type-tag type-tag 'type-desc type-desc + 'is-enum? (and (eq? type-tag 'interface) + (match type-desc + ((type name gi-type g-type confirmed?) + (or (eq? type 'enum) + (eq? type 'flags))))) 'array-type-desc array-type-desc 'forced-type forced-type 'is-pointer? is-pointer? diff --git a/g-golf/hl-api/callable.scm b/g-golf/hl-api/callable.scm index 8d84a6f..d004877 100644 --- a/g-golf/hl-api/callable.scm +++ b/g-golf/hl-api/callable.scm @@ -1,7 +1,7 @@ ;; -*- mode: scheme; coding: utf-8 -*- ;;;; -;;;; Copyright (C) 2022 +;;;; Copyright (C) 2022 - 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -81,6 +81,11 @@ 'caller-owns (g-callable-info-get-caller-owns info) 'return-type return-type 'type-desc type-desc + 'is-enum? (and (eq? return-type 'interface) + (match type-desc + ((type name gi-type g-type confirmed?) + (or (eq? type 'enum) + (eq? type 'flags))))) 'array-type-desc array-type-desc 'may-return-null? (g-callable-info-may-return-null info)) (initialize-callable-arguments self)))) @@ -107,7 +112,7 @@ (define (initialize-callable-arguments callable) (let* ((info (!info callable)) - (override? (!override? callable)) + (override? (!override? callable)) (is-method? (!is-method? callable)) (n-arg (g-callable-info-get-n-args info)) (args (if is-method? @@ -115,6 +120,7 @@ '()))) (let loop ((i 0) (arg-pos (length args)) + (al-pos '()) (arguments args) (n-gi-arg-in (length args)) (args-in args) @@ -122,41 +128,15 @@ (n-gi-arg-out 0) (args-out '())) (if (= i n-arg) - (let* ((arguments (reverse arguments)) - (args-in (reverse args-in)) - (args-out (reverse args-out)) - (gi-args-in-bv (if (> n-gi-arg-in 0) - (make-bytevector (* %gi-argument-size - n-gi-arg-in) - 0) - #f)) - (gi-args-in (if gi-args-in-bv - (bytevector->pointer gi-args-in-bv) - %null-pointer)) - (gi-args-out-bv (if (> n-gi-arg-out 0) - (make-bytevector (* %gi-argument-size - n-gi-arg-out) - 0) - #f)) - (gi-args-out (if gi-args-out-bv - (bytevector->pointer gi-args-out-bv) - %null-pointer))) - (when gi-args-in-bv - (finalize-callable-arguments args-in gi-args-in-bv !gi-argument-in)) - (when gi-args-out-bv - (finalize-callable-arguments args-out gi-args-out-bv !gi-argument-out)) - (mslot-set! callable - 'n-arg (if is-method? (+ n-arg 1) n-arg) - 'arguments arguments - 'n-gi-arg-in n-gi-arg-in - 'args-in args-in - 'gi-args-in gi-args-in - 'gi-args-in-bv gi-args-in-bv - 'n-gi-arg-out n-gi-arg-out - 'args-out args-out - 'gi-args-out gi-args-out - 'gi-args-out-bv gi-args-out-bv - 'gi-arg-result (make-gi-argument))) + (initialize-callable-arguments-final-steps callable + is-method? + n-arg + (reverse al-pos) + (reverse arguments) + (reverse args-in) + (reverse args-out) + n-gi-arg-in + n-gi-arg-out) (let* ((arg-info (g-callable-info-get-arg info i)) (argument (make <argument> #:info arg-info))) (case (!direction argument) @@ -168,6 +148,7 @@ 'gi-argument-in-bv-pos n-gi-arg-in) (loop (+ i 1) (+ arg-pos 1) + (al-pos-check argument al-pos is-method?) (cons argument arguments) (+ n-gi-arg-in 1) (cons argument args-in) @@ -183,6 +164,7 @@ 'gi-argument-out-bv-pos n-gi-arg-out) (loop (+ i 1) (+ arg-pos 1) + al-pos (cons argument arguments) (+ n-gi-arg-in 1) (cons argument args-in) @@ -195,6 +177,7 @@ 'gi-argument-out-bv-pos n-gi-arg-out) (loop (+ i 1) (+ arg-pos 1) + al-pos (cons argument arguments) n-gi-arg-in args-in @@ -202,6 +185,86 @@ (+ n-gi-arg-out 1) (cons argument args-out))))))))) +(define (al-pos-check argument al-pos is-method?) + (case (!type-tag argument) + ((array) + (match (!type-desc argument) + ((array fixed-size is-zero-terminated param-n param-tag) + (if (= param-n -1) + al-pos + (let* ((arg-pos (!arg-pos argument)) + (param-n (if is-method? (+ param-n 1) param-n)) + (u-args-ar-pos (if (< param-n arg-pos) ;; [1] + (- arg-pos + (+ (length al-pos) 1)) + (- arg-pos (length al-pos))))) + (cons (list u-args-ar-pos + arg-pos ;; 'real' array pos [2] + param-n) + al-pos)))))) + (else + al-pos))) + +;; [1] + +;; u-arg-ar-pos are 'shifted' to the left - compared to their 'real' +;; cble-args-ar-pos - by an amount that depens on both previous al args, +;; and whether the one being processed has its al-pos, param-n, +;; preceeding or following the array pos itself. + +;; [2] + +;; the 'real' array pos is the offset of the array arg in the (complete) +;; cble-args list - we need it to construct the cble-args list + +(define (initialize-callable-arguments-final-steps callable + is-method? + n-arg ;; callable-info-n-args + al-pos + arguments + args-in + args-out + n-gi-arg-in + n-gi-arg-out) + (let* ((gi-args-in-bv (if (> n-gi-arg-in 0) + (make-bytevector (* %gi-argument-size + n-gi-arg-in) + 0) + #f)) + (gi-args-in (if gi-args-in-bv + (bytevector->pointer gi-args-in-bv) + %null-pointer)) + (gi-args-out-bv (if (> n-gi-arg-out 0) + (make-bytevector (* %gi-argument-size + n-gi-arg-out) + 0) + #f)) + (gi-args-out (if gi-args-out-bv + (bytevector->pointer gi-args-out-bv) + %null-pointer))) + (when gi-args-in-bv + (finalize-callable-arguments args-in gi-args-in-bv !gi-argument-in)) + (when gi-args-out-bv + (finalize-callable-arguments args-out gi-args-out-bv !gi-argument-out)) + (for-each (lambda (item) + (match item + ((u-pos c-pos l-pos) + (set! (!al-arg? (list-ref arguments l-pos)) #t)))) + al-pos) + (mslot-set! callable + 'n-arg (if is-method? (+ n-arg 1) n-arg) + 'al-pos al-pos + 'arguments arguments + 'n-gi-arg-in n-gi-arg-in + 'args-in args-in + 'gi-args-in gi-args-in + 'gi-args-in-bv gi-args-in-bv + 'n-gi-arg-out n-gi-arg-out + 'args-out args-out + 'gi-args-out gi-args-out + 'gi-args-out-bv gi-args-out-bv + 'gi-arg-result (make-gi-argument)))) + (define (finalize-callable-arguments args gi-args-bv gi-argument-acc) (let loop ((args args) (i 0)) @@ -215,17 +278,74 @@ (+ i 1)))))) (define (callable-prepare-gi-arguments callable args) - (let ((args-length (length args)) - (n-arg (!n-arg callable)) - (n-arg-in (!n-gi-arg-in callable)) - (override? (!override? callable))) + (let* ((args-length (length args)) + (n-arg (!n-arg callable)) + (n-arg-in (!n-gi-arg-in callable)) + (al-pos (!al-pos callable)) + (effective-n-arg-in (- n-arg-in (length al-pos))) + (override? (!override? callable))) (if (or (and override? (= args-length n-arg)) - (= args-length n-arg-in)) - (begin + (= args-length effective-n-arg-in)) + (let ((args (if (null? al-pos) + args + (u-args->cble-args n-arg-in args al-pos)))) (callable-prepare-gi-args-in callable args) (callable-prepare-gi-args-out callable args args-length n-arg)) - (error "Wrong number of arguments: " args)))) + (scm-error 'wrong-arg-nb #f "Wrong number of arguments: ~A ~S" + (list (!name callable) args) #f)))) + +#! + +;; example - to play with + +(define cble-args + '(e0 3 (ar1-0 ar1-1 ar1-2) e3 (ar2-0) 1 e6 2 (ar3-0 ar3-1))) + +(define u-args + '(e0 (ar1-0 ar1-1 ar1-2) e3 (ar2-0) e6 (ar3-0 ar3-1))) + +(define al-pos + '((1 2 1) ;; [1] + (3 4 5) + (5 8 7))) + +;; [1] + +;; 0. u-args ar-pos +;; 1. cble-arg ar-pos +;; 2. cble-arg al-pos + +!# + +(define (u-args->cble-args n-arg-in u-args al-pos) + (let loop ((i 0) + (args u-args) + (al-pos al-pos) + (cble-args '())) + (if (= i n-arg-in) + (reverse! cble-args) + (if (null? al-pos) + (loop (+ i 1) + (cdr args) + '() + (cons (car args) cble-args)) + (match (car al-pos) + ((u-pos c-pos l-pos) + (if (= i l-pos) + (let ((ar (list-ref u-args u-pos))) + (loop (+ i 1) + args + (cdr al-pos) + (cons (cond ((list? ar) (length ar)) + ((string? ar) -1) + (else + (error "What array is this " ar))) + cble-args))) + (loop (+ i 1) + (cdr args) + al-pos + (cons (car args) cble-args))))))))) (define %allow-none-exceptions '(child-setup-data-destroy)) @@ -332,11 +452,12 @@ (error "Invalid array argument: " value)) (match type-desc ((array fixed-size is-zero-terminated param-n param-tag) - (let* ((param-n (case param-n - ((-1) param-n) - (else - (if is-method? (+ param-n 1) param-n)))) - (arg-n (list-ref args param-n))) + (let* ((param-n (if (= param-n -1) + -1 + (if is-method? (+ param-n 1) param-n))) + (arg-n (if (= param-n -1) + -1 + (list-ref args param-n)))) (case param-tag ((utf8 filename) @@ -368,6 +489,20 @@ (gi-argument-set! gi-argument 'v-pointer value)) (else (error "Invalid (uint8 array) argument: " value)))) + ((interface) + (match (!array-type-desc clb/arg) + ((type name gi-type g-type confirmed?) + (case type + ((object) + (let ((ptrs (map !g-inst value))) + (gi-argument-set! gi-argument 'v-pointer + (if (or is-zero-terminated + (= arg-n -1)) + (scm->gi-pointers ptrs) + (scm->gi-n-pointer ptrs arg-n))))) + (else + (warning "Unimplemented (prepare args-in) type - array;" + (format #f "~S" type-desc))))))) (else (warning "Unimplemented (prepare args-in) type - array;" (format #f "~S" type-desc))))))))) @@ -792,6 +927,7 @@ #:direction 'in #:type-tag 'interface #:type-desc (list type r-name gi-type id confirmed?) + #:is-enum? #f #:forced-type 'pointer #:is-pointer? #t #:may-be-null? #f diff --git a/g-golf/hl-api/callback.scm b/g-golf/hl-api/callback.scm index 5ecc1d6..214017a 100644 --- a/g-golf/hl-api/callback.scm +++ b/g-golf/hl-api/callback.scm @@ -1,7 +1,7 @@ ;; -*- mode: scheme; coding: utf-8 -*- ;;;; -;;;; Copyright (C) 2019 - 2022 +;;;; Copyright (C) 2019 - 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -27,6 +27,7 @@ (define-module (g-golf hl-api callback) + #:use-module (system foreign) #:use-module (ice-9 threads) #:use-module (ice-9 match) #:use-module (ice-9 receive) @@ -109,24 +110,35 @@ (mslot-set! self 'ffi-cif (callback-ffi-cif self)))) +(define (ffi-prep-cif-elements callback) + (let* ((ffi-cif-bv (make-bytevector (ffi-cif-size) 0)) + (r-type-info (g-callable-info-get-return-type (!info callback))) + (r-type (g-type-info-get-ffi-type r-type-info)) + (n-arg (!n-arg callback)) + (a-types-bv (make-bytevector (* n-arg (ffi-type-size)) 0))) + (g-base-info-unref r-type-info) + (values (bytevector->pointer ffi-cif-bv) + n-arg + r-type + (bytevector->pointer a-types-bv)))) + (define (callback-ffi-cif callback) - (let ((n-arg (!n-arg callback))) - (case n-arg - ((0) %null-pointer) - (else - (let ((ffi-cif - (bytevector->pointer - (make-bytevector (* n-arg (ffi-type-size)) 0)))) - (let loop ((arguments (!arguments callback)) - (w-ptr ffi-cif)) - (match arguments - (() ffi-cif) - ((argument . rest) - (bv-ptr-set! w-ptr - (gi-type-tag-get-ffi-type (!type-tag argument) - (!is-pointer? argument))) - (loop rest - (gi-pointer-inc w-ptr)))))))))) + (receive (ffi-cif n-arg r-type a-types) + (ffi-prep-cif-elements callback) + (if (= n-arg 0) + %null-pointer + (let loop ((arguments (!arguments callback)) + (w-ptr a-types)) + (match arguments + (() + (ffi-prep-cif ffi-cif n-arg r-type a-types) + ffi-cif) + ((argument . rest) + (bv-ptr-set! w-ptr + (gi-type-tag-get-ffi-type (!type-tag argument) + (!is-pointer? argument))) + (loop rest + (gi-pointer-inc w-ptr)))))))) (define (g-callable-info-make-closure info ffi-cif @@ -181,23 +193,60 @@ #:is-method? (!is-method? callback) #:forced-type return-type)))))) ((argument . rests) - (let ((type-info (!type-info argument))) - (if type-info - (gi-type-info-extract-ffi-return-value type-info ffi-arg gi-argument) - ;; a 'manually built' instance argument, the first argument of - ;; a method. - (gi-type-tag-extract-ffi-return-value 'interface - 'object - ffi-arg - gi-argument)) + (let* ((type-tag (!type-tag argument)) + (type-desc (!type-desc argument)) + (is-pointer? (!is-pointer? argument)) + (is-enum? (!is-enum? argument)) + (gi-argument (or (!gi-argument-in argument) + (!gi-argument-out argument))) + (forced-type (!forced-type argument)) + (ffi-value (ffi-arg->scm ffi-arg type-tag is-pointer? is-enum?))) (loop rests (gi-pointer-inc ffi-arg) - (cons (%gi-argument->scm (!type-tag argument) - (!type-desc argument) - gi-argument - argument - #:forced-type (!forced-type argument) - #:is-pointer? (!is-pointer? argument)) + (cons (case type-tag + ((boolean + int8 + uint8 + int16 + uint16 + int32 + uint3 + unichar + int64 + uint64 + float + double + gtype + utf + filename) + ffi-value) + ((array + glist + gslist + ghash + error) + (begin + (gi-argument-set! gi-argument 'v-pointer ffi-value) + (%gi-argument->scm type-tag + type-desc + gi-argument + argument + #:forced-type forced-type + #:is-pointer? is-pointer?))) + ((interface) + (if is-enum? + (gi-argument-set! gi-argument 'v-int32 ffi-value) + (gi-argument-set! gi-argument 'v-pointer ffi-value)) + (%gi-argument->scm type-tag + type-desc + gi-argument + argument + #:forced-type forced-type + #:is-pointer? is-pointer?)) + ((void) + (if is-pointer? + ffi-value + (error "unlikely possible")))) args)))))))) (define %g-golf-callback-closure-marshal diff --git a/g-golf/hl-api/ccc.scm b/g-golf/hl-api/ccc.scm index 572545a..18b1e62 100644 --- a/g-golf/hl-api/ccc.scm +++ b/g-golf/hl-api/ccc.scm @@ -1,7 +1,7 @@ ;; -*- mode: scheme; coding: utf-8 -*- ;;;; -;;;; Copyright (C) 2022 +;;;; Copyright (C) 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -57,9 +57,11 @@ !override? !is-method? !n-arg + !al-pos !caller-owns !return-type !type-desc + !is-enum? !array-type-desc !string-pointer !bv-cache @@ -94,9 +96,11 @@ (override? #:accessor !override? #:init-keyword #:override? #:init-value #f) (is-method? #:accessor !is-method?) (n-arg #:accessor !n-arg) + (al-pos #:accessor !al-pos) (caller-owns #:accessor !caller-owns) (return-type #:accessor !return-type) (type-desc #:accessor !type-desc) + (is-enum? #:accessor !is-enum?) (array-type-desc #:accessor !array-type-desc) (string-pointer #:accessor !string-pointer) (bv-cache #:accessor !bv-cache #:init-value #f) diff --git a/g-golf/hl-api/function.scm b/g-golf/hl-api/function.scm index cb721a4..cda2f27 100644 --- a/g-golf/hl-api/function.scm +++ b/g-golf/hl-api/function.scm @@ -1,7 +1,7 @@ ;; -*- mode: scheme; coding: utf-8 -*- ;;;; -;;;; Copyright (C) 2019 - 2022 +;;;; Copyright (C) 2019 - 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -218,7 +218,9 @@ (case (!direction argument) ((in inout) - argument) + (if (!al-arg? argument) + #f + argument)) (else #f))) arguments))))) diff --git a/g-golf/override/gtk.scm b/g-golf/override/gtk.scm index 37cb905..46437da 100644 --- a/g-golf/override/gtk.scm +++ b/g-golf/override/gtk.scm @@ -1,7 +1,7 @@ ;; -*- mode: scheme; coding: utf-8 -*- ;;;; -;;;; Copyright (C) 2020 - 2022 +;;;; Copyright (C) 2020 - 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -29,7 +29,7 @@ (define-module (g-golf override gtk) #:export (gtk-container-child-get-property-ov gtk-container-child-set-property-ov - gtk-list-store-new-ov + #;gtk-list-store-new-ov gtk-list-store-set-value-ov gtk-tree-store-set-value-ov gtk-tree-model-get-value-ov @@ -83,7 +83,7 @@ (error "No child property" container name)))) '(0 1 2 3))) -(define (gtk-list-store-new-ov proc) +#;(define (gtk-list-store-new-ov proc) (values #f `(lambda (g-types) diff --git a/g-golf/override/override.scm b/g-golf/override/override.scm index 73ee71b..9862280 100644 --- a/g-golf/override/override.scm +++ b/g-golf/override/override.scm @@ -1,7 +1,7 @@ ;; -*- mode: scheme; coding: utf-8 -*- ;;;; -;;;; Copyright (C) 2020 - 2022 +;;;; Copyright (C) 2020 - 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -39,7 +39,7 @@ "gtk_container_child_get_property" "gtk_container_child_set_property" - "gtk_list_store_newv" + #;"gtk_list_store_newv" "gtk_list_store_set_value" "gtk_tree_store_set_value" "gtk_tree_model_get_value" diff --git a/g-golf/support/ffi.scm b/g-golf/support/ffi.scm index 63ca479..b51abdf 100644 --- a/g-golf/support/ffi.scm +++ b/g-golf/support/ffi.scm @@ -1,7 +1,7 @@ ;; -*- mode: scheme; coding: utf-8 -*- ;;;; -;;;; Copyright (C) 2022 +;;;; Copyright (C) 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -27,13 +27,213 @@ (define-module (g-golf support ffi) + #:use-module (ice-9 match) + #:use-module (system foreign) + #:use-module (srfi srfi-4) #:use-module (g-golf support libg-golf) + #:use-module (g-golf gi utils) + #:use-module (g-golf support utils) - #:export (ffi-type-size)) + #:export (ffi-args->scm + ffi-arg->scm + ffi-arg-boolean->scm + ffi-arg-int8->scm + ffi-arg-uint8->scm + ffi-arg-int16->scm + ffi-arg-uint16->scm + ffi-arg-int16->scm + ffi-arg-uint16->scm + ffi-arg-int32->scm + ffi-arg-uint32->scm + ffi-arg-int64->scm + ffi-arg-uint64->scm + ffi-arg-float->scm + ffi-arg-double->scm + ffi-arg-gtype->scm + ffi-arg-string->scm + ffi-arg-pointer->scm + + ffi-cif-size + ffi-type-size + ffi-prep-cif + #;ffi-pack-double)) + + +(define (ffi-args->scm ffi-args type-descs) + (let loop ((ffi-arg ffi-args) + (descs type-descs) + (results '())) + (match descs + (() + (reverse! results)) + ((desc . rest) + (loop (gi-pointer-inc ffi-arg) + rest + (cons (match desc + ((type-tag is-póinter? is-enum?) + (ffi-arg->scm ffi-arg type-tag is-póinter? is-enum?))) + results)))))) + +(define (ffi-arg->scm ffi-arg type-tag is-pointer? is-enum?) + (case type-tag + ((boolean) + (ffi-arg-boolean->scm ffi-arg)) + ((int8) + (ffi-arg-int8->scm ffi-arg)) + ((uint8) + (ffi-arg-uint8->scm ffi-arg)) + ((int16) + (ffi-arg-int16->scm ffi-arg)) + ((uint16) + (ffi-arg-uint16->scm ffi-arg)) + ((int32) + (ffi-arg-int32->scm ffi-arg)) + ((uint32 + unichar) + (ffi-arg-uint32->scm ffi-arg)) + ((int64) + (ffi-arg-int64->scm ffi-arg)) + ((uint64) + (ffi-arg-uint64->scm ffi-arg)) + ((float) + (ffi-arg-float->scm ffi-arg)) + ((double) + (ffi-arg-double->scm ffi-arg)) + ((gtype) + (ffi-arg-gtype->scm ffi-arg)) + ((utf8 + filename) + (ffi-arg-string->scm ffi-arg)) + ((array + glist + gslist + ghash + error) + (ffi-arg-pointer->scm ffi-arg)) + ((interface) + ;; Needs to handle enums specially: + ;; https://bugzilla.gnome.org/show_bug.cgi?id=665150 + (if is-enum? + (ffi-arg-int32->scm ffi-arg) + (ffi-arg-pointer->scm ffi-arg))) + ((void) + (if is-pointer? + (ffi-arg-pointer->scm ffi-arg) + 'void)) + (else + (scm-error 'failed #f + "Unimplemented ffi-arg->scm type-tag: ~A" + (list type-tag) #f)))) + +(define (ffi-arg-boolean->scm ffi-arg) + (let* ((size (sizeof unsigned-int)) + (bv-ptr (dereference-pointer ffi-arg)) + (bv (pointer->bytevector bv-ptr size))) + (gi->scm (case size + ((4) + (u32vector-ref bv 0)) + ((8) + (u64vector-ref bv 0)) + (else + (error "what machine is this?"))) + 'boolean))) + +(define (ffi-arg-int8->scm ffi-arg) + (let* ((bv-ptr (dereference-pointer ffi-arg)) + (bv (pointer->bytevector bv-ptr (sizeof int8)))) + (s8vector-ref bv 0))) + +(define (ffi-arg-uint8->scm ffi-arg) + (let* ((bv-ptr (dereference-pointer ffi-arg)) + (bv (pointer->bytevector bv-ptr (sizeof uint8)))) + (u8vector-ref bv 0))) + +(define (ffi-arg-int16->scm ffi-arg) + (let* ((bv-ptr (dereference-pointer ffi-arg)) + (bv (pointer->bytevector bv-ptr (sizeof int16)))) + (s16vector-ref bv 0))) + +(define (ffi-arg-uint16->scm ffi-arg) + (let* ((bv-ptr (dereference-pointer ffi-arg)) + (bv (pointer->bytevector bv-ptr (sizeof uint16)))) + (u16vector-ref bv 0))) + +(define (ffi-arg-int32->scm ffi-arg) + (let* ((bv-ptr (dereference-pointer ffi-arg)) + (bv (pointer->bytevector bv-ptr (sizeof int32)))) + (s32vector-ref bv 0))) + +(define (ffi-arg-uint32->scm ffi-arg) + (let* ((bv-ptr (dereference-pointer ffi-arg)) + (bv (pointer->bytevector bv-ptr (sizeof uint32)))) + (u32vector-ref bv 0))) + +(define (ffi-arg-int64->scm ffi-arg) + (let* ((bv-ptr (dereference-pointer ffi-arg)) + (bv (pointer->bytevector bv-ptr (sizeof int64)))) + (s64vector-ref bv 0))) + +(define (ffi-arg-uint64->scm ffi-arg) + (let* ((bv-ptr (dereference-pointer ffi-arg)) + (bv (pointer->bytevector bv-ptr (sizeof uint64)))) + (u64vector-ref bv 0))) + +(define (ffi-arg-float->scm ffi-arg) + (let* ((size (sizeof float)) + (bv-ptr (dereference-pointer ffi-arg)) + (bv (pointer->bytevector bv-ptr size))) + (case size + ((4) + (f32vector-ref bv 0)) + ((8) + (f64vector-ref bv 0)) + (else + (error "what machine is this?"))))) + +(define (ffi-arg-double->scm ffi-arg) + (let* ((size (sizeof double)) + (bv-ptr (dereference-pointer ffi-arg)) + (bv (pointer->bytevector bv-ptr size))) + (case size + ((4) + (f32vector-ref bv 0)) + ((8) + (f64vector-ref bv 0)) + (else + (error "what machine is this?"))))) + +(define (ffi-arg-gtype->scm ffi-arg) + (let* ((size (sizeof size_t)) + (bv-ptr (dereference-pointer ffi-arg)) + (bv (pointer->bytevector bv-ptr size))) + (case size + ((4) + (u32vector-ref bv 0)) + ((8) + (u64vector-ref bv 0)) + (else + (error "what machine is this?"))))) + +(define (ffi-arg-string->scm ffi-arg) + (gi->scm (dereference-pointer ffi-arg) 'string)) + +(define (ffi-arg-pointer->scm ffi-arg) + (gi->scm (dereference-pointer ffi-arg) 'pointer)) ;;; ;;; From libg-golf ;;; -(define ffi-type-size ffi_type_size) +(define ffi-cif-size gg_ffi_cif_size) + +(define ffi-type-size gg_ffi_type_size) + +(define (ffi-prep-cif cif n-args r-type a-types) + (let ((ffi-status (gg_ffi_prep_cif cif n-args r-type a-types))) + (unless (= ffi-status 0) + (scm-error 'failed #f "ffi_prep_cif failed: ~A" + (list ffi-status) #f)))) + +#;(define (ffi-pack-double ffi-arg) + (gg_ffi_pack_double ffi-arg)) diff --git a/g-golf/support/libg-golf.scm b/g-golf/support/libg-golf.scm index 539d252..0e395bb 100644 --- a/g-golf/support/libg-golf.scm +++ b/g-golf/support/libg-golf.scm @@ -1,7 +1,7 @@ ;; -*- mode: scheme; coding: utf-8 -*- ;;;; -;;;; Copyright (C) 2016 - 2022 +;;;; Copyright (C) 2016 - 2023 ;;;; Free Software Foundation, Inc. ;;;; This file is part of GNU G-Golf @@ -31,7 +31,10 @@ #:use-module (g-golf init) #:export (;; FFI - ffi_type_size + gg_ffi_cif_size + gg_ffi_type_size + gg_ffi_prep_cif + gg_ffi_pack_double ;; Misc. pointer_address_size @@ -67,12 +70,33 @@ ;;; FFI ;;; -(define ffi_type_size +(define gg_ffi_cif_size (pointer->procedure size_t - (dynamic-func "ffi_type_size" + (dynamic-func "gg_ffi_cif_size" %libg-golf) (list))) +(define gg_ffi_type_size + (pointer->procedure size_t + (dynamic-func "gg_ffi_type_size" + %libg-golf) + (list))) + +(define gg_ffi_prep_cif + (pointer->procedure int + (dynamic-func "gg_ffi_prep_cif" + %libg-golf) + (list '* ;; *cif + unsigned-int ;; n-args + '* ;; *return-type + '*))) ;; **arg-types + +(define gg_ffi_pack_double + (pointer->procedure double + (dynamic-func "gg_ffi_pack_double" + %libg-golf) + (list '*))) ;; *ffi-arg + ;;; ;;; Misc. diff --git a/libg-golf/gg-ffi.c b/libg-golf/gg-ffi.c index 148b7bd..15666df 100644 --- a/libg-golf/gg-ffi.c +++ b/libg-golf/gg-ffi.c @@ -31,6 +31,7 @@ #include <math.h> #include <ffi.h> +#include <ffitarget.h> /* @@ -39,9 +40,47 @@ */ size_t -ffi_type_size () +gg_ffi_cif_size () +{ + size_t n = sizeof(ffi_cif); + + return n; +} + +size_t +gg_ffi_type_size () { size_t n = sizeof(ffi_type *); return n; } + +int +gg_ffi_prep_cif (ffi_cif *cif, \ + unsigned n_args, \ + ffi_type *r_type, \ + ffi_type **a_types) +{ + int ffi_status; + + /* printf("return type: %d\n", r_type->type); + * for (unsigned i = 0; i < n_args; i++) { + * printf (" arg %d type: %d\n", i, a_types[i]->type); + * } + */ + + ffi_status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, n_args, r_type, a_types); + + return ffi_status; +} + +double +gg_ffi_pack_double (void **arg) +{ + double dble; + + dble = *(double *) (*arg); + /* printf (" ffi_arg dble: %f\n", dble); */ + + return dble; +} diff --git a/libg-golf/gg-ffi.h b/libg-golf/gg-ffi.h index bba8d13..2865456 100644 --- a/libg-golf/gg-ffi.h +++ b/libg-golf/gg-ffi.h @@ -1,7 +1,7 @@ /* -*- mode: C; coding: utf-8 -*- #### -#### Copyright (C) 2022 +#### Copyright (C) 2023 #### Free Software Foundation, Inc. #### This file is part of GNU G-Golf. @@ -39,4 +39,16 @@ */ size_t -ffi_type_size (); +gg_ffi_cif_size (); + +size_t +gg_ffi_type_size (); + +int +gg_ffi_prep_cif (ffi_cif *cif, \ + uint n_args, \ + ffi_type *r_type, \ + ffi_type **a_types); + +double +gg_ffi_pack_double (void **arg); |