anchor.diff:                            sdl2-ffi:sdl-eventtype
                             "SDL-"))
   
  -(defwrapper event (sdl2-ffi:sdl-event))
  +(defun add-event-struct-slots (event-slots)
  +  (let ((hash-table (make-hash-table)))
  +    (loop for (event-type slot-name) in event-slots
  +       do (setf (gethash event-type hash-table) slot-name))
  +    hash-table))
  +
  +(defvar *event-struct-slots*
  +  (add-event-struct-slots
  +   (list (list :controlleraxismotion 'sdl2-ffi::caxis)
  +         (list :controllerbuttonup 'sdl2-ffi::cbutton)
  +         (list :controllerbuttondown 'sdl2-ffi::cbutton)
  +         (list :controllerdeviceremoved 'sdl2-ffi::cdevice)
  +         (list :controllerdeviceremapped 'sdl2-ffi::cdevice)
  +         (list :controllerdeviceadded 'sdl2-ffi::cdevice)
  +         (list :joyaxismotion 'sdl2-ffi::jaxis)
  +         (list :joyballmotion 'sdl2-ffi::jball)
  +         (list :joyhatmotion 'sdl2-ffi::jhat)
  +         (list :joybuttonup 'sdl2-ffi::jbutton)
  +         (list :joybuttondown 'sdl2-ffi::jbutton)
  +         (list :joydeviceadded 'sdl2-ffi::jdevice)
  +         (list :joydeviceremoved 'sdl2-ffi::jdevice)
  +         (list :keyup 'sdl2-ffi::key)
  +         (list :keydown 'sdl2-ffi::key)
  +         (list :mousewheel 'sdl2-ffi::wheel)
  +         (list :mousebuttonup 'sdl2-ffi::button)
  +         (list :mousebuttondown 'sdl2-ffi::button)
  +         (list :mousemotion 'sdl2-ffi::motion)
  +         (list :userevent 'sdl2-ffi::user)
  +         (list :windowevent 'sdl2-ffi::window)
  +         (list :quit 'sdl2-ffi::quit))))
   
   (defun new-event (&optional (event-type :firstevent))
     (let ((enum-value (foreign-enum-value 'event-type event-type))
  
positive.code:   (let ((enum-value (foreign-slot-value event-ptr 'sdl2-ffi:sdl-event 'type)))
      (foreign-enum-keyword 'event-type enum-value)))
  
  (defun event-value (event-ptr slot)
    (foreign-slot-value event-ptr 'sdl2-ffi:sdl-event (intern (string slot) :sdl2-ffi)))
  
  (defun get-event-data (event-ptr)
    (case (get-event-type event-ptr)
      (:windowevent ())
      (:keyboardevent ())
      (:mousemotion ())
      (:mousebuttonup ())
      (:mousebuttondown ())
      (:mousewheel ())
      (:joyaxismotion ())
      (:joyballmotion ())
      (:joyhatmotion ())
      (:joybuttonup ())
      (:joybuttondown ())
      (:joydeviceadded ())
      (:joydeviceremoved ())
      (:controlleraxismotion ())
      (:controllerbuttonup ())
      (:controllerbuttondown ())
      (:controllerdeviceadded ())
      (:controllerdeviceremoved ())
      (:controllerdeviceremapped ())
      (:quitevent ())
      (t ())))
  
  (defun next-event (event-ptr &optional (method :poll) (timeout 1))
    "Method can be either :poll, :wait, or :wait-with-timeout"
  
negative.code:            (event (list eventp (when eventp (get-event-data event-ptr)))))
        event)))
  
  (defmacro with-foreign-event ((event-ptr) &body body)
    `(let ((,event-ptr (new-event))
           (result (progn ,@body)))
       (free-event ,event-ptr)
       result))
  
  (defmacro poll-event ()
    `(with-foreign-event (event-ptr)
                         (next-event event-ptr)))
  
  (defun wait-event ()
    (with-foreign-event (event-ptr)
      (next-event event-ptr :wait)))
  
  (defun wait-event-timeout (timeout)
    (with-foreign-event (event-ptr)
      (next-event event-ptr :wait-with-timeout timeout)))
  
  (defun pump-events ()
    (sdl2-ffi:sdl-pumpevents))
  