]> git.cworth.org Git - apitrace/blob - glws_cocoa.mm
Use Cocoa on Mac OS X.
[apitrace] / glws_cocoa.mm
1 /**************************************************************************
2  *
3  * Copyright 2011 Jose Fonseca
4  * All Rights Reserved.
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
26 #include <stdlib.h>
27 #include <iostream>
28
29 #include <Cocoa/Cocoa.h>
30
31 #include "glws.hpp"
32
33
34 namespace glws {
35
36
37 NSAutoreleasePool *autoreleasePool = nil;
38
39
40 class CocoaVisual : public Visual
41 {
42 public:
43     NSOpenGLPixelFormat *pixelFormat;
44
45     CocoaVisual(NSOpenGLPixelFormat *pf) :
46         pixelFormat(pf)
47     {}
48
49     ~CocoaVisual() {
50         [pixelFormat release];
51     }
52 };
53  
54
55 class CocoaDrawable : public Drawable
56 {
57 public:
58     NSWindow *window;
59     NSOpenGLContext *currentContext;
60
61     CocoaDrawable(const Visual *vis, int w, int h) :
62         Drawable(vis, w, h),
63         currentContext(nil)
64     {
65         NSOpenGLPixelFormat *pixelFormat = dynamic_cast<const CocoaVisual *>(visual)->pixelFormat;
66
67         NSRect winRect = NSMakeRect(0, 0, w, h);
68
69         window = [[NSWindow alloc]
70                          initWithContentRect:winRect
71                                    styleMask:NSTitledWindowMask |
72                                              NSClosableWindowMask |
73                                              NSMiniaturizableWindowMask
74                                      backing:NSBackingStoreRetained
75                                        defer:NO];
76         assert(window != nil);
77
78         NSOpenGLView *view = [[NSOpenGLView alloc]
79                               initWithFrame:winRect
80                                 pixelFormat:pixelFormat];
81         assert(view != nil);
82
83         [window setContentView:view];
84         [window setTitle:@"glretrace"];
85
86     }
87
88     ~CocoaDrawable() {
89         [window release];
90     }
91
92     void
93     resize(int w, int h) {
94         Drawable::resize(w, h);
95
96         [window setContentSize:NSMakeSize(w, h)];
97
98         if (currentContext != nil) {
99             [currentContext update];
100             [window makeKeyAndOrderFront:nil];
101             [currentContext setView:[window contentView]];
102             [currentContext makeCurrentContext];
103         }
104     }
105
106     void show(void) {
107         if (!visible) {
108             // TODO
109             Drawable::show();
110         }
111     }
112
113     void swapBuffers(void) {
114         if (currentContext != nil) {
115             [currentContext flushBuffer];
116         }
117     }
118 };
119
120
121 class CocoaContext : public Context
122 {
123 public:
124     NSOpenGLContext *context;
125
126     CocoaContext(const Visual *vis, NSOpenGLContext *ctx) :
127         Context(vis),
128         context(ctx)
129     {}
130
131     ~CocoaContext() {
132         [context release];
133     }
134 };
135
136
137 void
138 init(void) {
139     [NSApplication sharedApplication];
140
141     autoreleasePool = [[NSAutoreleasePool alloc] init];
142
143     [NSApp finishLaunching];
144 }
145
146
147 void
148 cleanup(void) {
149     [autoreleasePool release];
150 }
151
152
153 Visual *
154 createVisual(bool doubleBuffer) {
155     NSOpenGLPixelFormatAttribute single_attribs[] = {
156         NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)1,
157         NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)24,
158         NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)1,
159         NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)1,
160         (NSOpenGLPixelFormatAttribute)0
161     };
162
163     NSOpenGLPixelFormatAttribute double_attribs[] = {
164         NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)1,
165         NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)24,
166         NSOpenGLPFADoubleBuffer,
167         NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)1,
168         NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)1,
169         (NSOpenGLPixelFormatAttribute)0
170     };
171
172     NSOpenGLPixelFormatAttribute *attribs = doubleBuffer ? double_attribs : single_attribs;
173
174     NSOpenGLPixelFormat *pixelFormat = [[NSOpenGLPixelFormat alloc]
175                                      initWithAttributes:attribs];
176
177     return new CocoaVisual(pixelFormat);
178 }
179
180 Drawable *
181 createDrawable(const Visual *visual, int width, int height)
182 {
183     return new CocoaDrawable(visual, width, height);
184 }
185
186 Context *
187 createContext(const Visual *visual, Context *shareContext)
188 {
189     NSOpenGLPixelFormat *pixelFormat = dynamic_cast<const CocoaVisual *>(visual)->pixelFormat;
190     NSOpenGLContext *share_context = nil;
191     NSOpenGLContext *context;
192
193     if (shareContext) {
194         share_context = dynamic_cast<CocoaContext*>(shareContext)->context;
195     }
196
197     context = [[NSOpenGLContext alloc]
198                initWithFormat:pixelFormat
199                shareContext:share_context];
200     assert(context != nil);
201
202     return new CocoaContext(visual, context);
203 }
204
205 bool
206 makeCurrent(Drawable *drawable, Context *context)
207 {
208     if (!drawable || !context) {
209         [NSOpenGLContext clearCurrentContext];
210     } else {
211         CocoaDrawable *cocoaDrawable = dynamic_cast<CocoaDrawable *>(drawable);
212         CocoaContext *cocoaContext = dynamic_cast<CocoaContext *>(context);
213
214         [cocoaDrawable->window makeKeyAndOrderFront:nil];
215         [cocoaContext->context setView:[cocoaDrawable->window contentView]];
216         [cocoaContext->context makeCurrentContext];
217
218         cocoaDrawable->currentContext = cocoaContext->context;
219     }
220
221     return TRUE;
222 }
223
224 bool
225 processEvents(void) {
226    NSEvent* event;
227
228     do {
229         event = [NSApp nextEventMatchingMask:NSAnyEventMask
230                                    untilDate:[NSDate distantPast]
231                                       inMode:NSDefaultRunLoopMode
232                                      dequeue:YES];
233         if (event)
234             [NSApp sendEvent:event];
235     } while (event);
236
237     return true;
238 }
239
240
241 } /* namespace glws */