summary refs log tree commit diff stats
path: root/libs/cocos2d/Platforms/Mac
diff options
context:
space:
mode:
Diffstat (limited to 'libs/cocos2d/Platforms/Mac')
-rwxr-xr-xlibs/cocos2d/Platforms/Mac/CCDirectorMac.h103
-rwxr-xr-xlibs/cocos2d/Platforms/Mac/CCDirectorMac.m479
-rwxr-xr-xlibs/cocos2d/Platforms/Mac/CCEventDispatcher.h277
-rwxr-xr-xlibs/cocos2d/Platforms/Mac/CCEventDispatcher.m645
-rwxr-xr-xlibs/cocos2d/Platforms/Mac/MacGLView.h89
-rwxr-xr-xlibs/cocos2d/Platforms/Mac/MacGLView.m242
-rwxr-xr-xlibs/cocos2d/Platforms/Mac/MacWindow.h42
-rwxr-xr-xlibs/cocos2d/Platforms/Mac/MacWindow.m70
8 files changed, 1947 insertions, 0 deletions
diff --git a/libs/cocos2d/Platforms/Mac/CCDirectorMac.h b/libs/cocos2d/Platforms/Mac/CCDirectorMac.h new file mode 100755 index 0000000..0d623b4 --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/CCDirectorMac.h
@@ -0,0 +1,103 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26
27// Only compile this code on Mac. These files should not be included on your iOS project.
28// But in case they are included, it won't be compiled.
29#import <Availability.h>
30#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
31#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
32
33#import <QuartzCore/CVDisplayLink.h>
34#import "../../CCDirector.h"
35
36enum {
37 /// If the window is resized, it won't be autoscaled
38 kCCDirectorResize_NoScale,
39 /// If the window is resized, it will be autoscaled (default behavior)
40 kCCDirectorResize_AutoScale,
41};
42
43@interface CCDirector (MacExtension)
44/** converts an NSEvent to GL coordinates */
45-(CGPoint) convertEventToGL:(NSEvent*)event;
46@end
47
48/** Base class of Mac directors
49 @since v0.99.5
50 */
51@interface CCDirectorMac : CCDirector
52{
53 BOOL isFullScreen_;
54 int resizeMode_;
55 CGPoint winOffset_;
56 CGSize originalWinSize_;
57
58 NSWindow *fullScreenWindow_;
59
60 // cache
61 NSWindow *windowGLView_;
62 NSView *superViewGLView_;
63 NSRect originalWinRect_; // Original size and position
64}
65
66// whether or not the view is in fullscreen mode
67@property (nonatomic, readonly) BOOL isFullScreen;
68
69// resize mode: with or without scaling
70@property (nonatomic, readwrite) int resizeMode;
71
72@property (nonatomic, readwrite) CGSize originalWinSize;
73
74/** Sets the view in fullscreen or window mode */
75- (void) setFullScreen:(BOOL)fullscreen;
76
77/** Converts window size coordiantes to logical coordinates.
78 Useful only if resizeMode is kCCDirectorResize_Scale.
79 If resizeMode is kCCDirectorResize_NoScale, then no conversion will be done.
80*/
81- (CGPoint) convertToLogicalCoordinates:(CGPoint)coordinates;
82@end
83
84
85/** DisplayLinkDirector is a Director that synchronizes timers with the refresh rate of the display.
86 *
87 * Features and Limitations:
88 * - Only available on 3.1+
89 * - Scheduled timers & drawing are synchronizes with the refresh rate of the display
90 * - Only supports animation intervals of 1/60 1/30 & 1/15
91 *
92 * It is the recommended Director if the SDK is 3.1 or newer
93 *
94 * @since v0.8.2
95 */
96@interface CCDirectorDisplayLink : CCDirectorMac
97{
98 CVDisplayLinkRef displayLink;
99}
100@end
101
102#endif // __MAC_OS_X_VERSION_MAX_ALLOWED
103
diff --git a/libs/cocos2d/Platforms/Mac/CCDirectorMac.m b/libs/cocos2d/Platforms/Mac/CCDirectorMac.m new file mode 100755 index 0000000..477081e --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/CCDirectorMac.m
@@ -0,0 +1,479 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26// Only compile this code on Mac. These files should not be included on your iOS project.
27// But in case they are included, it won't be compiled.
28#import <Availability.h>
29#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
30#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
31
32#import <sys/time.h>
33
34#import "CCDirectorMac.h"
35#import "CCEventDispatcher.h"
36#import "MacGLView.h"
37
38#import "../../CCNode.h"
39#import "../../CCScheduler.h"
40#import "../../ccMacros.h"
41
42#pragma mark -
43#pragma mark Director Mac extensions
44
45
46@interface CCDirector ()
47-(void) setNextScene;
48-(void) showFPS;
49-(void) calculateDeltaTime;
50@end
51
52@implementation CCDirector (MacExtension)
53-(CGPoint) convertEventToGL:(NSEvent*)event
54{
55 NSPoint point = [openGLView_ convertPoint:[event locationInWindow] fromView:nil];
56 CGPoint p = NSPointToCGPoint(point);
57
58 return [(CCDirectorMac*)self convertToLogicalCoordinates:p];
59}
60
61@end
62
63#pragma mark -
64#pragma mark Director Mac
65
66@implementation CCDirectorMac
67
68@synthesize isFullScreen = isFullScreen_;
69@synthesize originalWinSize = originalWinSize_;
70
71-(id) init
72{
73 if( (self = [super init]) ) {
74 isFullScreen_ = NO;
75 resizeMode_ = kCCDirectorResize_AutoScale;
76
77 originalWinSize_ = CGSizeZero;
78 fullScreenWindow_ = nil;
79 windowGLView_ = nil;
80 winOffset_ = CGPointZero;
81 }
82
83 return self;
84}
85
86- (void) dealloc
87{
88 [superViewGLView_ release];
89 [fullScreenWindow_ release];
90 [windowGLView_ release];
91 [super dealloc];
92}
93
94//
95// setFullScreen code taken from GLFullScreen example by Apple
96//
97- (void) setFullScreen:(BOOL)fullscreen
98{
99 // Mac OS X 10.6 and later offer a simplified mechanism to create full-screen contexts
100#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_5
101
102 if (isFullScreen_ == fullscreen) return;
103
104 if( fullscreen ) {
105 originalWinRect_ = [openGLView_ frame];
106
107 // Cache normal window and superview of openGLView
108 if(!windowGLView_)
109 windowGLView_ = [[openGLView_ window] retain];
110
111 [superViewGLView_ release];
112 superViewGLView_ = [[openGLView_ superview] retain];
113
114
115 // Get screen size
116 NSRect displayRect = [[NSScreen mainScreen] frame];
117
118 // Create a screen-sized window on the display you want to take over
119 fullScreenWindow_ = [[MacWindow alloc] initWithFrame:displayRect fullscreen:YES];
120
121 // Remove glView from window
122 [openGLView_ removeFromSuperview];
123
124 // Set new frame
125 [openGLView_ setFrame:displayRect];
126
127 // Attach glView to fullscreen window
128 [fullScreenWindow_ setContentView:openGLView_];
129
130 // Show the fullscreen window
131 [fullScreenWindow_ makeKeyAndOrderFront:self];
132 [fullScreenWindow_ makeMainWindow];
133
134 } else {
135
136 // Remove glView from fullscreen window
137 [openGLView_ removeFromSuperview];
138
139 // Release fullscreen window
140 [fullScreenWindow_ release];
141 fullScreenWindow_ = nil;
142
143 // Attach glView to superview
144 [superViewGLView_ addSubview:openGLView_];
145
146 // Set new frame
147 [openGLView_ setFrame:originalWinRect_];
148
149 // Show the window
150 [windowGLView_ makeKeyAndOrderFront:self];
151 [windowGLView_ makeMainWindow];
152 }
153 isFullScreen_ = fullscreen;
154
155 [openGLView_ retain]; // Retain +1
156
157 // re-configure glView
158 [self setOpenGLView:openGLView_];
159
160 [openGLView_ release]; // Retain -1
161
162 [openGLView_ setNeedsDisplay:YES];
163#else
164#error Full screen is not supported for Mac OS 10.5 or older yet
165#error If you don't want FullScreen support, you can safely remove these 2 lines
166#endif
167}
168
169-(void) setOpenGLView:(MacGLView *)view
170{
171 [super setOpenGLView:view];
172
173 // cache the NSWindow and NSOpenGLView created from the NIB
174 if( !isFullScreen_ && CGSizeEqualToSize(originalWinSize_, CGSizeZero))
175 {
176 originalWinSize_ = winSizeInPixels_;
177 }
178}
179
180-(int) resizeMode
181{
182 return resizeMode_;
183}
184
185-(void) setResizeMode:(int)mode
186{
187 if( mode != resizeMode_ ) {
188
189 resizeMode_ = mode;
190
191 [self setProjection:projection_];
192 [openGLView_ setNeedsDisplay: YES];
193 }
194}
195
196-(void) setProjection:(ccDirectorProjection)projection
197{
198 CGSize size = winSizeInPixels_;
199
200 CGPoint offset = CGPointZero;
201 float widthAspect = size.width;
202 float heightAspect = size.height;
203
204
205 if( resizeMode_ == kCCDirectorResize_AutoScale && ! CGSizeEqualToSize(originalWinSize_, CGSizeZero ) ) {
206
207 size = originalWinSize_;
208
209 float aspect = originalWinSize_.width / originalWinSize_.height;
210 widthAspect = winSizeInPixels_.width;
211 heightAspect = winSizeInPixels_.width / aspect;
212
213 if( heightAspect > winSizeInPixels_.height ) {
214 widthAspect = winSizeInPixels_.height * aspect;
215 heightAspect = winSizeInPixels_.height;
216 }
217
218 winOffset_.x = (winSizeInPixels_.width - widthAspect) / 2;
219 winOffset_.y = (winSizeInPixels_.height - heightAspect) / 2;
220
221 offset = winOffset_;
222
223 }
224
225 switch (projection) {
226 case kCCDirectorProjection2D:
227 glViewport(offset.x, offset.y, widthAspect, heightAspect);
228 glMatrixMode(GL_PROJECTION);
229 glLoadIdentity();
230 ccglOrtho(0, size.width, 0, size.height, -1024, 1024);
231 glMatrixMode(GL_MODELVIEW);
232 glLoadIdentity();
233 break;
234
235 case kCCDirectorProjection3D:
236 glViewport(offset.x, offset.y, widthAspect, heightAspect);
237 glMatrixMode(GL_PROJECTION);
238 glLoadIdentity();
239 gluPerspective(60, (GLfloat)widthAspect/heightAspect, 0.1f, 1500.0f);
240
241 glMatrixMode(GL_MODELVIEW);
242 glLoadIdentity();
243
244 float eyeZ = size.height * [self getZEye] / winSizeInPixels_.height;
245
246 gluLookAt( size.width/2, size.height/2, eyeZ,
247 size.width/2, size.height/2, 0,
248 0.0f, 1.0f, 0.0f);
249 break;
250
251 case kCCDirectorProjectionCustom:
252 if( projectionDelegate_ )
253 [projectionDelegate_ updateProjection];
254 break;
255
256 default:
257 CCLOG(@"cocos2d: Director: unrecognized projecgtion");
258 break;
259 }
260
261 projection_ = projection;
262}
263
264// If scaling is supported, then it should always return the original size
265// otherwise it should return the "real" size.
266-(CGSize) winSize
267{
268 if( resizeMode_ == kCCDirectorResize_AutoScale )
269 return originalWinSize_;
270
271 return winSizeInPixels_;
272}
273
274-(CGSize) winSizeInPixels
275{
276 return [self winSize];
277}
278
279- (CGPoint) convertToLogicalCoordinates:(CGPoint)coords
280{
281 CGPoint ret;
282
283 if( resizeMode_ == kCCDirectorResize_NoScale )
284 ret = coords;
285
286 else {
287
288 float x_diff = originalWinSize_.width / (winSizeInPixels_.width - winOffset_.x * 2);
289 float y_diff = originalWinSize_.height / (winSizeInPixels_.height - winOffset_.y * 2);
290
291 float adjust_x = (winSizeInPixels_.width * x_diff - originalWinSize_.width ) / 2;
292 float adjust_y = (winSizeInPixels_.height * y_diff - originalWinSize_.height ) / 2;
293
294 ret = CGPointMake( (x_diff * coords.x) - adjust_x, ( y_diff * coords.y ) - adjust_y );
295 }
296
297 return ret;
298}
299@end
300
301
302#pragma mark -
303#pragma mark DirectorDisplayLink
304
305
306@implementation CCDirectorDisplayLink
307
308- (CVReturn) getFrameForTime:(const CVTimeStamp*)outputTime
309{
310#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
311 if( ! runningThread_ )
312 runningThread_ = [NSThread currentThread];
313
314 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
315
316 [self drawScene];
317 [[CCEventDispatcher sharedDispatcher] dispatchQueuedEvents];
318
319 [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:nil];
320
321 [pool release];
322
323#else
324 [self performSelector:@selector(drawScene) onThread:runningThread_ withObject:nil waitUntilDone:YES];
325#endif
326
327 return kCVReturnSuccess;
328}
329
330// This is the renderer output callback function
331static CVReturn MyDisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext)
332{
333 CVReturn result = [(CCDirectorDisplayLink*)displayLinkContext getFrameForTime:outputTime];
334 return result;
335}
336
337- (void) startAnimation
338{
339#if ! CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
340 runningThread_ = [[NSThread alloc] initWithTarget:self selector:@selector(mainLoop) object:nil];
341 [runningThread_ start];
342#endif
343
344 gettimeofday( &lastUpdate_, NULL);
345
346 // Create a display link capable of being used with all active displays
347 CVDisplayLinkCreateWithActiveCGDisplays(&displayLink);
348
349 // Set the renderer output callback function
350 CVDisplayLinkSetOutputCallback(displayLink, &MyDisplayLinkCallback, self);
351
352 // Set the display link for the current renderer
353 CGLContextObj cglContext = [[openGLView_ openGLContext] CGLContextObj];
354 CGLPixelFormatObj cglPixelFormat = [[openGLView_ pixelFormat] CGLPixelFormatObj];
355 CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, cglContext, cglPixelFormat);
356
357 // Activate the display link
358 CVDisplayLinkStart(displayLink);
359}
360
361- (void) stopAnimation
362{
363 if( displayLink ) {
364 CVDisplayLinkStop(displayLink);
365 CVDisplayLinkRelease(displayLink);
366 displayLink = NULL;
367
368#if ! CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
369 [runningThread_ cancel];
370 [runningThread_ release];
371 runningThread_ = nil;
372#endif
373 }
374}
375
376-(void) dealloc
377{
378 if( displayLink ) {
379 CVDisplayLinkStop(displayLink);
380 CVDisplayLinkRelease(displayLink);
381 }
382 [super dealloc];
383}
384
385//
386// Mac Director has its own thread
387//
388-(void) mainLoop
389{
390 while( ![[NSThread currentThread] isCancelled] ) {
391 // There is no autorelease pool when this method is called because it will be called from a background thread
392 // It's important to create one or you will leak objects
393 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
394
395 [[NSRunLoop currentRunLoop] run];
396
397 [pool release];
398 }
399}
400
401//
402// Draw the Scene
403//
404- (void) drawScene
405{
406 // We draw on a secondary thread through the display link
407 // When resizing the view, -reshape is called automatically on the main thread
408 // Add a mutex around to avoid the threads accessing the context simultaneously when resizing
409 CGLLockContext([[openGLView_ openGLContext] CGLContextObj]);
410 [[openGLView_ openGLContext] makeCurrentContext];
411
412 /* calculate "global" dt */
413 [self calculateDeltaTime];
414
415 /* tick before glClear: issue #533 */
416 if( ! isPaused_ ) {
417 [[CCScheduler sharedScheduler] tick: dt];
418 }
419
420 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
421
422 /* to avoid flickr, nextScene MUST be here: after tick and before draw.
423 XXX: Which bug is this one. It seems that it can't be reproduced with v0.9 */
424 if( nextScene_ )
425 [self setNextScene];
426
427 glPushMatrix();
428
429
430 // By default enable VertexArray, ColorArray, TextureCoordArray and Texture2D
431 CC_ENABLE_DEFAULT_GL_STATES();
432
433 /* draw the scene */
434 [runningScene_ visit];
435
436 /* draw the notification node */
437 [notificationNode_ visit];
438
439 if( displayFPS_ )
440 [self showFPS];
441
442#if CC_ENABLE_PROFILERS
443 [self showProfilers];
444#endif
445
446 CC_DISABLE_DEFAULT_GL_STATES();
447
448 glPopMatrix();
449
450 [[openGLView_ openGLContext] flushBuffer];
451 CGLUnlockContext([[openGLView_ openGLContext] CGLContextObj]);
452}
453
454// set the event dispatcher
455-(void) setOpenGLView:(MacGLView *)view
456{
457 if( view != openGLView_ ) {
458
459 [super setOpenGLView:view];
460
461 CCEventDispatcher *eventDispatcher = [CCEventDispatcher sharedDispatcher];
462 [openGLView_ setEventDelegate: eventDispatcher];
463 [eventDispatcher setDispatchEvents: YES];
464
465 // Enable Touches. Default no.
466 [view setAcceptsTouchEvents:NO];
467// [view setAcceptsTouchEvents:YES];
468
469
470 // Synchronize buffer swaps with vertical refresh rate
471 [[view openGLContext] makeCurrentContext];
472 GLint swapInt = 1;
473 [[view openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
474 }
475}
476
477@end
478
479#endif // __MAC_OS_X_VERSION_MAX_ALLOWED
diff --git a/libs/cocos2d/Platforms/Mac/CCEventDispatcher.h b/libs/cocos2d/Platforms/Mac/CCEventDispatcher.h new file mode 100755 index 0000000..06889e8 --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/CCEventDispatcher.h
@@ -0,0 +1,277 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26// Only compile this code on Mac. These files should not be included on your iOS project.
27// But in case they are included, it won't be compiled.
28#import <Availability.h>
29#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
30#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
31
32#import <Cocoa/Cocoa.h>
33
34#import "MacGLView.h"
35#import "../../Support/uthash.h" // hack: uthash needs to be imported before utlist to prevent warning
36#import "../../Support/utlist.h"
37#import "../../ccConfig.h"
38
39#pragma mark -
40#pragma mark CCMouseEventDelegate
41
42/** CCMouseEventDelegate protocol.
43 Implement it in your node to receive any of mouse events
44 */
45@protocol CCMouseEventDelegate <NSObject>
46@optional
47
48//
49// left
50//
51/** called when the "mouseDown" event is received.
52 Return YES to avoid propagating the event to other delegates.
53 */
54-(BOOL) ccMouseDown:(NSEvent*)event;
55
56/** called when the "mouseDragged" event is received.
57 Return YES to avoid propagating the event to other delegates.
58 */
59-(BOOL) ccMouseDragged:(NSEvent*)event;
60
61/** called when the "mouseMoved" event is received.
62 Return YES to avoid propagating the event to other delegates.
63 By default, "mouseMoved" is disabled. To enable it, send the "setAcceptsMouseMovedEvents:YES" message to the main window.
64 */
65-(BOOL) ccMouseMoved:(NSEvent*)event;
66
67/** called when the "mouseUp" event is received.
68 Return YES to avoid propagating the event to other delegates.
69 */
70-(BOOL) ccMouseUp:(NSEvent*)event;
71
72
73//
74// right
75//
76
77/** called when the "rightMouseDown" event is received.
78 Return YES to avoid propagating the event to other delegates.
79 */
80-(BOOL) ccRightMouseDown:(NSEvent*)event;
81
82/** called when the "rightMouseDragged" event is received.
83 Return YES to avoid propagating the event to other delegates.
84 */
85-(BOOL) ccRightMouseDragged:(NSEvent*)event;
86
87/** called when the "rightMouseUp" event is received.
88 Return YES to avoid propagating the event to other delegates.
89 */
90-(BOOL) ccRightMouseUp:(NSEvent*)event;
91
92//
93// other
94//
95
96/** called when the "otherMouseDown" event is received.
97 Return YES to avoid propagating the event to other delegates.
98 */
99-(BOOL) ccOtherMouseDown:(NSEvent*)event;
100
101/** called when the "otherMouseDragged" event is received.
102 Return YES to avoid propagating the event to other delegates.
103 */
104-(BOOL) ccOtherMouseDragged:(NSEvent*)event;
105
106/** called when the "otherMouseUp" event is received.
107 Return YES to avoid propagating the event to other delegates.
108 */
109-(BOOL) ccOtherMouseUp:(NSEvent*)event;
110
111//
112// scroll wheel
113//
114
115/** called when the "scrollWheel" event is received.
116 Return YES to avoid propagating the event to other delegates.
117 */
118- (BOOL)ccScrollWheel:(NSEvent *)theEvent;
119
120
121//
122// enter / exit
123//
124
125/** called when the "mouseEntered" event is received.
126 Return YES to avoid propagating the event to other delegates.
127 */
128- (void)ccMouseEntered:(NSEvent *)theEvent;
129
130/** called when the "mouseExited" event is received.
131 Return YES to avoid propagating the event to other delegates.
132 */
133- (void)ccMouseExited:(NSEvent *)theEvent;
134
135@end
136
137#pragma mark -
138#pragma mark CCKeyboardEventDelegate
139
140/** CCKeyboardEventDelegate protocol.
141 Implement it in your node to receive any of keyboard events
142 */
143@protocol CCKeyboardEventDelegate <NSObject>
144@optional
145/** called when the "keyUp" event is received.
146 Return YES to avoid propagating the event to other delegates.
147 */
148-(BOOL) ccKeyUp:(NSEvent*)event;
149
150/** called when the "keyDown" event is received.
151 Return YES to avoid propagating the event to other delegates.
152 */
153-(BOOL) ccKeyDown:(NSEvent*)event;
154/** called when the "flagsChanged" event is received.
155 Return YES to avoid propagating the event to other delegates.
156 */
157-(BOOL) ccFlagsChanged:(NSEvent*)event;
158@end
159
160#pragma mark -
161#pragma mark CCTouchEventDelegate
162
163/** CCTouchEventDelegate protocol.
164 Implement it in your node to receive any of touch events
165 */
166@protocol CCTouchEventDelegate <NSObject>
167@optional
168/** called when the "touchesBegan" event is received.
169 Return YES to avoid propagating the event to other delegates.
170 */
171- (BOOL)ccTouchesBeganWithEvent:(NSEvent *)event;
172
173/** called when the "touchesMoved" event is received.
174 Return YES to avoid propagating the event to other delegates.
175 */
176- (BOOL)ccTouchesMovedWithEvent:(NSEvent *)event;
177
178/** called when the "touchesEnded" event is received.
179 Return YES to avoid propagating the event to other delegates.
180 */
181- (BOOL)ccTouchesEndedWithEvent:(NSEvent *)event;
182
183/** called when the "touchesCancelled" event is received.
184 Return YES to avoid propagating the event to other delegates.
185 */
186- (BOOL)ccTouchesCancelledWithEvent:(NSEvent *)event;
187
188@end
189
190
191#pragma mark -
192#pragma mark CCEventDispatcher
193
194struct _listEntry;
195
196/** CCEventDispatcher
197
198 This is object is responsible for dispatching the events:
199 - Mouse events
200 - Keyboard events
201 - Touch events
202
203 Only available on Mac
204 */
205@interface CCEventDispatcher : NSObject <MacEventDelegate> {
206
207 BOOL dispatchEvents_;
208
209 struct _listEntry *keyboardDelegates_;
210 struct _listEntry *mouseDelegates_;
211 struct _listEntry *touchDelegates_;
212}
213
214@property (nonatomic, readwrite) BOOL dispatchEvents;
215
216
217/** CCEventDispatcher singleton */
218+(CCEventDispatcher*) sharedDispatcher;
219
220#pragma mark CCEventDispatcher - Mouse
221
222/** Adds a mouse delegate to the dispatcher's list.
223 Delegates with a lower priority value will be called before higher priority values.
224 All the events will be propgated to all the delegates, unless the one delegate returns YES.
225
226 IMPORTANT: The delegate will be retained.
227 */
228-(void) addMouseDelegate:(id<CCMouseEventDelegate>) delegate priority:(NSInteger)priority;
229
230/** removes a mouse delegate */
231-(void) removeMouseDelegate:(id) delegate;
232
233/** Removes all mouse delegates, releasing all the delegates */
234-(void) removeAllMouseDelegates;
235
236#pragma mark CCEventDispatcher - Keyboard
237
238/** Adds a Keyboard delegate to the dispatcher's list.
239 Delegates with a lower priority value will be called before higher priority values.
240 All the events will be propgated to all the delegates, unless the one delegate returns YES.
241
242 IMPORTANT: The delegate will be retained.
243 */
244-(void) addKeyboardDelegate:(id<CCKeyboardEventDelegate>) delegate priority:(NSInteger)priority;
245
246/** removes a mouse delegate */
247-(void) removeKeyboardDelegate:(id) delegate;
248
249/** Removes all mouse delegates, releasing all the delegates */
250-(void) removeAllKeyboardDelegates;
251
252#pragma mark CCEventDispatcher - Touches
253
254/** Adds a Touch delegate to the dispatcher's list.
255 Delegates with a lower priority value will be called before higher priority values.
256 All the events will be propgated to all the delegates, unless the one delegate returns YES.
257
258 IMPORTANT: The delegate will be retained.
259 */
260- (void)addTouchDelegate:(id<CCTouchEventDelegate>)delegate priority:(NSInteger)priority;
261
262/** Removes a touch delegate */
263- (void)removeTouchDelegate:(id) delegate;
264
265/** Removes all touch delegates, releasing all the delegates */
266- (void)removeAllTouchDelegates;
267
268#pragma mark CCEventDispatcher - Dispatch Events
269
270#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
271-(void) dispatchQueuedEvents;
272#endif
273
274@end
275
276
277#endif // __MAC_OS_X_VERSION_MAX_ALLOWED
diff --git a/libs/cocos2d/Platforms/Mac/CCEventDispatcher.m b/libs/cocos2d/Platforms/Mac/CCEventDispatcher.m new file mode 100755 index 0000000..1d1740e --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/CCEventDispatcher.m
@@ -0,0 +1,645 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26// Only compile this code on Mac. These files should not be included on your iOS project.
27// But in case they are included, it won't be compiled.
28#import <Availability.h>
29#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
30#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
31
32#import "CCEventDispatcher.h"
33#import "../../ccConfig.h"
34
35static CCEventDispatcher *sharedDispatcher = nil;
36
37enum {
38 // mouse
39 kCCImplementsMouseDown = 1 << 0,
40 kCCImplementsMouseMoved = 1 << 1,
41 kCCImplementsMouseDragged = 1 << 2,
42 kCCImplementsMouseUp = 1 << 3,
43 kCCImplementsRightMouseDown = 1 << 4,
44 kCCImplementsRightMouseDragged = 1 << 5,
45 kCCImplementsRightMouseUp = 1 << 6,
46 kCCImplementsOtherMouseDown = 1 << 7,
47 kCCImplementsOtherMouseDragged = 1 << 8,
48 kCCImplementsOtherMouseUp = 1 << 9,
49 kCCImplementsScrollWheel = 1 << 10,
50 kCCImplementsMouseEntered = 1 << 11,
51 kCCImplementsMouseExited = 1 << 12,
52
53 kCCImplementsTouchesBegan = 1 << 13,
54 kCCImplementsTouchesMoved = 1 << 14,
55 kCCImplementsTouchesEnded = 1 << 15,
56 kCCImplementsTouchesCancelled = 1 << 16,
57
58 // keyboard
59 kCCImplementsKeyUp = 1 << 0,
60 kCCImplementsKeyDown = 1 << 1,
61 kCCImplementsFlagsChanged = 1 << 2,
62};
63
64
65typedef struct _listEntry
66{
67 struct _listEntry *prev, *next;
68 id delegate;
69 NSInteger priority;
70 NSUInteger flags;
71} tListEntry;
72
73
74#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
75
76#define QUEUE_EVENT_MAX 128
77struct _eventQueue {
78 SEL selector;
79 NSEvent *event;
80};
81
82static struct _eventQueue eventQueue[QUEUE_EVENT_MAX];
83static int eventQueueCount;
84
85#endif // CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
86
87
88@implementation CCEventDispatcher
89
90@synthesize dispatchEvents=dispatchEvents_;
91
92
93+(CCEventDispatcher*) sharedDispatcher
94{
95 @synchronized(self) {
96 if (sharedDispatcher == nil)
97 sharedDispatcher = [[self alloc] init]; // assignment not done here
98 }
99 return sharedDispatcher;
100}
101
102+(id) allocWithZone:(NSZone *)zone
103{
104 @synchronized(self) {
105 NSAssert(sharedDispatcher == nil, @"Attempted to allocate a second instance of a singleton.");
106 return [super allocWithZone:zone];
107 }
108 return nil; // on subsequent allocation attempts return nil
109}
110
111-(id) init
112{
113 if( (self = [super init]) )
114 {
115 // events enabled by default
116 dispatchEvents_ = YES;
117
118 // delegates
119 keyboardDelegates_ = NULL;
120 mouseDelegates_ = NULL;
121 touchDelegates_ = NULL;
122
123#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
124 eventQueueCount = 0;
125#endif
126 }
127
128 return self;
129}
130
131- (void) dealloc
132{
133 [super dealloc];
134}
135
136#pragma mark CCEventDispatcher - add / remove delegates
137
138-(void) addDelegate:(id)delegate priority:(NSInteger)priority flags:(NSUInteger)flags list:(tListEntry**)list
139{
140 tListEntry *listElement = malloc( sizeof(*listElement) );
141
142 listElement->delegate = [delegate retain];
143 listElement->priority = priority;
144 listElement->flags = flags;
145 listElement->next = listElement->prev = NULL;
146
147 // empty list ?
148 if( ! *list ) {
149 DL_APPEND( *list, listElement );
150
151 } else {
152 BOOL added = NO;
153
154 for( tListEntry *elem = *list; elem ; elem = elem->next ) {
155 if( priority < elem->priority ) {
156
157 if( elem == *list )
158 DL_PREPEND(*list, listElement);
159 else {
160 listElement->next = elem;
161 listElement->prev = elem->prev;
162
163 elem->prev->next = listElement;
164 elem->prev = listElement;
165 }
166
167 added = YES;
168 break;
169 }
170 }
171
172 // Not added? priority has the higher value. Append it.
173 if( !added )
174 DL_APPEND(*list, listElement);
175 }
176}
177
178-(void) removeDelegate:(id)delegate fromList:(tListEntry**)list
179{
180 tListEntry *entry, *tmp;
181
182 // updates with priority < 0
183 DL_FOREACH_SAFE( *list, entry, tmp ) {
184 if( entry->delegate == delegate ) {
185 DL_DELETE( *list, entry );
186 [delegate release];
187 free(entry);
188 break;
189 }
190 }
191}
192
193-(void) removeAllDelegatesFromList:(tListEntry**)list
194{
195 tListEntry *entry, *tmp;
196
197 DL_FOREACH_SAFE( *list, entry, tmp ) {
198 DL_DELETE( *list, entry );
199 free(entry);
200 }
201}
202
203
204-(void) addMouseDelegate:(id<CCMouseEventDelegate>) delegate priority:(NSInteger)priority
205{
206 NSUInteger flags = 0;
207
208 flags |= ( [delegate respondsToSelector:@selector(ccMouseDown:)] ? kCCImplementsMouseDown : 0 );
209 flags |= ( [delegate respondsToSelector:@selector(ccMouseDragged:)] ? kCCImplementsMouseDragged : 0 );
210 flags |= ( [delegate respondsToSelector:@selector(ccMouseMoved:)] ? kCCImplementsMouseMoved : 0 );
211 flags |= ( [delegate respondsToSelector:@selector(ccMouseUp:)] ? kCCImplementsMouseUp : 0 );
212
213 flags |= ( [delegate respondsToSelector:@selector(ccRightMouseDown:)] ? kCCImplementsRightMouseDown : 0 );
214 flags |= ( [delegate respondsToSelector:@selector(ccRightMouseDragged:)] ? kCCImplementsRightMouseDragged : 0 );
215 flags |= ( [delegate respondsToSelector:@selector(ccRightMouseUp:)] ? kCCImplementsRightMouseUp : 0 );
216
217 flags |= ( [delegate respondsToSelector:@selector(ccOtherMouseDown:)] ? kCCImplementsOtherMouseDown : 0 );
218 flags |= ( [delegate respondsToSelector:@selector(ccOtherMouseDragged:)] ? kCCImplementsOtherMouseDragged : 0 );
219 flags |= ( [delegate respondsToSelector:@selector(ccOtherMouseUp:)] ? kCCImplementsOtherMouseUp : 0 );
220
221 flags |= ( [delegate respondsToSelector:@selector(ccMouseEntered:)] ? kCCImplementsMouseEntered : 0 );
222 flags |= ( [delegate respondsToSelector:@selector(ccMouseExited:)] ? kCCImplementsMouseExited : 0 );
223
224 flags |= ( [delegate respondsToSelector:@selector(ccScrollWheel:)] ? kCCImplementsScrollWheel : 0 );
225
226 [self addDelegate:delegate priority:priority flags:flags list:&mouseDelegates_];
227}
228
229-(void) removeMouseDelegate:(id) delegate
230{
231 [self removeDelegate:delegate fromList:&mouseDelegates_];
232}
233
234-(void) removeAllMouseDelegates
235{
236 [self removeAllDelegatesFromList:&mouseDelegates_];
237}
238
239-(void) addKeyboardDelegate:(id<CCKeyboardEventDelegate>) delegate priority:(NSInteger)priority
240{
241 NSUInteger flags = 0;
242
243 flags |= ( [delegate respondsToSelector:@selector(ccKeyUp:)] ? kCCImplementsKeyUp : 0 );
244 flags |= ( [delegate respondsToSelector:@selector(ccKeyDown:)] ? kCCImplementsKeyDown : 0 );
245 flags |= ( [delegate respondsToSelector:@selector(ccFlagsChanged:)] ? kCCImplementsFlagsChanged : 0 );
246
247 [self addDelegate:delegate priority:priority flags:flags list:&keyboardDelegates_];
248}
249
250-(void) removeKeyboardDelegate:(id) delegate
251{
252 [self removeDelegate:delegate fromList:&keyboardDelegates_];
253}
254
255-(void) removeAllKeyboardDelegates
256{
257 [self removeAllDelegatesFromList:&keyboardDelegates_];
258}
259
260-(void) addTouchDelegate:(id<CCTouchEventDelegate>) delegate priority:(NSInteger)priority
261{
262 NSUInteger flags = 0;
263
264 flags |= ( [delegate respondsToSelector:@selector(ccTouchesBeganWithEvent:)] ? kCCImplementsTouchesBegan : 0 );
265 flags |= ( [delegate respondsToSelector:@selector(ccTouchesMovedWithEvent:)] ? kCCImplementsTouchesMoved : 0 );
266 flags |= ( [delegate respondsToSelector:@selector(ccTouchesEndedWithEvent:)] ? kCCImplementsTouchesEnded : 0 );
267 flags |= ( [delegate respondsToSelector:@selector(ccTouchesCancelledWithEvent:)] ? kCCImplementsTouchesCancelled : 0 );
268
269 [self addDelegate:delegate priority:priority flags:flags list:&touchDelegates_];
270}
271
272-(void) removeTouchDelegate:(id) delegate
273{
274 [self removeDelegate:delegate fromList:&touchDelegates_];
275}
276
277-(void) removeAllTouchDelegates
278{
279 [self removeAllDelegatesFromList:&touchDelegates_];
280}
281
282
283#pragma mark CCEventDispatcher - Mouse events
284//
285// Mouse events
286//
287
288//
289// Left
290//
291- (void)mouseDown:(NSEvent *)event
292{
293 if( dispatchEvents_ ) {
294 tListEntry *entry, *tmp;
295
296 DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
297 if ( entry->flags & kCCImplementsMouseDown ) {
298 void *swallows = [entry->delegate performSelector:@selector(ccMouseDown:) withObject:event];
299 if( swallows )
300 break;
301 }
302 }
303 }
304}
305
306- (void)mouseMoved:(NSEvent *)event
307{
308 if( dispatchEvents_ ) {
309 tListEntry *entry, *tmp;
310
311 DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
312 if ( entry->flags & kCCImplementsMouseMoved ) {
313 void *swallows = [entry->delegate performSelector:@selector(ccMouseMoved:) withObject:event];
314 if( swallows )
315 break;
316 }
317 }
318 }
319}
320
321- (void)mouseDragged:(NSEvent *)event
322{
323 if( dispatchEvents_ ) {
324 tListEntry *entry, *tmp;
325
326 DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
327 if ( entry->flags & kCCImplementsMouseDragged ) {
328 void *swallows = [entry->delegate performSelector:@selector(ccMouseDragged:) withObject:event];
329 if( swallows )
330 break;
331 }
332 }
333 }
334}
335
336- (void)mouseUp:(NSEvent *)event
337{
338 if( dispatchEvents_ ) {
339 tListEntry *entry, *tmp;
340
341 DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
342 if ( entry->flags & kCCImplementsMouseUp ) {
343 void *swallows = [entry->delegate performSelector:@selector(ccMouseUp:) withObject:event];
344 if( swallows )
345 break;
346 }
347 }
348 }
349}
350
351//
352// Mouse Right
353//
354- (void)rightMouseDown:(NSEvent *)event
355{
356 if( dispatchEvents_ ) {
357 tListEntry *entry, *tmp;
358
359 DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
360 if ( entry->flags & kCCImplementsRightMouseDown ) {
361 void *swallows = [entry->delegate performSelector:@selector(ccRightMouseDown:) withObject:event];
362 if( swallows )
363 break;
364 }
365 }
366 }
367}
368
369- (void)rightMouseDragged:(NSEvent *)event
370{
371 if( dispatchEvents_ ) {
372 tListEntry *entry, *tmp;
373
374 DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
375 if ( entry->flags & kCCImplementsRightMouseDragged ) {
376 void *swallows = [entry->delegate performSelector:@selector(ccRightMouseDragged:) withObject:event];
377 if( swallows )
378 break;
379 }
380 }
381 }
382}
383
384- (void)rightMouseUp:(NSEvent *)event
385{
386 if( dispatchEvents_ ) {
387 tListEntry *entry, *tmp;
388
389 DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
390 if ( entry->flags & kCCImplementsRightMouseUp ) {
391 void *swallows = [entry->delegate performSelector:@selector(ccRightMouseUp:) withObject:event];
392 if( swallows )
393 break;
394 }
395 }
396 }
397}
398
399//
400// Mouse Other
401//
402- (void)otherMouseDown:(NSEvent *)event
403{
404 if( dispatchEvents_ ) {
405 tListEntry *entry, *tmp;
406
407 DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
408 if ( entry->flags & kCCImplementsOtherMouseDown ) {
409 void *swallows = [entry->delegate performSelector:@selector(ccOtherMouseDown:) withObject:event];
410 if( swallows )
411 break;
412 }
413 }
414 }
415}
416
417- (void)otherMouseDragged:(NSEvent *)event
418{
419 if( dispatchEvents_ ) {
420 tListEntry *entry, *tmp;
421
422 DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
423 if ( entry->flags & kCCImplementsOtherMouseDragged ) {
424 void *swallows = [entry->delegate performSelector:@selector(ccOtherMouseDragged:) withObject:event];
425 if( swallows )
426 break;
427 }
428 }
429 }
430}
431
432- (void)otherMouseUp:(NSEvent *)event
433{
434 if( dispatchEvents_ ) {
435 tListEntry *entry, *tmp;
436
437 DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
438 if ( entry->flags & kCCImplementsOtherMouseUp ) {
439 void *swallows = [entry->delegate performSelector:@selector(ccOtherMouseUp:) withObject:event];
440 if( swallows )
441 break;
442 }
443 }
444 }
445}
446
447//
448// Scroll Wheel
449//
450- (void)scrollWheel:(NSEvent *)event
451{
452 if( dispatchEvents_ ) {
453 tListEntry *entry, *tmp;
454
455 DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
456 if ( entry->flags & kCCImplementsScrollWheel ) {
457 void *swallows = [entry->delegate performSelector:@selector(ccScrollWheel:) withObject:event];
458 if( swallows )
459 break;
460 }
461 }
462 }
463}
464
465//
466// Mouse enter / exit
467- (void)mouseExited:(NSEvent *)event
468{
469 if( dispatchEvents_ ) {
470 tListEntry *entry, *tmp;
471
472 DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
473 if ( entry->flags & kCCImplementsMouseEntered ) {
474 void *swallows = [entry->delegate performSelector:@selector(ccMouseEntered:) withObject:event];
475 if( swallows )
476 break;
477 }
478 }
479 }
480}
481
482- (void)mouseEntered:(NSEvent *)event
483{
484 if( dispatchEvents_ ) {
485 tListEntry *entry, *tmp;
486
487 DL_FOREACH_SAFE( mouseDelegates_, entry, tmp ) {
488 if ( entry->flags & kCCImplementsMouseExited) {
489 void *swallows = [entry->delegate performSelector:@selector(ccMouseExited:) withObject:event];
490 if( swallows )
491 break;
492 }
493 }
494 }
495}
496
497
498#pragma mark CCEventDispatcher - Keyboard events
499
500// Keyboard events
501- (void)keyDown:(NSEvent *)event
502{
503 if( dispatchEvents_ ) {
504 tListEntry *entry, *tmp;
505
506 DL_FOREACH_SAFE( keyboardDelegates_, entry, tmp ) {
507 if ( entry->flags & kCCImplementsKeyDown ) {
508 void *swallows = [entry->delegate performSelector:@selector(ccKeyDown:) withObject:event];
509 if( swallows )
510 break;
511 }
512 }
513 }
514}
515
516- (void)keyUp:(NSEvent *)event
517{
518 if( dispatchEvents_ ) {
519 tListEntry *entry, *tmp;
520
521 DL_FOREACH_SAFE( keyboardDelegates_, entry, tmp ) {
522 if ( entry->flags & kCCImplementsKeyUp ) {
523 void *swallows = [entry->delegate performSelector:@selector(ccKeyUp:) withObject:event];
524 if( swallows )
525 break;
526 }
527 }
528 }
529}
530
531- (void)flagsChanged:(NSEvent *)event
532{
533 if( dispatchEvents_ ) {
534 tListEntry *entry, *tmp;
535
536 DL_FOREACH_SAFE( keyboardDelegates_, entry, tmp ) {
537 if ( entry->flags & kCCImplementsFlagsChanged ) {
538 void *swallows = [entry->delegate performSelector:@selector(ccFlagsChanged:) withObject:event];
539 if( swallows )
540 break;
541 }
542 }
543 }
544}
545
546
547#pragma mark CCEventDispatcher - Touch events
548
549- (void)touchesBeganWithEvent:(NSEvent *)event
550{
551 if( dispatchEvents_ ) {
552 tListEntry *entry, *tmp;
553
554 DL_FOREACH_SAFE( touchDelegates_, entry, tmp ) {
555 if ( entry->flags & kCCImplementsTouchesBegan) {
556 void *swallows = [entry->delegate performSelector:@selector(ccTouchesBeganWithEvent:) withObject:event];
557 if( swallows )
558 break;
559 }
560 }
561 }
562}
563
564- (void)touchesMovedWithEvent:(NSEvent *)event
565{
566 if( dispatchEvents_ ) {
567 tListEntry *entry, *tmp;
568
569 DL_FOREACH_SAFE( touchDelegates_, entry, tmp ) {
570 if ( entry->flags & kCCImplementsTouchesMoved) {
571 void *swallows = [entry->delegate performSelector:@selector(ccTouchesMovedWithEvent:) withObject:event];
572 if( swallows )
573 break;
574 }
575 }
576 }
577}
578
579- (void)touchesEndedWithEvent:(NSEvent *)event
580{
581 if( dispatchEvents_ ) {
582 tListEntry *entry, *tmp;
583
584 DL_FOREACH_SAFE( touchDelegates_, entry, tmp ) {
585 if ( entry->flags & kCCImplementsTouchesEnded) {
586 void *swallows = [entry->delegate performSelector:@selector(ccTouchesEndedWithEvent:) withObject:event];
587 if( swallows )
588 break;
589 }
590 }
591 }
592}
593
594- (void)touchesCancelledWithEvent:(NSEvent *)event
595{
596 if( dispatchEvents_ ) {
597 tListEntry *entry, *tmp;
598
599 DL_FOREACH_SAFE( touchDelegates_, entry, tmp ) {
600 if ( entry->flags & kCCImplementsTouchesCancelled) {
601 void *swallows = [entry->delegate performSelector:@selector(ccTouchesCancelledWithEvent:) withObject:event];
602 if( swallows )
603 break;
604 }
605 }
606 }
607}
608
609
610#pragma mark CCEventDispatcher - queue events
611
612#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
613-(void) queueEvent:(NSEvent*)event selector:(SEL)selector
614{
615 NSAssert( eventQueueCount < QUEUE_EVENT_MAX, @"CCEventDispatcher: recompile. Increment QUEUE_EVENT_MAX value");
616
617 @synchronized (self) {
618 eventQueue[eventQueueCount].selector = selector;
619 eventQueue[eventQueueCount].event = [event copy];
620
621 eventQueueCount++;
622 }
623}
624
625-(void) dispatchQueuedEvents
626{
627 @synchronized (self) {
628 for( int i=0; i < eventQueueCount; i++ ) {
629 SEL sel = eventQueue[i].selector;
630 NSEvent *event = eventQueue[i].event;
631
632 [self performSelector:sel withObject:event];
633
634 [event release];
635 }
636
637 eventQueueCount = 0;
638 }
639}
640#endif // CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
641
642
643@end
644
645#endif // __MAC_OS_X_VERSION_MAX_ALLOWED
diff --git a/libs/cocos2d/Platforms/Mac/MacGLView.h b/libs/cocos2d/Platforms/Mac/MacGLView.h new file mode 100755 index 0000000..8099273 --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/MacGLView.h
@@ -0,0 +1,89 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26// Only compile this code on Mac. These files should not be included on your iOS project.
27// But in case they are included, it won't be compiled.
28#import <Availability.h>
29#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
30#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
31
32#import <Cocoa/Cocoa.h>
33
34#import "../../ccConfig.h"
35
36//PROTOCOLS:
37
38@protocol MacEventDelegate <NSObject>
39// Mouse
40- (void)mouseDown:(NSEvent *)theEvent;
41- (void)mouseUp:(NSEvent *)theEvent;
42- (void)mouseMoved:(NSEvent *)theEvent;
43- (void)mouseDragged:(NSEvent *)theEvent;
44- (void)rightMouseDown:(NSEvent*)event;
45- (void)rightMouseDragged:(NSEvent*)event;
46- (void)rightMouseUp:(NSEvent*)event;
47- (void)otherMouseDown:(NSEvent*)event;
48- (void)otherMouseDragged:(NSEvent*)event;
49- (void)otherMouseUp:(NSEvent*)event;
50- (void)scrollWheel:(NSEvent *)theEvent;
51- (void)mouseEntered:(NSEvent *)theEvent;
52- (void)mouseExited:(NSEvent *)theEvent;
53
54
55// Keyboard
56- (void)keyDown:(NSEvent *)theEvent;
57- (void)keyUp:(NSEvent *)theEvent;
58- (void)flagsChanged:(NSEvent *)theEvent;
59
60// Touches
61- (void)touchesBeganWithEvent:(NSEvent *)event;
62- (void)touchesMovedWithEvent:(NSEvent *)event;
63- (void)touchesEndedWithEvent:(NSEvent *)event;
64- (void)touchesCancelledWithEvent:(NSEvent *)event;
65
66#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
67- (void)queueEvent:(NSEvent*)event selector:(SEL)selector;
68#endif
69
70@end
71
72/** MacGLView
73
74 Only available for Mac OS X
75 */
76@interface MacGLView : NSOpenGLView {
77 id<MacEventDelegate> eventDelegate_;
78}
79
80@property (nonatomic, readwrite, assign) id<MacEventDelegate> eventDelegate;
81
82// initializes the MacGLView with a frame rect and an OpenGL context
83- (id) initWithFrame:(NSRect)frameRect shareContext:(NSOpenGLContext*)context;
84
85// private
86+(void) load_;
87@end
88
89#endif // __MAC_OS_X_VERSION_MAX_ALLOWED \ No newline at end of file
diff --git a/libs/cocos2d/Platforms/Mac/MacGLView.m b/libs/cocos2d/Platforms/Mac/MacGLView.m new file mode 100755 index 0000000..a041dc8 --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/MacGLView.m
@@ -0,0 +1,242 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
26/*
27 * Idea of subclassing NSOpenGLView was taken from "TextureUpload" Apple's sample
28 */
29
30// Only compile this code on Mac. These files should not be included on your iOS project.
31// But in case they are included, it won't be compiled.
32#import <Availability.h>
33#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
34#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
35
36#import "MacGLView.h"
37#import <OpenGL/gl.h>
38
39#import "CCDirectorMac.h"
40#import "../../ccConfig.h"
41
42
43@implementation MacGLView
44
45@synthesize eventDelegate = eventDelegate_;
46
47+(void) load_
48{
49 NSLog(@"%@ loaded", self);
50}
51
52- (id) initWithFrame:(NSRect)frameRect
53{
54 self = [self initWithFrame:frameRect shareContext:nil];
55 return self;
56}
57
58- (id) initWithFrame:(NSRect)frameRect shareContext:(NSOpenGLContext*)context
59{
60 NSOpenGLPixelFormatAttribute attribs[] =
61 {
62 NSOpenGLPFAAccelerated,
63 NSOpenGLPFANoRecovery,
64 NSOpenGLPFADoubleBuffer,
65 NSOpenGLPFADepthSize, 24,
66
67 0
68 };
69
70 NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs];
71
72 if (!pixelFormat)
73 NSLog(@"No OpenGL pixel format");
74
75 if( (self = [super initWithFrame:frameRect pixelFormat:[pixelFormat autorelease]]) ) {
76
77 if( context )
78 [self setOpenGLContext:context];
79
80 // Synchronize buffer swaps with vertical refresh rate
81 GLint swapInt = 1;
82 [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
83
84// GLint order = -1;
85// [[self openGLContext] setValues:&order forParameter:NSOpenGLCPSurfaceOrder];
86
87 // event delegate
88 eventDelegate_ = nil;
89 }
90
91 return self;
92}
93
94- (void) reshape
95{
96 // We draw on a secondary thread through the display link
97 // When resizing the view, -reshape is called automatically on the main thread
98 // Add a mutex around to avoid the threads accessing the context simultaneously when resizing
99 CGLLockContext([[self openGLContext] CGLContextObj]);
100
101 NSRect rect = [self bounds];
102
103 CCDirector *director = [CCDirector sharedDirector];
104 [director reshapeProjection: NSSizeToCGSize(rect.size) ];
105
106 // avoid flicker
107 [director drawScene];
108// [self setNeedsDisplay:YES];
109
110 CGLUnlockContext([[self openGLContext] CGLContextObj]);
111}
112
113- (void) dealloc
114{
115
116 [super dealloc];
117}
118
119#if CC_DIRECTOR_MAC_USE_DISPLAY_LINK_THREAD
120#define DISPATCH_EVENT(__event__, __selector__) [eventDelegate_ queueEvent:__event__ selector:__selector__];
121#else
122#define DISPATCH_EVENT(__event__, __selector__) \
123 id obj = eventDelegate_; \
124 [obj performSelector:__selector__ \
125 onThread:[(CCDirectorMac*)[CCDirector sharedDirector] runningThread] \
126 withObject:__event__ \
127 waitUntilDone:NO];
128#endif
129
130#pragma mark MacGLView - Mouse events
131- (void)mouseDown:(NSEvent *)theEvent
132{
133 DISPATCH_EVENT(theEvent, _cmd);
134}
135
136- (void)mouseMoved:(NSEvent *)theEvent
137{
138 DISPATCH_EVENT(theEvent, _cmd);
139}
140
141- (void)mouseDragged:(NSEvent *)theEvent
142{
143 DISPATCH_EVENT(theEvent, _cmd);
144}
145
146- (void)mouseUp:(NSEvent *)theEvent
147{
148 DISPATCH_EVENT(theEvent, _cmd);
149}
150
151- (void)rightMouseDown:(NSEvent *)theEvent {
152 DISPATCH_EVENT(theEvent, _cmd);
153}
154
155- (void)rightMouseDragged:(NSEvent *)theEvent {
156 DISPATCH_EVENT(theEvent, _cmd);
157}
158
159- (void)rightMouseUp:(NSEvent *)theEvent {
160 DISPATCH_EVENT(theEvent, _cmd);
161}
162
163- (void)otherMouseDown:(NSEvent *)theEvent {
164 DISPATCH_EVENT(theEvent, _cmd);
165}
166
167- (void)otherMouseDragged:(NSEvent *)theEvent {
168 DISPATCH_EVENT(theEvent, _cmd);
169}
170
171- (void)otherMouseUp:(NSEvent *)theEvent {
172 DISPATCH_EVENT(theEvent, _cmd);
173}
174
175- (void)mouseEntered:(NSEvent *)theEvent {
176 DISPATCH_EVENT(theEvent, _cmd);
177}
178
179- (void)mouseExited:(NSEvent *)theEvent {
180 DISPATCH_EVENT(theEvent, _cmd);
181}
182
183-(void) scrollWheel:(NSEvent *)theEvent {
184 DISPATCH_EVENT(theEvent, _cmd);
185}
186
187#pragma mark MacGLView - Key events
188
189-(BOOL) becomeFirstResponder
190{
191 return YES;
192}
193
194-(BOOL) acceptsFirstResponder
195{
196 return YES;
197}
198
199-(BOOL) resignFirstResponder
200{
201 return YES;
202}
203
204- (void)keyDown:(NSEvent *)theEvent
205{
206 DISPATCH_EVENT(theEvent, _cmd);
207}
208
209- (void)keyUp:(NSEvent *)theEvent
210{
211 DISPATCH_EVENT(theEvent, _cmd);
212}
213
214- (void)flagsChanged:(NSEvent *)theEvent
215{
216 DISPATCH_EVENT(theEvent, _cmd);
217}
218
219#pragma mark MacGLView - Touch events
220- (void)touchesBeganWithEvent:(NSEvent *)theEvent
221{
222 DISPATCH_EVENT(theEvent, _cmd);
223}
224
225- (void)touchesMovedWithEvent:(NSEvent *)theEvent
226{
227 DISPATCH_EVENT(theEvent, _cmd);
228}
229
230- (void)touchesEndedWithEvent:(NSEvent *)theEvent
231{
232 DISPATCH_EVENT(theEvent, _cmd);
233}
234
235- (void)touchesCancelledWithEvent:(NSEvent *)theEvent
236{
237 DISPATCH_EVENT(theEvent, _cmd);
238}
239
240@end
241
242#endif // __MAC_OS_X_VERSION_MAX_ALLOWED
diff --git a/libs/cocos2d/Platforms/Mac/MacWindow.h b/libs/cocos2d/Platforms/Mac/MacWindow.h new file mode 100755 index 0000000..716fe9b --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/MacWindow.h
@@ -0,0 +1,42 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2010 Ricardo Quesada
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25// Only compile this code on Mac. These files should not be included on your iOS project.
26// But in case they are included, it won't be compiled.
27#import <Availability.h>
28#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
29#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
30
31#import <Cocoa/Cocoa.h>
32
33
34@interface MacWindow : NSWindow
35{
36}
37- (id) initWithFrame:(NSRect)frame fullscreen:(BOOL)fullscreen;
38
39@end
40
41
42#endif // __MAC_OS_X_VERSION_MAX_ALLOWED \ No newline at end of file
diff --git a/libs/cocos2d/Platforms/Mac/MacWindow.m b/libs/cocos2d/Platforms/Mac/MacWindow.m new file mode 100755 index 0000000..28736a3 --- /dev/null +++ b/libs/cocos2d/Platforms/Mac/MacWindow.m
@@ -0,0 +1,70 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2010 Ricardo Quesada
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25// Only compile this code on Mac. These files should not be included on your iOS project.
26// But in case they are included, it won't be compiled.
27#import <Availability.h>
28#ifdef __IPHONE_OS_VERSION_MAX_ALLOWED
29#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
30
31#import "MacWindow.h"
32
33
34@implementation MacWindow
35
36- (id) initWithFrame:(NSRect)frame fullscreen:(BOOL)fullscreen
37{
38 int styleMask = fullscreen ? NSBackingStoreBuffered : ( NSTitledWindowMask | NSClosableWindowMask );
39 self = [self initWithContentRect:frame
40 styleMask:styleMask
41 backing:NSBackingStoreBuffered
42 defer:YES];
43
44 if (self != nil)
45 {
46 if(fullscreen)
47 {
48 [self setLevel:NSMainMenuWindowLevel+1];
49 [self setHidesOnDeactivate:YES];
50 [self setHasShadow:NO];
51 }
52
53 [self setAcceptsMouseMovedEvents:NO];
54 [self setOpaque:YES];
55 }
56 return self;
57}
58
59- (BOOL) canBecomeKeyWindow
60{
61 return YES;
62}
63
64- (BOOL) canBecomeMainWindow
65{
66 return YES;
67}
68@end
69
70#endif // __MAC_OS_X_VERSION_MAX_ALLOWED