Permalink
Browse files

Everything works as it should, I hope, now it's refactoring time.

  • Loading branch information...
1 parent 514d62a commit 61283a198907f165fa2ba619fa564ce8068c9f18 @jtza8 jtza8 committed with patzy Oct 26, 2011
View
23 src/osx/appkit.lisp
@@ -58,12 +58,9 @@
(:begin-gesture 19)
(:end-gesture 20))
-(defcfun ("NSEventGetType" %ns-event-type) ns-uinteger
+(defcfun ("NSEventGetType" ns-event-type) ns-event-type
(event :pointer))
-(defun ns-event-type (event)
- (foreign-enum-keyword 'ns-event-type (%ns-event-type event)))
-
(defcenum ns-key-code
:a
:s
@@ -199,16 +196,10 @@
(defcfun ("NSEventWindow" ns-event-window) :pointer
(event :pointer))
-(defcfun ("NSEventLocationInWindow" %ns-event-location-in-window) :void
- (event :pointer)
- (point :pointer))
+(defcfun ("NSEventLocationInWindow" ns-event-location-in-window) ns-point
+ (event :pointer))
-(defun ns-event-location-in-window (event)
- (with-foreign-object (point 'ns-point)
- (%ns-event-location-in-window event point)
- (let ((x (foreign-slot-value point 'ns-point 'x))
- (y (foreign-slot-value point 'ns-point 'y)))
- (list (truncate x) (truncate y)))))
+(defcfun ("NSEventMouseLocation" ns-event-mouse-location) ns-point)
(defcfun ("NSEventButtonNumber" ns-event-button-number) ns-integer
(event :pointer))
@@ -222,6 +213,9 @@
(defcfun ("NSEventCharacters" ns-event-characters) ns-string
(event :pointer))
+(defcfun ("GlopSendNoticeEvent" glop-send-notice-event) :void
+ (window :pointer))
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; NSApplication ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -466,4 +460,7 @@
(context :pointer))
(defcfun ("NSOpenGLContextFlushBuffer" ns-opengl-context-flush-buffer) :void
+ (context :pointer))
+
+(defcfun ("NSOpenGLContextUpdate" ns-opengl-context-update) :void
(context :pointer))
View
6 src/osx/bridge/GlopView.h
@@ -3,7 +3,10 @@
typedef enum {
GlopNoticeWindowClose,
- GlopNoticeWindowResize
+ GlopNoticeWindowResize,
+ GlopNoticeWindowExpose,
+ GlopNoticeWindowFocus,
+ GlopNoticeWindowUnfocus
} GlopNoticeType;
typedef struct glopNotice {
@@ -23,5 +26,6 @@ typedef void(*GlopEventCallback)(NSEvent*);
- (id)initWithEventCallback:(GlopEventCallback)eventCallbackFunc
noticeCallback:(GlopNoticeCallback)noticeCallbackFunc;
+- (void)sendGlopNotice:(GlopNoticeType)type;
@end
View
32 src/osx/bridge/GlopView.m
@@ -95,20 +95,37 @@ - (void)flagsChanged:(NSEvent *)event
eventCallback(event);
}
-- (void)windowWillClose:(NSNotification *)notification
+- (void)sendGlopNotice:(GlopNoticeType)type
{
GlopNotice *notice = malloc(sizeof(GlopNotice));
- notice->type = GlopNoticeWindowClose;
- notice->source = [notification object];
+ notice->type = type;
+ notice->source = [self window];
noticeCallback(notice);
}
+- (void)windowWillClose:(NSNotification *)notification
+{
+ [self sendGlopNotice:GlopNoticeWindowClose];
+}
+
- (void)windowDidResize:(NSNotification *)notification
{
- GlopNotice *notice = malloc(sizeof(GlopNotice));
- notice->type = GlopNoticeWindowResize;
- notice->source = [notification object];
- noticeCallback(notice);
+ [self sendGlopNotice:GlopNoticeWindowResize];
+}
+
+- (void)windowDidExpose:(NSNotification *)notification
+{
+ [self sendGlopNotice:GlopNoticeWindowExpose];
+}
+
+- (void)windowDidBecomeKey:(NSNotification *)notification
+{
+ [self sendGlopNotice:GlopNoticeWindowFocus];
+}
+
+- (void)windowDidResignKey:(NSNotification *)notification
+{
+ [self sendGlopNotice:GlopNoticeWindowUnfocus];
}
@end
@@ -120,4 +137,3 @@ - (void)windowDidResize:(NSNotification *)notification
return [[GlopView alloc] initWithEventCallback:eventCallbackFunc
noticeCallback:noticeCallbackFunc];
}
-
View
2 src/osx/bridge/Makefile
@@ -4,7 +4,7 @@ OBJ=foundation.o appkit.o GlopApp.o GlopView.o
all: glop-bridge.dylib
glop-bridge.dylib: ${OBJ}
- ld -dylib -o glop-bridge.dylib ${OBJ} -lc -framework AppKit,Carbon
+ ld -dylib -o glop-bridge.dylib ${OBJ} -lc -framework AppKit,Carbon,CoreServices
clean:
rm -f *.dylib *.o
View
37 src/osx/bridge/appkit.m
@@ -1,5 +1,7 @@
#include <AppKit/AppKit.h>
#include <malloc/malloc.h>
+#include <CoreServices/CoreServices.h>
+#include <unistd.h>
#include <string.h>
@@ -49,9 +51,20 @@ NSUInteger NSEventModifierFlags (NSEvent *event)
return [event window];
}
-void NSEventLocationInWindow (NSEvent *event, NSPoint *point)
+NSPoint *NSEventLocationInWindow (NSEvent *event)
{
- *point = [event locationInWindow];
+ NSPoint point = [event locationInWindow];
+ NSPoint *ptr = malloc(sizeof(NSPoint));
+ memcpy(ptr, &point, sizeof(NSPoint));
+ return ptr;
+}
+
+NSPoint *NSEventMouseLocation ()
+{
+ NSPoint point = [NSEvent mouseLocation];
+ NSPoint *ptr = malloc(sizeof(NSPoint));
+ memcpy(ptr, &point, sizeof(NSPoint));
+ return ptr;
}
NSInteger NSEventButtonNumber (NSEvent *event)
@@ -74,6 +87,21 @@ CGFloat NSEventDeltaY (NSEvent *event)
return [event characters];
}
+void GlopSendNoticeEvent (NSWindow *window)
+{
+ NSTimeInterval time = AbsoluteToDuration(UpTime())/(NSTimeInterval)1000.0;
+ NSEvent *event =
+ [NSEvent otherEventWithType:NSApplicationDefined
+ location:NSMakePoint(0.0, 0.0)
+ modifierFlags:0
+ timestamp:time
+ windowNumber:window == NULL ? 0 : [window windowNumber]
+ context:NULL
+ subtype:0
+ data1:0
+ data2:0];
+ [NSApp postEvent:event atStart:NO];
+}
/******************************************************************************/
/*** NSApplication ***/
@@ -288,3 +316,8 @@ void NSOpenGLContextFlushBuffer (NSOpenGLContext *context)
{
[context flushBuffer];
}
+
+void NSOpenGLContextUpdate (NSOpenGLContext *context)
+{
+ [context update];
+}
View
BIN src/osx/bridge/glop-bridge.dylib
Binary file not shown.
View
19 src/osx/foundation.lisp
@@ -10,10 +10,23 @@
(defctype ns-integer #+x86-64 :long #-x86-64 :int)
(defctype cg-float #+x86-64 :double #-x86-64 :float)
-(defcstruct ns-point
+(defcstruct ns-point-struct
(x cg-float)
(y cg-float))
+(define-foreign-type ns-point-type ()
+ ()
+ (:actual-type ns-point-struct)
+ (:simple-parser ns-point))
+
+(defmethod translate-from-foreign (point (type ns-point-type))
+ (with-foreign-slots ((x y) point ns-point-struct)
+ (list x y)))
+
+(defmethod free-translated-object (point (type ns-point-type) param)
+ (declare (ignore param))
+ (foreign-free point))
+
(defcstruct ns-size
(width cg-float)
(height cg-float))
@@ -25,7 +38,7 @@
(height 0 :type fixnum))
(defcstruct ns-rect-struct
- (point ns-point)
+ (point ns-point-struct)
(size ns-size))
(define-foreign-type ns-rect-type ()
@@ -35,7 +48,7 @@
(defmethod translate-from-foreign (ns-rect (type ns-rect-type))
(with-foreign-slots ((point size) ns-rect ns-rect-struct)
- (with-foreign-slots ((x y) point ns-point)
+ (with-foreign-slots ((x y) point ns-point-struct)
(with-foreign-slots ((width height) size ns-size)
(make-rect
:x (truncate x)
View
134 src/osx/glop-osx.lisp
@@ -2,11 +2,10 @@
(defparameter *autorelease-pool* nil)
(defparameter *opengl-bundle* nil)
-(defparameter *main-menu* nil)
(defparameter *event-stacks* (make-hash-table))
+(defparameter *fullscreen-active* nil)
(declaim (special *native-video-mode*))
-
(defun event-stack (ns-window)
(gethash (cffi:pointer-address ns-window) *event-stacks*))
@@ -86,12 +85,21 @@
((:mouse-moved :left-mouse-dragged :right-mouse-dragged
:other-mouse-dragged)
(destructuring-bind (x y)
- (glop-bridge:ns-event-location-in-window ns-event)
- (make-instance 'mouse-motion-event
- :x x
- :y y
- :dx (truncate (glop-bridge:ns-event-delta-x ns-event))
- :dy (truncate (glop-bridge:ns-event-delta-y ns-event)))))
+ (mapcar #'truncate
+ (if *fullscreen-active*
+ (glop-bridge:ns-event-mouse-location)
+ (glop-bridge:ns-event-location-in-window
+ ns-event)))
+ (let ((inverted-y (- (glop-bridge:rect-height
+ (glop-bridge:ns-view-frame
+ (glop-bridge:ns-window-content-view
+ (glop-bridge:ns-event-window ns-event))))
+ y)))
+ (make-instance 'mouse-motion-event
+ :x x
+ :y inverted-y
+ :dx (truncate (glop-bridge:ns-event-delta-x ns-event))
+ :dy (truncate (glop-bridge:ns-event-delta-y ns-event))))))
((:left-mouse-down :right-mouse-down :other-mouse-down)
(make-instance 'button-press-event
:button (glop-bridge:ns-event-button-number ns-event)
@@ -103,20 +111,43 @@
(when event
(push event (event-stack (glop-bridge:ns-event-window ns-event))))))
+(defun push-event (window event)
+ (with-accessors ((ns-window ns-window)) window
+ (push event (event-stack ns-window))
+ (glop-bridge:glop-send-notice-event ns-window)))
+
+(defun push-expose-event (window)
+ (with-accessors ((width window-width) (height window-height)) window
+ (push-event window
+ (make-instance 'expose-event :width width :height height))))
+
(cffi:defcallback push-notification-to-event-stack :void
((notice glop-bridge:glop-notice))
(destructuring-bind (&key type source) notice
- (let ((event
- (case type
- (:window-close (make-instance 'close-event))
- (:resize
- (let ((rect (glop-bridge:ns-view-frame
- (glop-bridge:ns-window-content-view source))))
- (make-instance 'resize-event
- :height (glop-bridge:rect-height rect)
- :width (glop-bridge:rect-width rect)))))))
- (when event
- (push event (event-stack source))))))
+ (macrolet ((with-view-size (width height &body body)
+ (let ((rect-var (gensym "RECT-")))
+ `(let* ((,rect-var (glop-bridge:ns-view-frame
+ (glop-bridge:ns-window-content-view
+ source)))
+ (,width (glop-bridge:rect-width ,rect-var))
+ (,height (glop-bridge:rect-height ,rect-var)))
+ ,@body))))
+ (let ((event
+ (case type
+ (:window-close (make-instance 'close-event))
+ (:window-resize
+ (with-view-size width height
+ (make-instance 'resize-event :width width :height height)))
+ (:window-expose
+ (with-view-size width height
+ (make-instance 'expose-event :width width :height height)))
+ (:window-focus
+ (make-instance 'focus-in-event :focused t))
+ (:window-unfocus
+ (make-instance 'focus-out-event :focused nil)))))
+ (when event
+ (push event (event-stack source))
+ (glop-bridge:glop-send-notice-event source))))))
(defmethod open-window ((window osx-window) title width height
&key (x 0) (y 0) (rgba t) (double-buffer t) stereo
@@ -127,6 +158,8 @@
(declare (ignore rgba accum-buffer stencil-buffer))
(when (cffi:null-pointer-p glop-bridge:*ns-app*) (init-ns-app))
(unless *autorelease-pool* (init-global-autorelease-pool))
+ (unless (boundp '*native-video-mode*)
+ (defparameter *native-video-mode* (current-video-mode)))
(let* ((color-size (+ red-size green-size blue-size alpha-size))
(accum-size (+ accum-red-size accum-blue-size accum-green-size))
(pf-list (list :full-screen
@@ -186,7 +219,9 @@
(defmethod attach-gl-context ((window osx-window) ctx)
(with-accessors ((gl-view gl-view)) window
- (glop-bridge:ns-opengl-context-set-view ctx gl-view)))
+ (glop-bridge:ns-opengl-context-make-current-context ctx)
+ (glop-bridge:ns-opengl-context-set-view ctx gl-view)
+ (push-expose-event window)))
(defmethod detach-gl-context (ctx)
(glop-bridge:ns-opengl-context-clear-drawable ctx))
@@ -199,27 +234,27 @@
(pixel-format-list pixel-format-list)
(ns-window ns-window) (gl-view gl-view)
(gl-context window-gl-context)) window
- (glop-bridge:with-ns-autorelease-pool
- (let ((pixel-format (glop-bridge:ns-autorelease
- (glop-bridge:ns-opengl-pixel-format-init
- pixel-format-list))))
- (setf gl-context (glop-bridge:ns-opengl-context-init pixel-format))
- (glop-bridge:ns-opengl-context-make-current-context gl-context)
- (attach-gl-context window gl-context)
- (glop-bridge:ns-opengl-context-set-view gl-context gl-view)))))
+ (let ((pixel-format (glop-bridge:ns-opengl-pixel-format-init
+ pixel-format-list)))
+ (glop-bridge:ns-autorelease
+ (setf gl-context (glop-bridge:ns-opengl-context-init pixel-format)))
+ (glop-bridge:ns-release pixel-format)
+ (attach-gl-context window gl-context))))
-(defmethod destroy-gl-context (context)
- (detach-gl-context context)
- (glop-bridge:ns-release context))
+(defmethod destroy-gl-context (ctx)
+ (detach-gl-context ctx))
(defmethod swap-buffers ((window osx-window))
(glop-bridge:ns-opengl-context-flush-buffer (window-gl-context window)))
(defmethod set-fullscreen ((window osx-window)
&optional (state (not (window-fullscreen window))))
(declare (ignorable window state))
+ (when (eq (window-fullscreen window) state)
+ (return-from set-fullscreen))
(with-accessors ((gl-context window-gl-context)
- (gl-view gl-view)) window
+ (gl-view gl-view)
+ (ns-window ns-window)) window
(if state
(let ((fullscreen-mode
(closest-video-mode (current-video-mode)
@@ -228,40 +263,43 @@
(window-height window))))
(glop-bridge:capture-all-displays)
(glop-bridge:set-display-mode
- (glop-bridge:main-display-id)
- (osx-video-mode-mode fullscreen-mode)
- (cffi:null-pointer))
+ (glop-bridge:main-display-id)
+ (osx-video-mode-mode fullscreen-mode)
+ (cffi:null-pointer))
(glop-bridge:ns-opengl-context-clear-drawable gl-context)
(glop-bridge:ns-opengl-context-set-full-screen gl-context)
- (glop-bridge:ns-retain gl-context)
- (setf (window-fullscreen window) t))
+ (setf (window-fullscreen window) t
+ *fullscreen-active* t)
+ (push-expose-event window))
(progn
(glop-bridge:set-display-mode
- (glop-bridge:main-display-id)
- (osx-video-mode-mode *native-video-mode*)
- (cffi:null-pointer))
+ (glop-bridge:main-display-id)
+ (osx-video-mode-mode *native-video-mode*)
+ (cffi:null-pointer))
(glop-bridge:ns-opengl-context-clear-drawable gl-context)
(glop-bridge:release-all-displays)
(glop-bridge:ns-opengl-context-set-view gl-context gl-view)
- (setf (window-fullscreen window) nil)))))
+ (setf (window-fullscreen window) nil
+ *fullscreen-active* nil)
+ (push-expose-event window)))))
(defun %next-event (win &key blocking)
(loop
for ns-window = (ns-window win)
for event = (glop-bridge:glop-app-next-event glop-bridge:*ns-app* blocking)
- for found = (cffi:pointer-eq ns-window (glop-bridge:ns-event-window event))
- do (progn (glop-bridge:glop-app-send-event glop-bridge:*ns-app* event)
+ for found = (or (cffi:pointer-eq ns-window
+ (glop-bridge:ns-event-window event))
+ *fullscreen-active*)
+ do (progn (glop-bridge:ns-event-type event)
+ (glop-bridge:glop-app-send-event glop-bridge:*ns-app* event)
(glop-bridge:glop-app-update-windows))
while (and blocking (or (not found) (null (event-stack ns-window))))
- finally (when found
- (return (pop (event-stack ns-window))))))
+ finally (when found (return (pop (event-stack ns-window))))))
(defun gl-get-proc-address (proc-name)
(init-opengl-bundle)
(let ((name (glop-bridge:ns-string-alloc-init-with-c-string
proc-name :iso-latin-1)))
(unwind-protect (glop-bridge:cf-bundle-get-function-pointer-for-name
*opengl-bundle* name)
- (glop-bridge:ns-release name))))
-
-(defparameter *native-video-mode* (current-video-mode))
+ (glop-bridge:ns-release name))))
View
5 src/osx/glop-view.lisp
@@ -2,7 +2,10 @@
(defcenum glop-notice-type
:window-close
- :window-resize)
+ :window-resize
+ :window-expose
+ :window-focus
+ :window-unfocus)
(defcstruct glop-notice-struct
(type glop-notice-type)
View
5 src/osx/package.lisp
@@ -101,4 +101,7 @@
#:capture-all-displays
#:release-all-displays
#:ns-opengl-context-set-full-screen
- #:translate-to-video-mode))
+ #:translate-to-video-mode
+ #:ns-opengl-context-update
+ #:glop-send-notice-event
+ #:ns-event-mouse-location))
View
6 src/utils.lisp
@@ -37,12 +37,12 @@
(defclass osx-window ()
((ns-window :initform nil
:accessor ns-window)
- (fs-window :initform nil
- :accessor fs-window)
(gl-view :initform nil
:accessor gl-view)
(pixel-format-list :initform '()
- :accessor pixel-format-list)))
+ :accessor pixel-format-list)
+ (invert-mouse-y :initform nil
+ :accessor invert-mouse-y)))
#+darwin
(defstruct (osx-video-mode (:include video-mode))

0 comments on commit 61283a1

Please sign in to comment.