MacOpenGLWindowObjC.m 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252
  1. #ifndef B3_USE_GLFW
  2. #define __OBJC2__ 1
  3. #include <Foundation/NSExtensionContext.h>
  4. #include "MacOpenGLWindowObjC.h"
  5. #define GL_DO_NOT_WARN_IF_MULTI_GL_VERSION_HEADERS_INCLUDED
  6. #import <Cocoa/Cocoa.h>
  7. #include "OpenGLInclude.h"
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <stddef.h>
  11. #include <string.h>
  12. #include <Availability.h>
  13. //aargh, Mac OSX 10.12 broke backwards compatibility, fix it here for now
  14. #ifdef __MAC_10_12
  15. #define MyNSTitledWindowMask NSWindowStyleMaskTitled
  16. #define MyNSResizableWindowMask NSWindowStyleMaskResizable
  17. #define MyNSClosableWindowMask NSWindowStyleMaskClosable
  18. #define MyNSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable
  19. #define MyNSAnyEventMask NSEventMaskAny
  20. #define MyNSEventTypeFlagsChanged NSEventTypeFlagsChanged
  21. #define MyNSEventModifierFlagShift NSEventModifierFlagShift
  22. #define MyNSEventModifierFlagControl NSEventModifierFlagControl
  23. #define MyNSEventModifierFlagOption NSEventModifierFlagOption
  24. #define MyNSKeyUp NSEventTypeKeyUp
  25. #define MyNSKeyDown NSEventTypeKeyDown
  26. #define MyNSRightMouseDown NSEventTypeRightMouseDown
  27. #define MyNSLeftMouseDown NSEventTypeLeftMouseDown
  28. #define MyNSOtherMouseDown NSEventTypeOtherMouseDown
  29. #define MyNSRightMouseUp NSEventTypeRightMouseUp
  30. #define MyNSLeftMouseUp NSEventTypeLeftMouseUp
  31. #define MyNSOtherMouseUp NSEventTypeOtherMouseUp
  32. #define MyNSMouseMoved NSEventTypeMouseMoved
  33. #define MyNSLeftMouseDragged NSEventTypeLeftMouseDragged
  34. #define MyNSRightMouseDragged NSEventTypeRightMouseDragged
  35. #define MyNSOtherMouseDragged NSEventTypeOtherMouseDragged
  36. #define MyNSScrollWheel NSEventTypeScrollWheel
  37. #else
  38. #define MyNSTitledWindowMask NSTitledWindowMask
  39. #define MyNSResizableWindowMask NSResizableWindowMask
  40. #define MyNSClosableWindowMask NSClosableWindowMask
  41. #define MyNSMiniaturizableWindowMask NSMiniaturizableWindowMask
  42. #define MyNSAnyEventMask NSAnyEventMask
  43. #define MyNSEventTypeFlagsChanged NSFlagsChanged
  44. #define MyNSEventModifierFlagShift NSShiftKeyMask
  45. #define MyNSEventModifierFlagControl NSControlKeyMask
  46. #define MyNSEventModifierFlagOption NSAlternateKeyMask
  47. #define MyNSKeyUp NSKeyUp
  48. #define MyNSKeyDown NSKeyDown
  49. #define MyNSRightMouseDown NSRightMouseDown
  50. #define MyNSLeftMouseDown NSLeftMouseDown
  51. #define MyNSOtherMouseDown NSOtherMouseDown
  52. #define MyNSLeftMouseUp NSLeftMouseUp
  53. #define MyNSRightMouseUp NSRightMouseUp
  54. #define MyNSOtherMouseUp NSOtherMouseUp
  55. #define MyNSMouseMoved NSMouseMoved
  56. #define MyNSLeftMouseDragged NSLeftMouseDragged
  57. #define MyNSRightMouseDragged NSRightMouseDragged
  58. #define MyNSOtherMouseDragged NSOtherMouseDragged
  59. #define MyNSScrollWheel NSScrollWheel
  60. #endif
  61. /* report GL errors, if any, to stderr */
  62. static void checkError(const char *functionName)
  63. {
  64. GLenum error;
  65. while (( error = glGetError() ) != GL_NO_ERROR)
  66. {
  67. fprintf (stderr, "GL error 0x%X detected in %s\n", error, functionName);
  68. }
  69. }
  70. void dumpInfo(void)
  71. {
  72. printf ("Vendor: %s\n", glGetString (GL_VENDOR));
  73. printf ("Renderer: %s\n", glGetString (GL_RENDERER));
  74. printf ("Version: %s\n", glGetString (GL_VERSION));
  75. printf ("GLSL: %s\n", glGetString (GL_SHADING_LANGUAGE_VERSION));
  76. checkError ("dumpInfo");
  77. }
  78. // -------------------- View ------------------------
  79. @interface TestView : NSView
  80. {
  81. NSOpenGLContext* m_context;
  82. int m_lastWidth;
  83. int m_lastHeight;
  84. bool m_requestClose;
  85. b3ResizeCallback m_resizeCallback;
  86. }
  87. -(void)drawRect:(NSRect)rect;
  88. -(void) MakeContext:(int) openglVersion;
  89. -(void) MakeCurrent;
  90. -(float) GetWindowWidth;
  91. -(float) GetWindowHeight;
  92. -(BOOL) GetRequestClose;
  93. - (BOOL)windowShouldClose:(id)sender;
  94. -(void) setResizeCallback:(b3ResizeCallback) callback;
  95. -(b3ResizeCallback) getResizeCallback;
  96. -(NSOpenGLContext*) getContext;
  97. @end
  98. @implementation TestView
  99. - (BOOL)windowShouldClose:(id)sender
  100. {
  101. m_requestClose = true;
  102. return false;
  103. }
  104. -(BOOL) GetRequestClose
  105. {
  106. return m_requestClose;
  107. }
  108. -(float) GetWindowWidth
  109. {
  110. return m_lastWidth;
  111. }
  112. -(float) GetWindowHeight
  113. {
  114. return m_lastHeight;
  115. }
  116. -(b3ResizeCallback) getResizeCallback
  117. {
  118. return m_resizeCallback;
  119. }
  120. -(NSOpenGLContext*) getContext
  121. {
  122. return m_context;
  123. }
  124. -(void)setResizeCallback:(b3ResizeCallback)callback
  125. {
  126. m_resizeCallback = callback;
  127. }
  128. -(void)drawRect:(NSRect)rect
  129. {
  130. if (([self frame].size.width != m_lastWidth) || ([self frame].size.height != m_lastHeight))
  131. {
  132. m_lastWidth = [self frame].size.width;
  133. m_lastHeight = [self frame].size.height;
  134. // Only needed on resize:
  135. [m_context clearDrawable];
  136. // reshape([self frame].size.width, [self frame].size.height);
  137. float width = [self frame].size.width;
  138. float height = [self frame].size.height;
  139. // Get view dimensions in pixels
  140. // glViewport(0,0,10,10);
  141. if (m_resizeCallback)
  142. {
  143. (*m_resizeCallback)(width,height);
  144. #ifndef NO_OPENGL3
  145. NSRect backingBounds = [self convertRectToBacking:[self bounds]];
  146. GLsizei backingPixelWidth = (GLsizei)(backingBounds.size.width),
  147. backingPixelHeight = (GLsizei)(backingBounds.size.height);
  148. // Set viewport
  149. glViewport(0, 0, backingPixelWidth, backingPixelHeight);
  150. #else
  151. glViewport(0,0,(GLsizei)width,(GLsizei)height);
  152. #endif
  153. }
  154. }
  155. [m_context setView: self];
  156. [m_context makeCurrentContext];
  157. [m_context update];
  158. // Draw
  159. //display();
  160. [m_context flushBuffer];
  161. [NSOpenGLContext clearCurrentContext];
  162. }
  163. -(void) MakeContext :(int) openglVersion
  164. {
  165. // NSWindow *w;
  166. NSOpenGLPixelFormat *fmt;
  167. m_requestClose = false;
  168. #ifndef NO_OPENGL3
  169. if (openglVersion==3)
  170. {
  171. NSOpenGLPixelFormatAttribute attrs[] =
  172. {
  173. NSOpenGLPFAOpenGLProfile,
  174. NSOpenGLProfileVersion3_2Core,
  175. NSOpenGLPFADoubleBuffer,
  176. NSOpenGLPFADepthSize, 32,
  177. NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)8,
  178. (NSOpenGLPixelFormatAttribute)0
  179. };
  180. // Init GL context
  181. fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: (NSOpenGLPixelFormatAttribute*)attrs];
  182. } else
  183. #endif
  184. {
  185. NSOpenGLPixelFormatAttribute attrs[] =
  186. {
  187. NSOpenGLPFADoubleBuffer,
  188. NSOpenGLPFADepthSize, 32,
  189. NSOpenGLPFAStencilSize, (NSOpenGLPixelFormatAttribute)8,
  190. (NSOpenGLPixelFormatAttribute)0
  191. };
  192. // Init GL context
  193. fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: (NSOpenGLPixelFormatAttribute*)attrs];
  194. }
  195. m_context = [[NSOpenGLContext alloc] initWithFormat: fmt shareContext: nil];
  196. [fmt release];
  197. [m_context makeCurrentContext];
  198. [m_context update];
  199. //checkError("makeCurrentContext");
  200. }
  201. -(void) MakeCurrent
  202. {
  203. [m_context makeCurrentContext];
  204. [m_context update];
  205. }
  206. -(void)windowWillClose:(NSNotification *)note
  207. {
  208. [[NSApplication sharedApplication] terminate:self];
  209. }
  210. @end
  211. struct MacOpenGLWindowInternalData
  212. {
  213. NSApplication* m_myApp;
  214. TestView* m_myview;
  215. NSAutoreleasePool* m_pool;
  216. NSWindow* m_window;
  217. bool m_exitRequested;
  218. float m_mouseX;
  219. float m_mouseY;
  220. int m_modifierFlags;
  221. b3MouseButtonCallback m_mouseButtonCallback;
  222. b3MouseMoveCallback m_mouseMoveCallback;
  223. b3WheelCallback m_wheelCallback;
  224. b3KeyboardCallback m_keyboardCallback;
  225. b3RenderCallback m_renderCallback;
  226. float m_retinaScaleFactor;
  227. bool m_allowRetina;
  228. };
  229. struct MacOpenGLWindowInternalData* Mac_createData()
  230. {
  231. struct MacOpenGLWindowInternalData* data = malloc(sizeof(struct MacOpenGLWindowInternalData));
  232. data->m_myApp = 0;
  233. data->m_myview = 0;
  234. data->m_pool = 0;
  235. data->m_window = 0;
  236. data->m_exitRequested = false;
  237. data->m_mouseX=-1;
  238. data->m_mouseY=-1;
  239. data->m_modifierFlags = 0;
  240. data->m_mouseButtonCallback = 0;
  241. data->m_mouseMoveCallback = 0;;
  242. data->m_wheelCallback =0;
  243. data->m_keyboardCallback =0;
  244. data->m_renderCallback=0;
  245. data->m_allowRetina = true;
  246. data->m_retinaScaleFactor = 1;
  247. return data;
  248. }
  249. void Mac_destroyData(struct MacOpenGLWindowInternalData* data)
  250. {
  251. free(data);
  252. }
  253. void Mac_setWindowTitle(struct MacOpenGLWindowInternalData* data, const char* windowTitle)
  254. {
  255. [data->m_window setTitle:[NSString stringWithCString:windowTitle encoding:NSISOLatin1StringEncoding]] ;
  256. }
  257. int Mac_createWindow(struct MacOpenGLWindowInternalData* m_internalData,struct MacWindowConstructionInfo* ci)
  258. {
  259. const char* windowTitle = ci->m_title;
  260. m_internalData->m_allowRetina = (ci->m_allowRetina!=0);
  261. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  262. m_internalData->m_pool = [NSAutoreleasePool new];
  263. m_internalData->m_myApp = [NSApplication sharedApplication];
  264. //myApp = [MyApp sharedApplication];
  265. //home();
  266. [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
  267. id menubar = [[NSMenu new] autorelease];
  268. id appMenuItem = [[NSMenuItem new] autorelease];
  269. [menubar addItem:appMenuItem];
  270. [NSApp setMainMenu:menubar];
  271. id appMenu = [[NSMenu new] autorelease];
  272. id appName = [[NSProcessInfo processInfo] processName];
  273. id quitTitle = [@"Quit " stringByAppendingString:appName];
  274. id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle
  275. action:@selector(terminate:) keyEquivalent:@"q"] autorelease];
  276. [appMenu addItem:quitMenuItem];
  277. [appMenuItem setSubmenu:appMenu];
  278. NSMenuItem *fileMenuItem = [[NSMenuItem new] autorelease];
  279. NSMenu *fileMenu = [[NSMenu alloc] initWithTitle:@"File"];
  280. [fileMenuItem setSubmenu: fileMenu]; // was setMenu:
  281. NSMenuItem *newMenu = [[NSMenuItem alloc] initWithTitle:@"New" action:NULL keyEquivalent:@""];
  282. NSMenuItem *openMenu = [[NSMenuItem alloc] initWithTitle:@"Open" action:NULL keyEquivalent:@""];
  283. NSMenuItem *saveMenu = [[NSMenuItem alloc] initWithTitle:@"Save" action:NULL keyEquivalent:@""];
  284. [fileMenu addItem: newMenu];
  285. [fileMenu addItem: openMenu];
  286. [fileMenu addItem: saveMenu];
  287. [menubar addItem: fileMenuItem];
  288. // add Edit menu
  289. NSMenuItem *editMenuItem = [[NSMenuItem new] autorelease];
  290. NSMenu *menu = [[NSMenu alloc]initWithTitle:@"Edit"];
  291. [editMenuItem setSubmenu: menu];
  292. NSMenuItem *copyItem = [[NSMenuItem alloc]initWithTitle:@"Copy" action:@selector(copy:) keyEquivalent:@"c"];
  293. [menu addItem:copyItem];
  294. [menubar addItem:editMenuItem];
  295. // [mainMenu setSubmenu:menu forItem:menuItem];
  296. //NSMenuItem *fileMenuItem = [[NSMenuItem alloc] initWithTitle: @"File"];
  297. /*[fileMenuItem setSubmenu: fileMenu]; // was setMenu:
  298. [fileMenuItem release];
  299. */
  300. /*NSMenu *newMenu;
  301. NSMenuItem *newItem;
  302. // Add the submenu
  303. newItem = [[NSMenuItem allocWithZone:[NSMenu menuZone]]
  304. initWithTitle:@"Flashy" action:NULL keyEquivalent:@""];
  305. newMenu = [[NSMenu allocWithZone:[NSMenu menuZone]]
  306. initWithTitle:@"Flashy"];
  307. [newItem setSubmenu:newMenu];
  308. [newMenu release];
  309. [[NSApp mainMenu] addItem:newItem];
  310. [newItem release];
  311. */
  312. NSRect frame = NSMakeRect(0., 0., ci->m_width, ci->m_height);
  313. m_internalData->m_window = [NSWindow alloc];
  314. [m_internalData->m_window initWithContentRect:frame
  315. styleMask:MyNSTitledWindowMask |MyNSResizableWindowMask| MyNSClosableWindowMask | MyNSMiniaturizableWindowMask
  316. backing:NSBackingStoreBuffered
  317. defer:false];
  318. [m_internalData->m_window setTitle:[NSString stringWithCString:windowTitle encoding:NSISOLatin1StringEncoding]] ;
  319. m_internalData->m_myview = [TestView alloc];
  320. [m_internalData->m_myview setResizeCallback:0];
  321. ///ci.m_resizeCallback];
  322. [m_internalData->m_myview initWithFrame: frame];
  323. // OpenGL init!
  324. [m_internalData->m_myview MakeContext : ci->m_openglVersion];
  325. [m_internalData->m_myview drawRect: frame];
  326. // https://developer.apple.com/library/mac/#documentation/GraphicsAnimation/Conceptual/HighResolutionOSX/CapturingScreenContents/CapturingScreenContents.html#//apple_ref/doc/uid/TP40012302-CH10-SW1
  327. //support HighResolutionOSX for Retina Macbook
  328. if (ci->m_openglVersion>=3)
  329. {
  330. if (m_internalData->m_allowRetina)
  331. {
  332. [m_internalData->m_myview setWantsBestResolutionOpenGLSurface:YES];
  333. }
  334. }
  335. NSSize sz;
  336. sz.width = 1;
  337. sz.height = 1;
  338. // float newBackingScaleFactor = [m_internalData->m_window backingScaleFactor];
  339. //dumpInfo();
  340. [m_internalData->m_window setContentView: m_internalData->m_myview];
  341. [m_internalData->m_window setDelegate:(id) m_internalData->m_myview];
  342. [m_internalData->m_window makeKeyAndOrderFront: nil];
  343. [m_internalData->m_myview MakeCurrent];
  344. [NSApp activateIgnoringOtherApps:YES];
  345. //[m_internalData->m_window setLevel:NSMainMenuWindowLevel];
  346. // [NSEvent addGlobalMonitorForEventsMatchingMask:NSMouseMovedMask];
  347. // [NSEvent addGlobalMonitorForEventsMatchingMask:NSMouseMovedMask handler:^(NSEvent *event)
  348. // {
  349. //[window setFrameOrigin:[NSEvent mouseLocation]];
  350. // NSPoint eventLocation = [m_internalData->m_window mouseLocationOutsideOfEventStream];
  351. // NSPoint eventLocation = [event locationInWindow];
  352. //NSPoint center = [m_internalData->m_myview convertPoint:eventLocation fromView:nil];
  353. // m_mouseX = center.x;
  354. // m_mouseY = [m_internalData->m_myview GetWindowHeight] - center.y;
  355. // printf("mouse coord = %f, %f\n",m_mouseX,m_mouseY);
  356. // if (m_mouseMoveCallback)
  357. // (*m_mouseMoveCallback)(m_mouseX,m_mouseY);
  358. // }];
  359. //see http://stackoverflow.com/questions/8238473/cant-get-nsmousemoved-events-from-nexteventmatchingmask-with-an-nsopenglview
  360. /* ProcessSerialNumber psn;
  361. GetCurrentProcess(&psn);
  362. TransformProcessType(&psn, kProcessTransformToForegroundApplication);
  363. SetFrontProcess(&psn);
  364. */
  365. #ifndef NO_OPENGL3
  366. m_internalData->m_retinaScaleFactor = [m_internalData->m_myview convertSizeToBacking:sz].width;
  367. #else
  368. m_internalData->m_retinaScaleFactor=1.f;
  369. #endif
  370. GLint sync = 0;
  371. CGLContextObj ctx = CGLGetCurrentContext();
  372. CGLSetParameter(ctx, kCGLCPSwapInterval, &sync);
  373. [m_internalData->m_myApp finishLaunching];
  374. [pool release];
  375. if(!gladLoaderLoadGL()) {
  376. printf("gladLoaderLoadGL failed!\n");
  377. exit(-1);
  378. }
  379. return 0;
  380. }
  381. /*
  382. * Summary:
  383. * Virtual keycodes
  384. *
  385. * Discussion:
  386. * These constants are the virtual keycodes defined originally in
  387. * Inside Mac Volume V, pg. V-191. They identify physical keys on a
  388. * keyboard. Those constants with "ANSI" in the name are labeled
  389. * according to the key position on an ANSI-standard US keyboard.
  390. * For example, kVK_ANSI_A indicates the virtual keycode for the key
  391. * with the letter 'A' in the US keyboard layout. Other keyboard
  392. * layouts may have the 'A' key label on a different physical key;
  393. * in this case, pressing 'A' will generate a different virtual
  394. * keycode.
  395. */
  396. enum {
  397. kVK_ANSI_A = 0x00,
  398. kVK_ANSI_S = 0x01,
  399. kVK_ANSI_D = 0x02,
  400. kVK_ANSI_F = 0x03,
  401. kVK_ANSI_H = 0x04,
  402. kVK_ANSI_G = 0x05,
  403. kVK_ANSI_Z = 0x06,
  404. kVK_ANSI_X = 0x07,
  405. kVK_ANSI_C = 0x08,
  406. kVK_ANSI_V = 0x09,
  407. kVK_ANSI_B = 0x0B,
  408. kVK_ANSI_Q = 0x0C,
  409. kVK_ANSI_W = 0x0D,
  410. kVK_ANSI_E = 0x0E,
  411. kVK_ANSI_R = 0x0F,
  412. kVK_ANSI_Y = 0x10,
  413. kVK_ANSI_T = 0x11,
  414. kVK_ANSI_1 = 0x12,
  415. kVK_ANSI_2 = 0x13,
  416. kVK_ANSI_3 = 0x14,
  417. kVK_ANSI_4 = 0x15,
  418. kVK_ANSI_6 = 0x16,
  419. kVK_ANSI_5 = 0x17,
  420. kVK_ANSI_Equal = 0x18,
  421. kVK_ANSI_9 = 0x19,
  422. kVK_ANSI_7 = 0x1A,
  423. kVK_ANSI_Minus = 0x1B,
  424. kVK_ANSI_8 = 0x1C,
  425. kVK_ANSI_0 = 0x1D,
  426. kVK_ANSI_RightBracket = 0x1E,
  427. kVK_ANSI_O = 0x1F,
  428. kVK_ANSI_U = 0x20,
  429. kVK_ANSI_LeftBracket = 0x21,
  430. kVK_ANSI_I = 0x22,
  431. kVK_ANSI_P = 0x23,
  432. kVK_ANSI_L = 0x25,
  433. kVK_ANSI_J = 0x26,
  434. kVK_ANSI_Quote = 0x27,
  435. kVK_ANSI_K = 0x28,
  436. kVK_ANSI_Semicolon = 0x29,
  437. kVK_ANSI_Backslash = 0x2A,
  438. kVK_ANSI_Comma = 0x2B,
  439. kVK_ANSI_Slash = 0x2C,
  440. kVK_ANSI_N = 0x2D,
  441. kVK_ANSI_M = 0x2E,
  442. kVK_ANSI_Period = 0x2F,
  443. kVK_ANSI_Grave = 0x32,
  444. kVK_ANSI_KeypadDecimal = 0x41,
  445. kVK_ANSI_KeypadMultiply = 0x43,
  446. kVK_ANSI_KeypadPlus = 0x45,
  447. kVK_ANSI_KeypadClear = 0x47,
  448. kVK_ANSI_KeypadDivide = 0x4B,
  449. kVK_ANSI_KeypadEnter = 0x4C,
  450. kVK_ANSI_KeypadMinus = 0x4E,
  451. kVK_ANSI_KeypadEquals = 0x51,
  452. kVK_ANSI_Keypad0 = 0x52,
  453. kVK_ANSI_Keypad1 = 0x53,
  454. kVK_ANSI_Keypad2 = 0x54,
  455. kVK_ANSI_Keypad3 = 0x55,
  456. kVK_ANSI_Keypad4 = 0x56,
  457. kVK_ANSI_Keypad5 = 0x57,
  458. kVK_ANSI_Keypad6 = 0x58,
  459. kVK_ANSI_Keypad7 = 0x59,
  460. kVK_ANSI_Keypad8 = 0x5B,
  461. kVK_ANSI_Keypad9 = 0x5C
  462. };
  463. /* keycodes for keys that are independent of keyboard layout*/
  464. enum {
  465. kVK_Return = 0x24,
  466. kVK_Tab = 0x30,
  467. kVK_Space = 0x31,
  468. kVK_Delete = 0x33,
  469. kVK_Escape = 0x35,
  470. kVK_Command = 0x37,
  471. kVK_Shift = 0x38,
  472. kVK_CapsLock = 0x39,
  473. kVK_Option = 0x3A,
  474. kVK_Control = 0x3B,
  475. kVK_RightShift = 0x3C,
  476. kVK_RightOption = 0x3D,
  477. kVK_RightControl = 0x3E,
  478. kVK_Function = 0x3F,
  479. kVK_F17 = 0x40,
  480. kVK_VolumeUp = 0x48,
  481. kVK_VolumeDown = 0x49,
  482. kVK_Mute = 0x4A,
  483. kVK_F18 = 0x4F,
  484. kVK_F19 = 0x50,
  485. kVK_F20 = 0x5A,
  486. kVK_F5 = 0x60,
  487. kVK_F6 = 0x61,
  488. kVK_F7 = 0x62,
  489. kVK_F3 = 0x63,
  490. kVK_F8 = 0x64,
  491. kVK_F9 = 0x65,
  492. kVK_F11 = 0x67,
  493. kVK_F13 = 0x69,
  494. kVK_F16 = 0x6A,
  495. kVK_F14 = 0x6B,
  496. kVK_F10 = 0x6D,
  497. kVK_F12 = 0x6F,
  498. kVK_F15 = 0x71,
  499. kVK_Help = 0x72,
  500. kVK_Home = 0x73,
  501. kVK_PageUp = 0x74,
  502. kVK_ForwardDelete = 0x75,
  503. kVK_F4 = 0x76,
  504. kVK_End = 0x77,
  505. kVK_F2 = 0x78,
  506. kVK_PageDown = 0x79,
  507. kVK_F1 = 0x7A,
  508. kVK_LeftArrow = 0x7B,
  509. kVK_RightArrow = 0x7C,
  510. kVK_DownArrow = 0x7D,
  511. kVK_UpArrow = 0x7E
  512. };
  513. /* ISO keyboards only*/
  514. enum {
  515. kVK_ISO_Section = 0x0A
  516. };
  517. /* JIS keyboards only*/
  518. enum {
  519. kVK_JIS_Yen = 0x5D,
  520. kVK_JIS_Underscore = 0x5E,
  521. kVK_JIS_KeypadComma = 0x5F,
  522. kVK_JIS_Eisu = 0x66,
  523. kVK_JIS_Kana = 0x68
  524. };
  525. int getAsciiCodeFromVirtualKeycode(int virtualKeyCode)
  526. {
  527. int keycode = 0xffffffff;
  528. switch (virtualKeyCode)
  529. {
  530. case kVK_ANSI_A : {keycode = 'a'; break;}
  531. case kVK_ANSI_B : {keycode = 'b'; break;}
  532. case kVK_ANSI_C : {keycode = 'c'; break;}
  533. case kVK_ANSI_D : {keycode = 'd';break;}
  534. case kVK_ANSI_E : {keycode = 'e'; break;}
  535. case kVK_ANSI_F : {keycode = 'f'; break;}
  536. case kVK_ANSI_G : {keycode = 'g'; break;}
  537. case kVK_ANSI_H : {keycode = 'h'; break;}
  538. case kVK_ANSI_I : {keycode = 'i'; break;}
  539. case kVK_ANSI_J : {keycode = 'j'; break;}
  540. case kVK_ANSI_K : {keycode = 'k'; break;}
  541. case kVK_ANSI_L : {keycode = 'l'; break;}
  542. case kVK_ANSI_M : {keycode = 'm'; break;}
  543. case kVK_ANSI_N : {keycode = 'n'; break;}
  544. case kVK_ANSI_O : {keycode = 'o'; break;}
  545. case kVK_ANSI_P : {keycode = 'p'; break;}
  546. case kVK_ANSI_Q : {keycode = 'q'; break;}
  547. case kVK_ANSI_R : {keycode = 'r'; break;}
  548. case kVK_ANSI_S : {keycode = 's';break;}
  549. case kVK_ANSI_T : {keycode = 't'; break;}
  550. case kVK_ANSI_U : {keycode = 'u'; break;}
  551. case kVK_ANSI_V : {keycode = 'v'; break;}
  552. case kVK_ANSI_W : {keycode = 'w'; break;}
  553. case kVK_ANSI_X : {keycode = 'x'; break;}
  554. case kVK_ANSI_Y : {keycode = 'y'; break;}
  555. case kVK_ANSI_Z : {keycode = 'z'; break;}
  556. case kVK_ANSI_1 : {keycode = '1'; break;}
  557. case kVK_ANSI_2 : {keycode = '2'; break;}
  558. case kVK_ANSI_3 : {keycode = '3'; break;}
  559. case kVK_ANSI_4 : {keycode = '4'; break;}
  560. case kVK_ANSI_5 : {keycode = '5'; break;}
  561. case kVK_ANSI_6 : {keycode = '6'; break;}
  562. case kVK_ANSI_7 : {keycode = '7'; break;}
  563. case kVK_ANSI_8 : {keycode = '8'; break;}
  564. case kVK_ANSI_9 : {keycode = '9'; break;}
  565. case kVK_ANSI_0 : {keycode = '0'; break;}
  566. case kVK_ANSI_Equal : {keycode = '='; break;}
  567. case kVK_ANSI_Minus : {keycode = '-'; break;}
  568. case kVK_Tab: {keycode = 9; break;}
  569. case kVK_Space: {keycode=' '; break;}
  570. case kVK_Escape: {keycode=27; break;}
  571. case kVK_Delete: {keycode=8; break;}
  572. case kVK_ForwardDelete: {keycode=B3G_INSERT; break;}
  573. case kVK_F1: {keycode = B3G_F1; break;}
  574. case kVK_F2: {keycode = B3G_F2; break;}
  575. case kVK_F3: {keycode = B3G_F3; break;}
  576. case kVK_F4: {keycode = B3G_F4; break;}
  577. case kVK_F5: {keycode = B3G_F5; break;}
  578. case kVK_F6: {keycode = B3G_F6; break;}
  579. case kVK_F7: {keycode = B3G_F7; break;}
  580. case kVK_F8: {keycode = B3G_F8; break;}
  581. case kVK_F9: {keycode = B3G_F9; break;}
  582. case kVK_F10: {keycode = B3G_F10; break;}
  583. case kVK_F11: {keycode = B3G_F11; break;}
  584. case kVK_F12: {keycode = B3G_F12; break;}
  585. case kVK_F13: {keycode = B3G_F13; break;}
  586. case kVK_F14: {keycode = B3G_F14; break;}
  587. case kVK_F15: {keycode = B3G_F15; break;}
  588. case kVK_LeftArrow: {keycode = B3G_LEFT_ARROW;break;}
  589. case kVK_RightArrow: {keycode = B3G_RIGHT_ARROW;break;}
  590. case kVK_UpArrow: {keycode = B3G_UP_ARROW;break;}
  591. case kVK_DownArrow: {keycode = B3G_DOWN_ARROW;break;}
  592. case kVK_PageUp :{keycode = B3G_PAGE_UP;break;}
  593. case kVK_PageDown :{keycode = B3G_PAGE_DOWN;break;}
  594. case kVK_End :{keycode = B3G_END;break;}
  595. case kVK_Home :{keycode = B3G_HOME;break;}
  596. case kVK_Control: {keycode = B3G_CONTROL;break;}
  597. case kVK_Option: {keycode = B3G_ALT;break;}
  598. case kVK_ANSI_RightBracket : {keycode = ']'; break;}
  599. case kVK_ANSI_LeftBracket : {keycode = '['; break;}
  600. case kVK_ANSI_Quote : {keycode = '\''; break;}
  601. case kVK_ANSI_Semicolon : {keycode = ';'; break;}
  602. case kVK_ANSI_Backslash : {keycode = '\\'; break;}
  603. case kVK_ANSI_Comma : {keycode = ','; break;}
  604. case kVK_ANSI_Slash : {keycode = '/'; break;}
  605. case kVK_ANSI_Period : {keycode = '.'; break;}
  606. case kVK_ANSI_Grave : {keycode = '`'; break;}
  607. case kVK_ANSI_KeypadDecimal : {keycode = '.'; break;}
  608. case kVK_ANSI_KeypadMultiply : {keycode = '*'; break;}
  609. case kVK_ANSI_KeypadPlus : {keycode = '+'; break;}
  610. case kVK_ANSI_KeypadClear : {keycode = '?'; break;}
  611. case kVK_ANSI_KeypadDivide : {keycode = '/'; break;}
  612. case kVK_ANSI_KeypadEnter : {keycode = B3G_RETURN; break;}
  613. case kVK_ANSI_KeypadMinus : {keycode = '-'; break;}
  614. case kVK_ANSI_KeypadEquals : {keycode = '='; break;}
  615. case kVK_ANSI_Keypad0 : {keycode = '0'; break;}
  616. case kVK_ANSI_Keypad1 : {keycode = '1'; break;}
  617. case kVK_ANSI_Keypad2 : {keycode = '2'; break;}
  618. case kVK_ANSI_Keypad3 : {keycode = '3'; break;}
  619. case kVK_ANSI_Keypad4 : {keycode = '4'; break;}
  620. case kVK_ANSI_Keypad5 : {keycode = '5'; break;}
  621. case kVK_ANSI_Keypad6 : {keycode = '6'; break;}
  622. case kVK_ANSI_Keypad7 : {keycode = '7'; break;}
  623. case kVK_ANSI_Keypad8 : {keycode = '8'; break;}
  624. case kVK_ANSI_Keypad9 : {keycode = '9'; break;}
  625. case kVK_Return:
  626. {
  627. keycode = B3G_RETURN; break;
  628. }
  629. default:
  630. {
  631. printf("unknown keycode\n");
  632. }
  633. }
  634. return keycode;
  635. }
  636. int Mac_updateWindow(struct MacOpenGLWindowInternalData* m_internalData)
  637. {
  638. NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  639. GLint err = glGetError();
  640. assert(err==GL_NO_ERROR);
  641. NSEvent *event = nil;
  642. bool handledEvent = false;
  643. do
  644. {
  645. [pool release];
  646. pool = [[NSAutoreleasePool alloc] init];
  647. event = [m_internalData->m_myApp
  648. nextEventMatchingMask:MyNSAnyEventMask
  649. untilDate:[NSDate distantPast]
  650. inMode:NSDefaultRunLoopMode
  651. // inMode:NSEventTrackingRunLoopMode
  652. dequeue:YES];
  653. //NSShiftKeyMask = 1 << 17,
  654. //NSControlKeyMask
  655. if ([event type] == MyNSEventTypeFlagsChanged)
  656. {
  657. int modifiers = [event modifierFlags];
  658. if (m_internalData->m_keyboardCallback)
  659. {
  660. if ((modifiers & MyNSEventModifierFlagShift))
  661. {
  662. m_internalData->m_keyboardCallback(B3G_SHIFT,1);
  663. m_internalData->m_modifierFlags |= MY_MAC_SHIFTKEY;
  664. }else
  665. {
  666. if (m_internalData->m_modifierFlags& MY_MAC_SHIFTKEY)
  667. {
  668. m_internalData->m_keyboardCallback(B3G_SHIFT,0);
  669. m_internalData->m_modifierFlags &= ~MY_MAC_SHIFTKEY;
  670. }
  671. }
  672. if (modifiers & MyNSEventModifierFlagControl)
  673. {
  674. m_internalData->m_keyboardCallback(B3G_CONTROL,1);
  675. m_internalData->m_modifierFlags |= MY_MAC_CONTROL_KEY;
  676. } else
  677. {
  678. if (m_internalData->m_modifierFlags&MY_MAC_CONTROL_KEY)
  679. {
  680. m_internalData->m_keyboardCallback(B3G_CONTROL,0);
  681. m_internalData->m_modifierFlags &= ~MY_MAC_CONTROL_KEY;
  682. }
  683. }
  684. if (modifiers & MyNSEventModifierFlagOption)
  685. {
  686. m_internalData->m_keyboardCallback(B3G_ALT,1);
  687. m_internalData->m_modifierFlags |= MY_MAC_ALTKEY;
  688. } else
  689. {
  690. if (m_internalData->m_modifierFlags&MY_MAC_ALTKEY)
  691. {
  692. m_internalData->m_keyboardCallback(B3G_ALT,0);
  693. m_internalData->m_modifierFlags &= ~MY_MAC_ALTKEY;
  694. }
  695. }
  696. //handle NSCommandKeyMask
  697. }
  698. }
  699. if ([event type] == MyNSKeyUp)
  700. {
  701. handledEvent = true;
  702. uint32 virtualKeycode = [event keyCode];
  703. int keycode = getAsciiCodeFromVirtualKeycode(virtualKeycode);
  704. // printf("keycode = %d\n", keycode);
  705. if (m_internalData->m_keyboardCallback)
  706. {
  707. int state = 0;
  708. m_internalData->m_keyboardCallback(keycode,state);
  709. }
  710. }
  711. if ([event type] == MyNSKeyDown)
  712. {
  713. handledEvent = true;
  714. if (![event isARepeat])
  715. {
  716. uint32 virtualKeycode = [event keyCode];
  717. int keycode = getAsciiCodeFromVirtualKeycode(virtualKeycode);
  718. //printf("keycode = %d\n", keycode);
  719. if (m_internalData->m_keyboardCallback)
  720. {
  721. int state = 1;
  722. m_internalData->m_keyboardCallback(keycode,state);
  723. }
  724. }
  725. }
  726. if (([event type]== MyNSRightMouseDown) || ([ event type]==MyNSLeftMouseDown)||([event type]==MyNSOtherMouseDown))
  727. {
  728. // printf("right mouse!");
  729. // float mouseX,mouseY;
  730. NSPoint eventLocation = [event locationInWindow];
  731. NSPoint center = [m_internalData->m_myview convertPoint:eventLocation fromView:nil];
  732. m_internalData->m_mouseX = center.x;
  733. m_internalData->m_mouseY = [m_internalData->m_myview GetWindowHeight] - center.y;
  734. int button=0;
  735. switch ([event type])
  736. {
  737. case MyNSLeftMouseDown:
  738. {
  739. button=0;
  740. break;
  741. }
  742. case MyNSOtherMouseDown:
  743. {
  744. button=1;
  745. break;
  746. }
  747. case MyNSRightMouseDown:
  748. {
  749. button=2;
  750. break;
  751. }
  752. default:
  753. {
  754. }
  755. };
  756. // printf("mouse coord = %f, %f\n",mouseX,mouseY);
  757. if (m_internalData->m_mouseButtonCallback)
  758. {
  759. //handledEvent = true;
  760. (*m_internalData->m_mouseButtonCallback)(button,1,m_internalData->m_mouseX,m_internalData->m_mouseY);
  761. }
  762. }
  763. if (([event type]== MyNSRightMouseUp) || ([ event type]==MyNSLeftMouseUp)||([event type]==MyNSOtherMouseUp))
  764. {
  765. // printf("right mouse!");
  766. // float mouseX,mouseY;
  767. NSPoint eventLocation = [event locationInWindow];
  768. NSPoint center = [m_internalData->m_myview convertPoint:eventLocation fromView:nil];
  769. m_internalData->m_mouseX = center.x;
  770. m_internalData->m_mouseY = [m_internalData->m_myview GetWindowHeight] - center.y;
  771. int button=0;
  772. switch ([event type])
  773. {
  774. case MyNSLeftMouseUp:
  775. {
  776. button=0;
  777. break;
  778. }
  779. case MyNSOtherMouseUp:
  780. {
  781. button=1;
  782. break;
  783. }
  784. case MyNSRightMouseUp:
  785. {
  786. button=2;
  787. break;
  788. }
  789. default:
  790. {
  791. }
  792. };
  793. // printf("mouse coord = %f, %f\n",mouseX,mouseY);
  794. if (m_internalData->m_mouseButtonCallback)
  795. (*m_internalData->m_mouseButtonCallback)(button,0,m_internalData->m_mouseX,m_internalData->m_mouseY);
  796. }
  797. if ([event type] == MyNSMouseMoved)
  798. {
  799. NSPoint eventLocation = [event locationInWindow];
  800. NSPoint center = [m_internalData->m_myview convertPoint:eventLocation fromView:nil];
  801. m_internalData->m_mouseX = center.x;
  802. m_internalData->m_mouseY = [m_internalData->m_myview GetWindowHeight] - center.y;
  803. // printf("mouse coord = %f, %f\n",m_mouseX,m_mouseY);
  804. if (m_internalData->m_mouseMoveCallback)
  805. {
  806. //handledEvent = true;
  807. (*m_internalData->m_mouseMoveCallback)(m_internalData->m_mouseX,m_internalData->m_mouseY);
  808. }
  809. }
  810. if (([event type] == MyNSLeftMouseDragged) || ([event type] == MyNSRightMouseDragged) || ([event type] == MyNSOtherMouseDragged))
  811. {
  812. int dx1, dy1;
  813. CGGetLastMouseDelta (&dx1, &dy1);
  814. NSPoint eventLocation = [event locationInWindow];
  815. NSPoint center = [m_internalData->m_myview convertPoint:eventLocation fromView:nil];
  816. m_internalData->m_mouseX = center.x;
  817. m_internalData->m_mouseY = [m_internalData->m_myview GetWindowHeight] - center.y;
  818. if (m_internalData->m_mouseMoveCallback)
  819. {
  820. //handledEvent = true;
  821. (*m_internalData->m_mouseMoveCallback)(m_internalData->m_mouseX,m_internalData->m_mouseY);
  822. }
  823. // printf("mouse coord = %f, %f\n",m_mouseX,m_mouseY);
  824. }
  825. if ([event type] == MyNSScrollWheel)
  826. {
  827. float dy, dx;
  828. dy = [ event deltaY ];
  829. dx = [ event deltaX ];
  830. if (m_internalData->m_wheelCallback)
  831. {
  832. handledEvent = true;
  833. (*m_internalData->m_wheelCallback)(dx,dy);
  834. }
  835. // m_cameraDistance -= dy*0.1;
  836. // m_azi -= dx*0.1;
  837. }
  838. if (!handledEvent)
  839. [m_internalData->m_myApp sendEvent:event];
  840. [m_internalData->m_myApp updateWindows];
  841. } while (event);
  842. err = glGetError();
  843. assert(err==GL_NO_ERROR);
  844. [m_internalData->m_myview MakeCurrent];
  845. err = glGetError();
  846. assert(err==GL_NO_ERROR);
  847. // glClearColor(1,1,1,1);
  848. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); //clear buffers
  849. err = glGetError();
  850. assert(err==GL_NO_ERROR);
  851. //glCullFace(GL_BACK);
  852. //glFrontFace(GL_CCW);
  853. glEnable(GL_DEPTH_TEST);
  854. err = glGetError();
  855. assert(err==GL_NO_ERROR);
  856. err = glGetError();
  857. assert(err==GL_NO_ERROR);
  858. [pool release];
  859. return 0;
  860. }
  861. int Mac_isModifierKeyPressed(struct MacOpenGLWindowInternalData* m_internalData, int key)
  862. {
  863. int isPressed = 0;
  864. switch (key)
  865. {
  866. case B3G_ALT:
  867. {
  868. isPressed = ((m_internalData->m_modifierFlags & MY_MAC_ALTKEY)!=0);
  869. break;
  870. };
  871. case B3G_SHIFT:
  872. {
  873. isPressed = ((m_internalData->m_modifierFlags & MY_MAC_SHIFTKEY)!=0);
  874. break;
  875. };
  876. case B3G_CONTROL:
  877. {
  878. isPressed = ((m_internalData->m_modifierFlags & MY_MAC_CONTROL_KEY )!=0);
  879. break;
  880. };
  881. default:
  882. {
  883. }
  884. };
  885. return isPressed;
  886. }
  887. //void Mac_setRenderCallback(struct MacOpenGLWindowInternalData* m_internalData, b3RenderCallback renderCallback)
  888. //{
  889. // m_internalData->m_renderCallback = renderCallback;
  890. //}
  891. void Mac_swapBuffer(struct MacOpenGLWindowInternalData* m_internalData)
  892. {
  893. [m_internalData->m_myview MakeCurrent];
  894. //#ifndef NO_OPENGL3
  895. // glSwapAPPLE();
  896. //#else
  897. [[m_internalData->m_myview getContext] flushBuffer];
  898. // #endif
  899. }
  900. int Mac_requestedExit(struct MacOpenGLWindowInternalData* m_internalData)
  901. {
  902. int closeme = m_internalData->m_myview.GetRequestClose;
  903. return m_internalData->m_exitRequested || closeme;
  904. }
  905. void Mac_setRequestExit(struct MacOpenGLWindowInternalData* m_internalData)
  906. {
  907. m_internalData->m_exitRequested = true;
  908. }
  909. void Mac_setMouseButtonCallback(struct MacOpenGLWindowInternalData* m_internalData, b3MouseButtonCallback mouseCallback)
  910. {
  911. m_internalData->m_mouseButtonCallback = mouseCallback;
  912. }
  913. b3MouseButtonCallback Mac_getMouseButtonCallback(struct MacOpenGLWindowInternalData* m_internalData)
  914. {
  915. return m_internalData->m_mouseButtonCallback;
  916. }
  917. void Mac_setWheelCallback(struct MacOpenGLWindowInternalData* m_internalData, b3WheelCallback wheelCallback)
  918. {
  919. m_internalData->m_wheelCallback = wheelCallback;
  920. }
  921. b3WheelCallback Mac_getWheelCallback(struct MacOpenGLWindowInternalData* m_internalData)
  922. {
  923. return m_internalData->m_wheelCallback;
  924. }
  925. void Mac_setMouseMoveCallback(struct MacOpenGLWindowInternalData* m_internalData, b3MouseMoveCallback mouseCallback)
  926. {
  927. m_internalData->m_mouseMoveCallback = mouseCallback;
  928. }
  929. b3MouseMoveCallback Mac_getMouseMoveCallback(struct MacOpenGLWindowInternalData* m_internalData)
  930. {
  931. return m_internalData->m_mouseMoveCallback;
  932. }
  933. b3KeyboardCallback Mac_getKeyboardCallback(struct MacOpenGLWindowInternalData* m_internalData)
  934. {
  935. return m_internalData->m_keyboardCallback;
  936. }
  937. void Mac_setKeyboardCallback( struct MacOpenGLWindowInternalData* m_internalData, b3KeyboardCallback keyboardCallback)
  938. {
  939. m_internalData->m_keyboardCallback = keyboardCallback;
  940. }
  941. float Mac_getRetinaScale(struct MacOpenGLWindowInternalData* m_internalData)
  942. {
  943. return m_internalData->m_retinaScaleFactor;
  944. }
  945. void Mac_setAllowRetina(struct MacOpenGLWindowInternalData* m_internalData, int allow)
  946. {
  947. m_internalData->m_allowRetina = allow;
  948. }
  949. int Mac_fileOpenDialog(char* filename, int maxNameLength)
  950. {
  951. //save/restore the OpenGL context, NSOpenPanel can mess it up
  952. //http://stackoverflow.com/questions/13987148/nsopenpanel-breaks-my-sdl-opengl-app
  953. NSOpenGLContext *foo = [NSOpenGLContext currentContext];
  954. // get the url of a .txt file
  955. NSOpenPanel * zOpenPanel = [NSOpenPanel openPanel];
  956. NSArray * zAryOfExtensions = [NSArray arrayWithObjects:@"urdf",@"bullet",@"obj",@"sdf",@"stl",nil];
  957. [zOpenPanel setAllowedFileTypes:zAryOfExtensions];
  958. NSInteger zIntResult = [zOpenPanel runModal];
  959. [foo makeCurrentContext];
  960. [foo update];
  961. if (zIntResult == NSFileHandlingPanelCancelButton) {
  962. NSLog(@"readUsingOpenPanel cancelled");
  963. return 0;
  964. }
  965. NSURL *zUrl = [zOpenPanel URL];
  966. if (zUrl)
  967. {
  968. //without the file://
  969. NSString *myString = [zUrl absoluteString];
  970. int slen = (int)[myString length];
  971. if (slen < maxNameLength)
  972. {
  973. const char *cfilename=[myString UTF8String];
  974. //expect file:// at start of URL
  975. const char* p = strstr(cfilename, "file://");
  976. if (p==cfilename)
  977. {
  978. int actualLen = (int)strlen(cfilename)-7;
  979. memcpy(filename, cfilename+7,actualLen);
  980. filename[actualLen]=0;
  981. return actualLen;
  982. }
  983. }
  984. }
  985. return 0;
  986. }
  987. void Mac_getMouseCoordinates(struct MacOpenGLWindowInternalData* m_internalData, int* xPtr, int* yPtr)
  988. {
  989. NSPoint pt = [m_internalData->m_window mouseLocationOutsideOfEventStream];
  990. m_internalData->m_mouseX = pt.x;
  991. m_internalData->m_mouseY = pt.y;
  992. *xPtr = m_internalData->m_mouseX;
  993. //our convention is x,y is upper left hand side
  994. *yPtr = [m_internalData->m_myview GetWindowHeight]-m_internalData->m_mouseY;
  995. }
  996. int Mac_getWidth(struct MacOpenGLWindowInternalData* m_internalData)
  997. {
  998. if (m_internalData && m_internalData->m_myview && m_internalData->m_myview.GetWindowWidth)
  999. return m_internalData->m_myview.GetWindowWidth;
  1000. return 0;
  1001. }
  1002. int Mac_getHeight(struct MacOpenGLWindowInternalData* m_internalData)
  1003. {
  1004. if (m_internalData && m_internalData->m_myview && m_internalData->m_myview.GetWindowHeight)
  1005. return m_internalData->m_myview.GetWindowHeight;
  1006. return 0;
  1007. }
  1008. void Mac_setResizeCallback(struct MacOpenGLWindowInternalData* m_internalData, b3ResizeCallback resizeCallback)
  1009. {
  1010. [m_internalData->m_myview setResizeCallback:resizeCallback];
  1011. if (resizeCallback)
  1012. {
  1013. (resizeCallback)(Mac_getWidth(m_internalData), Mac_getHeight(m_internalData));
  1014. }
  1015. }
  1016. b3ResizeCallback Mac_getResizeCallback(struct MacOpenGLWindowInternalData* m_internalData)
  1017. {
  1018. return [m_internalData->m_myview getResizeCallback];
  1019. }
  1020. #endif //B3_USE_GLFW