
Here is an example (Racket 8.0 [cs]): #lang racket
(require gui-widget-mixins racket/gui)
(define tooltip-check-box% (tooltip-mixin check-box%))
(define clicks '())
(define (make-callback n)
(λ _ (set! clicks (cons n clicks))))
(define f (new frame% [label "A Frame"]))
(define vp (new vertical-panel% [parent f] ))
(define tcb1 (new tooltip-check-box% [parent vp] [label "Button 1"]
[callback (make-callback 1)]
[tooltip "This is button 1"]
[tooltip-delay 500]))
(define tcb2 (new tooltip-check-box% [parent vp] [label "Button 2"]
[callback (make-callback 2)]
[tooltip "This is button 2"]
[tooltip-delay 500]))
(send f show #t)

I retry 7.5 version. all the same. At this time last year, I directly executed build.bat. It took about half an hour and everything would be completed. At that time, it seemed that vcpkg was not installed on my computer. I thought it might be because I installed vcpkg, because when I opened it in visual studio, it would prompt me "Cannot identify debug or release, whether to close vcpkg, I chose yes. Then a new problem appeared.

"C:\Users\mingy\Desktop\racket-7.5\racket\src\worksp\racket\racketX.sln" (default target) (1) ->
“C:\Users\mingy\Desktop\racket–7.5\racket\src\worksp\racket\racketX.vcxproj” (default target) (2) -> (PostBuildEvent target) -> C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MS B3073: The command " [C:\Users\mingy\Desktop\racket–7.5\racket\src\worksp\racket\racketX.vcxproj] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3 073: if exist “C:\Users\mingy\Desktop\racket–7.5\racket\RacketCGC.exe” goto :MzOK [C:\Users\mingy\Desktop\racket–7.5\racket\src\worksp \racket\racketX.vcxproj] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3 073: echo Error: did not find C:\Users\mingy\Desktop\racket–7.5\racket\RacketCGC.exe [C:\Users\mingy\Desktop\racket–7.5\racket\src\wor ksp\racket\racketX.vcxproj] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3 073: exit 1 [C:\Users\mingy\Desktop\racket–7.5\racket\src\worksp\racket\racketX.vcxproj] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3 073: :MzOK [C:\Users\mingy\Desktop\racket–7.5\racket\src\worksp\racket\racketX.vcxproj] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3 073: “C:\Users\mingy\Desktop\racket–7.5\racket\RacketCGC.exe” -cu ....\racket\mkincludes.rkt “C:\Users\mingy\Desktop\racket–7.5\racke t/include/” ....\racket .. [C:\Users\mingy\Desktop\racket–7.5\racket\src\worksp\racket\racketX.vcxproj] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3 073: if errorlevel 1 exit 1 [C:\Users\mingy\Desktop\racket–7.5\racket\src\worksp\racket\racketX.vcxproj] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3 073: cd ....\racket\dynsrc [C:\Users\mingy\Desktop\racket–7.5\racket\src\worksp\racket\racketX.vcxproj] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3 073: call mkmzdyn.bat SRelease x64 [C:\Users\mingy\Desktop\racket–7.5\racket\src\worksp\racket\racketX.vcxproj] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3 073: cd ....\worksp\racket [C:\Users\mingy\Desktop\racket–7.5\racket\src\worksp\racket\racketX.vcxproj] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3 073: addman.bat [C:\Users\mingy\Desktop\racket–7.5\racket\src\worksp\racket\racketX.vcxproj] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3 073: [C:\Users\mingy\Desktop\racket–7.5\racket\src\worksp\racket\racketX.vcxproj] C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(155,5): error MSB3 073: :VCEnd" exited with code 1. [C:\Users\mingy\Desktop\racket–7.5\racket\src\worksp\racket\racketX.vcxproj]
1975 Warning(s)
1 Error(s)
Time Elapsed 00:01:34.29

I also considered whether it was because the folder directory had "-", and then I renamed the folder to racket. The result was the same as above.

I executed vcpkg integrate remove. I saw a familiar picture!

It’s a success!

Hello, if I want to know the implementation of racket, which version of the source code is most suitable for building a knowledge map, and what materials can I refer to?

I could not reproduce the bug with the sample program (running on Windows), so perhaps Mac OS does not sent “mouse leave” events to the widget. I attempted to work around this on the “ah/leave” branch, https://github.com/alex-hhh/gui-widget-mixins/tree/ah/leave, you can check if this solves the problem…

@alexharsanyi Thanks for looking into it. I see the same thing again. I cloned your repo. And (the second time…) remembered to checkout “ah/leave”. To make sure I was running the new version, I added a line that displays “tooltip-mixin”.

Good to know about vcpkg!
I recommend looking at the CS implementaton or Racket and ignoring the BC implementation. Depending on which layer you want to understand, start with either racket/src/ChezScheme/IMPLEMENTATION.md (that’s Chez Scheme, obviously) or racker/src/cs/README.txt (that describes the layers built on top of Chez Scheme).

thanks!

Hi! Does anybody have any idea why this doesn’t work? (let ([w (malloc _int)]
[h (malloc _int)])
(sdl2:query-texture texture #f #f w h)
(printf (format "Texture size: ~ax~a" (ptr-ref w _int) (ptr-ref h _int))))
According to the SDL docs, SDL_QueryTexture wants the address of the w (width) and h (height) variables, which this should provide. However, it bails, saying that “int*->C: argument is not `int*’ pointer”. However cpointer? says that it is. Thanks in advance!

What’s the context? Are you writing your own bindings or using an existing set?

@soegaard2 I am trying to use the sdl2 package from https://github.com/lockie/racket-sdl2.

I’m using the “pretty” version of the library, which is supposed to be more lispy instead of just direct ffi C calls. However, I think I’d have the same problem with the bare ffi.

@idraper has joined the channel

@josh803 In most FFI bindings I have seen, that kind of detail is hidden. However, let’s try and figure out how racket-sdl2
binds the function. It looks a bit complicated at first sight.

Hold on, I have that code.

In “pretty.rkt” I see: (define-sdl2 query-texture
(_fun _texture* _uint32*/null _int*/null _int*/null _int*/null -> _int))

That was what I was about to paste…

(define-ffi-definer define-sdl2 sdl2-lib #:make-c-id convention:uglify)


Let’s look up what #:make means.


As I understand it, that’s just what he’s using to “prettify” the library interface.

True.

He specifies the pointer to int arguments as _int*/null, which I think is supposed to mean it can be a pointer to _int (from ffi) or null (#f).

Maybe you just need to cast the value to an _int*/null ?

So, when I malloc an _int, it’s a pointer to allocated memory. So it should be what’s wanted there, but it dies on the type conversion.

In the code, I see: (define-cpointer-type _int*)
So the cpointers are tagged with their type, there _int*
.

Maybe I should malloc an _int* instead? But that doesn’t seem to make sense (from what I remember of C) — because it would be a pointer to an int instead of an actual int?

Yeah, it doesn’t like that either:

Here’s the error:

I don’t want to distract from the discussion (which is good regardless), but - ./shameless_plug - if you’re having issues with SDL2, you may want to consider the CSFML bindings: https://pkgs.racket-lang.org/package/csfml. I put a lot of effort into them handling all sorts of things for you (like automatically releasing FFI memory when no longer being used).

Maybe _cpointer/null
is useful?

#f
should map to null always in the FFI.

Thanks @massung! I actually have that up in another tab (after hearing about the r-cade project)…

@soegaard2, I can use #f for null, but in this case, I need to pass in the pointer to the int so that it can load it with the width and height information.

So null is not what I want.

I think, _cpointer/null handles the Racket #f to C null conversion automatically.

Wait a minute… Isn’t it _ptr the thing you need?

The code says: (define-cpointer-type _int*)
and the documentation of define-cpointer-type
says, that it uses _cpointer and _cpointer/null to _int* and _int*/null. Given (define-sdl2 query-texture
(_fun _texture* _uint32*/null _int*/null _int*/null _int*/null -> _int))
I think your cpointer needs to be tagged with ’_int*/null.

Even when it isn’t a null pointer.

Obviously it’s a 3rd party binding, but @josh803, you may want to try defining your own function here and seeing if you can get what you need that way. The issue is that these are being used as (optional) outputs. The FFI code can handle all of that for you.
This is an example of what I mean from CSFML:
(define-sfml sfRenderWindow_waitEvent
(_fun _sfRenderWindow* (e : (_ptr o _sfEvent)) -> (ok : _bool) -> (and ok e)))
Notice how the event is an output (the o
in (_ptr o _dfEvent)
? And the the binding is actually handling all the allocation and even returning of the value for you? In this case, it returns the AND of the boolean return value and whether or not the even was non-null (non-#f
), but the binding could just as easily have returned a list or multiple values.
Untested, but you could try something like:
(define-sdl2 query-texture
(_fun _texture* _int* _int* (w : (_ptr o _int)) (h : (_ptr o _int)) -> (ok : _int) -> (and (zero? ok) (list w h)))
I don’t remember the SDL2 API off-hand, but the above assumes the return value is 0 if successful.

And I don’t know what those first two _int*
parameters are meant to be, I just stuck them in there for consistency

Running the original program with a fresh raco install --auto gui-widget-mixins
crashes on my Mac.

That’s running from the command line, not in DrRacket

I would type unsafe-
into the search bar and it should turn up all of the documented ones.

Also version 8.0 cs ?

Yes

Catalina 10.15.7

same here

Not crashing on DrRacket, but the window was not letting me transfer focus back to Slack.

I saw that too.

Crash: $ racket gui-tooltip.rkt
objc[12503]: autorelease pool page 0x7ffd2595c000 corrupted
magic 0x00000000 0x00000000 0x00000000 0x00000000
should be 0xa1a1a1a1 0x4f545541 0x454c4552 0x21455341
pthread 0x10aadedc0
should be 0x10aadedc0

I wonder why quadmath doesn’t need to be moved.

I didn’t really had to move quadmath up. However, quadmath then started looking for libgfortran4 (libblas was looking for libgfortran3). So, I had to put both fortran 3&4 versions in libs/ and add another ffi load for it: (define gfortran-lib (case dist
[(fedora) (ffi-lib "libgfortran" '("5" #f))] ; Untested
[else (ffi-lib "libgfortran" '("3" #f))]))
(define gfortran-lib-1 (case dist
[(fedora) (ffi-lib "libgfortran" '("5" #f))] ; Untested
[else (ffi-lib "libgfortran" '("4" #f))]))

I am hoping it is this messy because I experimented with quite a few library versions - install & uninstall

Has anyone written a for
generator that provides the 2 values of a cons
cell from an assoc
list?

something like: (define items
`((a . 1)
(b . 2)
(c . 3)))
(for/list ([(k v) (in-assoc-list items)])
(format "~a: ~a~n" k v))

in-dict
will do that

Ah, so it will… thanks!

note that it will not do it fast

True — if speed is a big concern you can do a lot better with make-do-sequence
, like: (define (in-alist alist)
(make-do-sequence
(λ ()
(values
;; pos->element
(λ (xs) (values (caar xs) (cdar xs)))
;; next-pos
cdr
;; initial-position
alist
;; continue-with-pos?
(λ (xs) (not (null? xs)))
;; continue-with-val?
#f
;; continue-after-pos+val?
#f))))

@massung, I was able to modify sdl2’s pretty module like this: ;(define-sdl2 query-texture
; (_fun _texture* _uint32*/null _int*/null _int*/null _int*/null -> _int))
(define-sdl2 query-texture
(_fun _texture*
(format : (_ptr o _uint32))
(access : (_ptr o _int))
(w : (_ptr o _int))
(h : (_ptr o _int)) -> (ok : _int) -> (and (zero? ok) (list format access w h))))
(The commented out part at the top is the original function we were all looking at.) So now, it’s pretty much as you suggested, except I also added in format and access (because why not, right?). This seems pretty straightforward (now that you’ve explained it and I’ve bashed my head on the docs some more), so I’m not sure why the original author didn’t set it up that way. I certainly didn’t have any luck at all with my attempts to call it directly without the ffi helpers. I guess he may not have needed it for his use case? Or maybe there’s a performance implication I’m not aware of. Apparently “access” is an enum, so this could probably be developed further to be even more informative, but this works and I’m quite done for tonight!

@soegaard2, thanks for taking a look and your suggestions as well!

@hufangyu123 has joined the channel