@@ -67,7 +67,7 @@ abstract class GObject
6767 * Don't call this yourself, users should stick to (for example)
6868 * Image::newFromFile().
6969 *
70- * @param FFI\ CData $pointer The underlying pointer that this
70+ * @param CData $pointer The underlying pointer that this
7171 * object should wrap.
7272 *
7373 * @internal
@@ -99,47 +99,121 @@ public function unref(): void
9999
100100 public function signalConnect (string $ name , Closure $ callback ): void
101101 {
102- static $ marshalers = null ;
103-
104- if ($ marshalers === null ) {
105- $ imageProgressCb = static function (CData $ vi , CData $ progress , CData $ handle ) {
106- FFI ::gobject ()->g_object_ref ($ vi );
107- $ image = new Image ($ vi );
108- $ progress = \FFI ::cast (FFI ::ctypes ('VipsProgress ' ), $ progress );
109- $ handle ($ image , $ progress );
102+ $ imageProgressCb = static function (
103+ CData $ gClosure ,
104+ ?CData $ returnValue ,
105+ int $ numberOfParams ,
106+ CData $ params ,
107+ CData $ hint ,
108+ ?CData $ data
109+ ) use ($ callback ) {
110+ assert ($ numberOfParams === 3 );
111+ /**
112+ * Marshal-Signature: void(VipsImage*, void*, void*)
113+ */
114+ $ vi = \FFI ::cast (FFI ::ctypes ('GObject ' ), FFI ::gobject ()->g_value_get_pointer (\FFI ::addr ($ params [1 ])));
115+ FFI ::gobject ()->g_object_ref ($ vi );
116+ $ image = new Image ($ vi );
117+ $ pr = \FFI ::cast (FFI ::ctypes ('VipsProgress ' ), FFI ::gobject ()->g_value_get_pointer (\FFI ::addr ($ params [2 ])));
118+ $ callback ($ image , $ pr );
119+ };
120+ $ marshalers = ['preeval ' => $ imageProgressCb , 'eval ' => $ imageProgressCb , 'posteval ' => $ imageProgressCb ];
121+
122+ if (FFI ::atLeast (8 , 9 )) {
123+ $ marshalers ['read ' ] = static function (
124+ CData $ gClosure ,
125+ CData $ returnValue ,
126+ int $ numberOfParams ,
127+ CData $ params ,
128+ CData $ hint ,
129+ ?CData $ data
130+ ) use (&$ callback ): void {
131+ assert ($ numberOfParams === 4 );
132+ /*
133+ * Marshal-Signature: gint64(VipsSourceCustom*, void*, gint64, void*)
134+ */
135+ $ bufferPointer = FFI ::gobject ()->g_value_get_pointer (\FFI ::addr ($ params [1 ]));
136+ $ bufferLength = (int ) FFI ::gobject ()->g_value_get_int64 (\FFI ::addr ($ params [2 ]));
137+ $ buffer = \FFI ::string ($ bufferPointer , $ bufferLength );
138+ $ returnBufferLength = $ callback ($ buffer );
139+ \FFI ::memcpy ($ bufferPointer , $ buffer , $ returnBufferLength );
140+ FFI ::gobject ()->g_value_set_int64 ($ returnValue , $ returnBufferLength );
141+ FFI ::gobject ()->g_value_set_pointer (\FFI ::addr ($ params [1 ]), $ bufferPointer );
110142 };
111- $ marshalers = ['preeval ' => $ imageProgressCb , 'eval ' => $ imageProgressCb , 'posteval ' => $ imageProgressCb ];
112-
113- if (FFI ::atLeast (8 , 9 )) {
114- $ marshalers ['read ' ] = static function (CData $ gObject , CData $ pointer , int $ length , CData $ handle ): int {
115- $ buffer = \FFI ::string ($ pointer , $ length );
116- return $ handle ($ buffer );
117- };
118- $ marshalers ['seek ' ] = static function (CData $ gObject , int $ offset , int $ whence , CData $ handle ): int {
119- return $ handle ($ offset , $ whence );
120- };
121- $ marshalers ['write ' ] = static function (CData $ gObject , CData $ pointer , int $ length , CData $ handle ): int {
122- $ buffer = \FFI ::string ($ pointer , $ length );
123- return $ handle ($ buffer );
124- };
125- $ marshalers ['finish ' ] = static function (CData $ gObject , CData $ handle ): void {
126- $ handle ();
127- };
128- }
143+ $ marshalers ['seek ' ] = static function (
144+ CData $ gClosure ,
145+ CData $ returnValue ,
146+ int $ numberOfParams ,
147+ CData $ params ,
148+ CData $ hint ,
149+ ?CData $ data
150+ ) use (&$ callback ): void {
151+ assert ($ numberOfParams === 4 );
152+ /*
153+ * Marshal-Signature: gint64(VipsSourceCustom*, gint64, int, void*)
154+ */
155+ $ offset = (int ) FFI ::gobject ()->g_value_get_int64 (\FFI ::addr ($ params [1 ]));
156+ $ whence = (int ) FFI ::gobject ()->g_value_get_int (\FFI ::addr ($ params [2 ]));
157+ FFI ::gobject ()->g_value_set_int64 ($ returnValue , $ callback ($ offset , $ whence ));
158+ };
159+ $ marshalers ['write ' ] = static function (
160+ CData $ gClosure ,
161+ CData $ returnValue ,
162+ int $ numberOfParams ,
163+ CData $ params ,
164+ CData $ hint ,
165+ ?CData $ data
166+ ) use (&$ callback ): void {
167+ assert ($ numberOfParams === 4 );
168+ /*
169+ * Marshal-Signature: gint64(VipsTargetCustom*, void*, gint64, void*)
170+ */
171+ $ bufferPointer = FFI ::gobject ()->g_value_get_pointer (\FFI ::addr ($ params [1 ]));
172+ $ bufferLength = (int ) FFI ::gobject ()->g_value_get_int64 (\FFI ::addr ($ params [2 ]));
173+ $ buffer = \FFI ::string ($ bufferPointer , $ bufferLength );
174+ FFI ::gobject ()->g_value_set_int64 ($ returnValue , $ callback ($ buffer ));
175+ };
176+ $ marshalers ['finish ' ] = static function (
177+ CData $ gClosure ,
178+ ?CData $ returnValue ,
179+ int $ numberOfParams ,
180+ CData $ params ,
181+ CData $ hint ,
182+ ?CData $ data
183+ ) use (&$ callback ): void {
184+ assert ($ numberOfParams === 2 );
185+ /**
186+ * Marshal-Signature: void(VipsTargetCustom*, void*)
187+ */
188+ $ callback ();
189+ };
190+ }
129191
130- if (FFI ::atLeast (8 , 13 )) {
131- $ marshalers ['end ' ] = static function (CData $ gObject , CData $ handle ): int {
132- return $ handle ();
133- };
134- }
192+ if (FFI ::atLeast (8 , 13 )) {
193+ $ marshalers ['end ' ] = static function (
194+ CData $ gClosure ,
195+ CData $ returnValue ,
196+ int $ numberOfParams ,
197+ CData $ params ,
198+ CData $ hint ,
199+ ?CData $ data
200+ ) use (&$ callback ): void {
201+ assert ($ numberOfParams === 2 );
202+ /**
203+ * Marshal-Signature: int(VipsTargetCustom*, void*)
204+ */
205+ FFI ::gobject ()->g_value_set_int ($ returnValue , $ callback ());
206+ };
135207 }
136208
137209 if (!isset ($ marshalers [$ name ])) {
138210 throw new Exception ("unsupported signal $ name " );
139211 }
140212
141213 $ go = \FFI ::cast (FFI ::ctypes ('GObject ' ), $ this ->pointer );
142- FFI ::gobject ()->g_signal_connect_data ($ go , $ name , $ marshalers [$ name ], $ callback , null , 0 );
214+ $ gc = FFI ::gobject ()->g_closure_new_simple (64 , null );
215+ $ gc ->marshal = $ marshalers [$ name ];
216+ FFI ::gobject ()->g_signal_connect_closure ($ go , $ name , $ gc , 0 );
143217 }
144218}
145219
0 commit comments