#|Use like this: $ doas pkg_add sdl2 ecl $ ecl > (ext:install-c-compiler) > (setf c:*user-ld-flags* "-lSDL2") > (compile-file "keys.ecl.lisp" :load t) > (sdl2-receive-keys) ; pops up a window. Use the x button or your wm to quit Hope it helps someone. Ask jackdaniel to support you <3. I use the undrawn window for sloppy focus. ymmv |# (ffi:clines " #include <stdio.h> #include <SDL2/SDL.h> SDL_Renderer *renderer; SDL_Window *window; SDL_Event e; ") (defun c-keyname (sdlk) " sdlk should be an e.key.keysym.sym originating int. " (let ((cstring (ffi:c-inline (sdlk) (:int) :cstring "SDL_GetKeyName(#0)" :one-liner t))) (ffi:convert-from-cstring cstring))) (defun interpret-mods (keymod) " keymod should be an e.key.keysym.mod originating int. " (let ((mods '((:lshift . #x1) (:rshift . #x2) (:lctrl . #x40) (:rctrl . #x80) (:lalt . #x100) (:ralt . #x200) (:lgui . #x400) (:rgui . #x800) (:num . #x1000) (:caps . #x2000) (:mode . #x4000) (:scroll . #x8000)))) (loop :for mod :in mods :for kw := (car mod) :for hx := (cdr mod) :unless (zerop (logand hx keymod)) :collect kw))) (defun sdl2-receive-keys (&aux (keys ())) (let ((key 0) ; int (ie default enum) (mod 0)) ; uint16 (declare (:int key mod)) (ffi:c-progn (key mod) " if (SDL_Init(SDL_INIT_VIDEO) < 0) " (error "%s failed" 'SDL_INIT_VIDEO) " if (SDL_CreateWindowAndRenderer( 640, 480, SDL_WINDOW_RESIZABLE, &window, &renderer)) " (error "%s failed" 'SDL_WINDOW_RESIZABLE) " for (;;) { SDL_SetRenderDrawColor(renderer,0,0,0,255); SDL_RenderClear(renderer); SDL_RenderPresent(renderer); SDL_Delay(25); while (SDL_PollEvent(&e)) if (e.type == SDL_QUIT) { quit: SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit();" (return-from sdl2-receive-keys (nreverse keys)) " } else if (e.type == SDL_KEYDOWN) if (e.key.keysym.sym == SDLK_ESCAPE) goto quit; else { #0 = (int)(e.key.keysym.sym ); #1 = (int)(e.key.keysym.mod & 65475);" (push (list (intern (c-keyname key) :keyword) (interpret-mods mod) key mod) keys) "}}")))