SDL_QuartzEvents.m
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:16k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2. SDL - Simple DirectMedia Layer
  3. Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Library General Public
  6. License as published by the Free Software Foundation; either
  7. version 2 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11. Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this library; if not, write to the Free
  14. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15. Sam Lantinga
  16. slouken@libsdl.org
  17. */
  18. #include <sys/time.h>
  19. #include "SDL_QuartzKeys.h"
  20. static SDLKey keymap[256];
  21. static unsigned int currentMods = 0; /* Current keyboard modifiers, to track modifier state */
  22. static int last_virtual_button = 0; /* Last virtual mouse button pressed */
  23. static void  QZ_InitOSKeymap (_THIS) {
  24. const void *KCHRPtr;
  25. UInt32 state;
  26. UInt32 value;
  27. int i;
  28. int world = SDLK_WORLD_0;
  29. for ( i=0; i<SDL_TABLESIZE(keymap); ++i )
  30. keymap[i] = SDLK_UNKNOWN;
  31. /* This keymap is almost exactly the same as the OS 9 one */
  32. keymap[QZ_ESCAPE] = SDLK_ESCAPE;
  33. keymap[QZ_F1] = SDLK_F1;
  34. keymap[QZ_F2] = SDLK_F2;
  35. keymap[QZ_F3] = SDLK_F3;
  36. keymap[QZ_F4] = SDLK_F4;
  37. keymap[QZ_F5] = SDLK_F5;
  38. keymap[QZ_F6] = SDLK_F6;
  39. keymap[QZ_F7] = SDLK_F7;
  40. keymap[QZ_F8] = SDLK_F8;
  41. keymap[QZ_F9] = SDLK_F9;
  42. keymap[QZ_F10] = SDLK_F10;
  43. keymap[QZ_F11] = SDLK_F11;
  44. keymap[QZ_F12] = SDLK_F12;
  45. keymap[QZ_PRINT] = SDLK_PRINT;
  46. keymap[QZ_SCROLLOCK] = SDLK_SCROLLOCK;
  47. keymap[QZ_PAUSE] = SDLK_PAUSE;
  48. keymap[QZ_POWER] = SDLK_POWER;
  49. keymap[QZ_BACKQUOTE] = SDLK_BACKQUOTE;
  50. keymap[QZ_1] = SDLK_1;
  51. keymap[QZ_2] = SDLK_2;
  52. keymap[QZ_3] = SDLK_3;
  53. keymap[QZ_4] = SDLK_4;
  54. keymap[QZ_5] = SDLK_5;
  55. keymap[QZ_6] = SDLK_6;
  56. keymap[QZ_7] = SDLK_7;
  57. keymap[QZ_8] = SDLK_8;
  58. keymap[QZ_9] = SDLK_9;
  59. keymap[QZ_0] = SDLK_0;
  60. keymap[QZ_MINUS] = SDLK_MINUS;
  61. keymap[QZ_EQUALS] = SDLK_EQUALS;
  62. keymap[QZ_BACKSPACE] = SDLK_BACKSPACE;
  63. keymap[QZ_INSERT] = SDLK_INSERT;
  64. keymap[QZ_HOME] = SDLK_HOME;
  65. keymap[QZ_PAGEUP] = SDLK_PAGEUP;
  66. keymap[QZ_NUMLOCK] = SDLK_NUMLOCK;
  67. keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS;
  68. keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE;
  69. keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
  70. keymap[QZ_TAB] = SDLK_TAB;
  71. keymap[QZ_q] = SDLK_q;
  72. keymap[QZ_w] = SDLK_w;
  73. keymap[QZ_e] = SDLK_e;
  74. keymap[QZ_r] = SDLK_r;
  75. keymap[QZ_t] = SDLK_t;
  76. keymap[QZ_y] = SDLK_y;
  77. keymap[QZ_u] = SDLK_u;
  78. keymap[QZ_i] = SDLK_i;
  79. keymap[QZ_o] = SDLK_o;
  80. keymap[QZ_p] = SDLK_p;
  81. keymap[QZ_LEFTBRACKET] = SDLK_LEFTBRACKET;
  82. keymap[QZ_RIGHTBRACKET] = SDLK_RIGHTBRACKET;
  83. keymap[QZ_BACKSLASH] = SDLK_BACKSLASH;
  84. keymap[QZ_DELETE] = SDLK_DELETE;
  85. keymap[QZ_END] = SDLK_END;
  86. keymap[QZ_PAGEDOWN] = SDLK_PAGEDOWN;
  87. keymap[QZ_KP7] = SDLK_KP7;
  88. keymap[QZ_KP8] = SDLK_KP8;
  89. keymap[QZ_KP9] = SDLK_KP9;
  90. keymap[QZ_KP_MINUS] = SDLK_KP_MINUS;
  91. keymap[QZ_CAPSLOCK] = SDLK_CAPSLOCK;
  92. keymap[QZ_a] = SDLK_a;
  93. keymap[QZ_s] = SDLK_s;
  94. keymap[QZ_d] = SDLK_d;
  95. keymap[QZ_f] = SDLK_f;
  96. keymap[QZ_g] = SDLK_g;
  97. keymap[QZ_h] = SDLK_h;
  98. keymap[QZ_j] = SDLK_j;
  99. keymap[QZ_k] = SDLK_k;
  100. keymap[QZ_l] = SDLK_l;
  101. keymap[QZ_SEMICOLON] = SDLK_SEMICOLON;
  102. keymap[QZ_QUOTE] = SDLK_QUOTE;
  103. keymap[QZ_RETURN] = SDLK_RETURN;
  104. keymap[QZ_KP4] = SDLK_KP4;
  105. keymap[QZ_KP5] = SDLK_KP5;
  106. keymap[QZ_KP6] = SDLK_KP6;
  107. keymap[QZ_KP_PLUS] = SDLK_KP_PLUS;
  108. keymap[QZ_LSHIFT] = SDLK_LSHIFT;
  109. keymap[QZ_z] = SDLK_z;
  110. keymap[QZ_x] = SDLK_x;
  111. keymap[QZ_c] = SDLK_c;
  112. keymap[QZ_v] = SDLK_v;
  113. keymap[QZ_b] = SDLK_b;
  114. keymap[QZ_n] = SDLK_n;
  115. keymap[QZ_m] = SDLK_m;
  116. keymap[QZ_COMMA] = SDLK_COMMA;
  117. keymap[QZ_PERIOD] = SDLK_PERIOD;
  118. keymap[QZ_SLASH] = SDLK_SLASH;
  119. keymap[QZ_UP] = SDLK_UP;
  120. keymap[QZ_KP1] = SDLK_KP1;
  121. keymap[QZ_KP2] = SDLK_KP2;
  122. keymap[QZ_KP3] = SDLK_KP3;
  123. keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
  124. keymap[QZ_LCTRL] = SDLK_LCTRL;
  125. keymap[QZ_LALT] = SDLK_LALT;
  126. keymap[QZ_LMETA] = SDLK_LMETA;
  127. keymap[QZ_SPACE] = SDLK_SPACE;
  128. keymap[QZ_LEFT] = SDLK_LEFT;
  129. keymap[QZ_DOWN] = SDLK_DOWN;
  130. keymap[QZ_RIGHT] = SDLK_RIGHT;
  131. keymap[QZ_KP0] = SDLK_KP0;
  132. keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD;
  133. keymap[QZ_IBOOK_ENTER] = SDLK_KP_ENTER;
  134. keymap[QZ_IBOOK_RIGHT] = SDLK_RIGHT;
  135. keymap[QZ_IBOOK_DOWN] = SDLK_DOWN;
  136. keymap[QZ_IBOOK_UP]   = SDLK_UP;
  137. keymap[QZ_IBOOK_LEFT] = SDLK_LEFT;
  138. /* Up there we setup a static scancode->keysym map. However, it will not
  139.  * work very well on international keyboard. Hence we now query MacOS
  140.  * for its own keymap to adjust our own mapping table. However, this is
  141.  * bascially only useful for ascii char keys. This is also the reason
  142.  * why we keep the static table, too.
  143.  */
  144. /* Get a pointer to the systems cached KCHR */
  145. KCHRPtr = (void *)GetScriptManagerVariable(smKCHRCache);
  146. if (KCHRPtr)
  147. {
  148. /* Loop over all 127 possible scan codes */
  149. for (i = 0; i < 0x7F; i++)
  150. {
  151. /* We pretend a clean start to begin with (i.e. no dead keys active */
  152. state = 0;
  153. /* Now translate the key code to a key value */
  154. value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
  155. /* If the state become 0, it was a dead key. We need to translate again,
  156. passing in the new state, to get the actual key value */
  157. if (state != 0)
  158. value = KeyTranslate(KCHRPtr, i, &state) & 0xff;
  159. /* Now we should have an ascii value, or 0. Try to figure out to which SDL symbol it maps */
  160. if (value >= 128)  /* Some non-ASCII char, map it to SDLK_WORLD_* */
  161. keymap[i] = world++;
  162. else if (value >= 32)  /* non-control ASCII char */
  163. keymap[i] = value;
  164. }
  165. }
  166. /* The keypad codes are re-setup here, because the loop above cannot
  167.  * distinguish between a key on the keypad and a regular key. We maybe
  168.  * could get around this problem in another fashion: NSEvent's flags
  169.  * include a "NSNumericPadKeyMask" bit; we could check that and modify
  170.  * the symbol we return on the fly. However, this flag seems to exhibit
  171.  * some weird behaviour related to the num lock key
  172.  */
  173. keymap[QZ_KP0] = SDLK_KP0;
  174. keymap[QZ_KP1] = SDLK_KP1;
  175. keymap[QZ_KP2] = SDLK_KP2;
  176. keymap[QZ_KP3] = SDLK_KP3;
  177. keymap[QZ_KP4] = SDLK_KP4;
  178. keymap[QZ_KP5] = SDLK_KP5;
  179. keymap[QZ_KP6] = SDLK_KP6;
  180. keymap[QZ_KP7] = SDLK_KP7;
  181. keymap[QZ_KP8] = SDLK_KP8;
  182. keymap[QZ_KP9] = SDLK_KP9;
  183. keymap[QZ_KP_MINUS] = SDLK_KP_MINUS;
  184. keymap[QZ_KP_PLUS] = SDLK_KP_PLUS;
  185. keymap[QZ_KP_PERIOD] = SDLK_KP_PERIOD;
  186. keymap[QZ_KP_EQUALS] = SDLK_KP_EQUALS;
  187. keymap[QZ_KP_DIVIDE] = SDLK_KP_DIVIDE;
  188. keymap[QZ_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
  189. keymap[QZ_KP_ENTER] = SDLK_KP_ENTER;
  190. }
  191. static void QZ_DoKey (int state, NSEvent *event) {
  192. NSString *chars;
  193. int i;
  194. SDL_keysym key;
  195. /* An event can contain multiple characters */
  196. /* I'll ignore this fact for now, since there is only one virtual key code per event */
  197. chars = [ event characters ];
  198. for (i =0; i < 1 /*[ chars length ] */; i++) {
  199. key.scancode = [ event keyCode ];
  200. key.sym  = keymap [ key.scancode ];
  201. key.unicode  = [ chars characterAtIndex:i];
  202. key.mod  = KMOD_NONE;
  203. SDL_PrivateKeyboard (state, &key);
  204. }
  205. }
  206. static void QZ_DoModifiers (unsigned int newMods) {
  207. const int mapping[] = { SDLK_CAPSLOCK, SDLK_LSHIFT, SDLK_LCTRL, SDLK_LALT, SDLK_LMETA } ;
  208. int i;
  209. int bit;
  210. SDL_keysym key;
  211. key.scancode = 0;
  212. key.sym  = SDLK_UNKNOWN;
  213. key.unicode  = 0;
  214. key.mod  = KMOD_NONE;
  215. /* Iterate through the bits, testing each against the current modifiers */
  216. for (i = 0, bit = NSAlphaShiftKeyMask; bit <= NSCommandKeyMask; bit <<= 1, ++i) {
  217. unsigned int currentMask, newMask;
  218. currentMask = currentMods & bit;
  219. newMask = newMods & bit;
  220. if ( currentMask &&
  221.  currentMask != newMask ) {  /* modifier up event */
  222. key.sym = mapping[i];
  223. /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
  224. if (bit == NSAlphaShiftKeyMask)
  225. SDL_PrivateKeyboard (SDL_PRESSED, &key);
  226. SDL_PrivateKeyboard (SDL_RELEASED, &key);
  227. }
  228. else
  229. if ( newMask &&
  230.  currentMask != newMask ) {  /* modifier down event */
  231. key.sym = mapping[i];
  232. SDL_PrivateKeyboard (SDL_PRESSED, &key);
  233. /* If this was Caps Lock, we need some additional voodoo to make SDL happy */
  234. if (bit == NSAlphaShiftKeyMask)
  235. SDL_PrivateKeyboard (SDL_RELEASED, &key);
  236. }
  237. }
  238. currentMods = newMods;
  239. }
  240. static void QZ_DoActivate (_THIS)
  241. {
  242. inForeground = YES;
  243. /* Regrab the mouse */
  244. if (currentGrabMode == SDL_GRAB_ON) {
  245. QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
  246. CGAssociateMouseAndMouseCursorPosition (0);
  247. }
  248. /* Hide the mouse cursor if inside the app window */
  249. if (!QZ_cursor_visible) {
  250. HideCursor ();
  251. }
  252. SDL_PrivateAppActive (1, SDL_APPINPUTFOCUS);
  253. }
  254. static void QZ_DoDeactivate (_THIS) {
  255. inForeground = NO;
  256. /* Ungrab mouse if it is grabbed */
  257. if (currentGrabMode == SDL_GRAB_ON) {
  258. CGAssociateMouseAndMouseCursorPosition (1);
  259. }
  260. /* Show the mouse cursor */
  261. if (!QZ_cursor_visible) {
  262. ShowCursor ();
  263. }
  264. SDL_PrivateAppActive (0, SDL_APPINPUTFOCUS);
  265. }
  266. static void QZ_PumpEvents (_THIS)
  267. {
  268.         static NSPoint lastMouse;
  269.         NSPoint mouse, saveMouse;
  270.         Point qdMouse;
  271.         CGMouseDelta dx, dy;
  272.         
  273.         NSDate *distantPast;
  274. NSEvent *event;
  275. NSRect winRect;
  276. NSRect titleBarRect;
  277. NSAutoreleasePool *pool;
  278. pool = [ [ NSAutoreleasePool alloc ] init ];
  279. distantPast = [ NSDate distantPast ];
  280. winRect = NSMakeRect (0, 0, SDL_VideoSurface->w, SDL_VideoSurface->h);
  281. titleBarRect = NSMakeRect ( 0, SDL_VideoSurface->h, SDL_VideoSurface->w,
  282. SDL_VideoSurface->h + 22 );
  283.         if (currentGrabMode != SDL_GRAB_ON) { /* if grabbed, the cursor can't move! (see fallback below) */
  284.         
  285.             /* 1/2 second after a warp, the mouse cannot move (don't ask me why) */
  286.             /* So, approximate motion with CGGetLastMouseDelta, which still works, somehow */
  287.             if (! warp_flag) {
  288.             
  289.                 GetGlobalMouse (&qdMouse);  /* use Carbon since [ NSEvent mouseLocation ] is broken */
  290.                 mouse = NSMakePoint (qdMouse.h, qdMouse.v);
  291.                 saveMouse = mouse;
  292.                 
  293.                 if (mouse.x != lastMouse.x || mouse.y != lastMouse.y) {
  294.                 
  295.                     QZ_PrivateCGToSDL (this, &mouse);
  296.                     if (inForeground && NSPointInRect (mouse, winRect)) {
  297.                         //printf ("Mouse Loc: (%f, %f)n", mouse.x, mouse.y);
  298.                         SDL_PrivateMouseMotion (0, 0, mouse.x, mouse.y);
  299.                     }
  300.                 }
  301.                 lastMouse = saveMouse;
  302.             }
  303.         }
  304.         
  305.         /* accumulate any mouse events into one SDL mouse event */
  306.         dx = 0;
  307.         dy = 0;
  308.         
  309. do {
  310. /* Poll for an event. This will not block */
  311. event = [ NSApp nextEventMatchingMask:NSAnyEventMask
  312. untilDate:distantPast
  313. inMode: NSDefaultRunLoopMode dequeue:YES ];
  314. if (event != nil) {
  315. unsigned int type;
  316. BOOL isForGameWin;
  317. #define DO_MOUSE_DOWN(button, sendToWindow) do {  
  318. if ( inForeground ) {                                  
  319. if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) ||  
  320.  NSPointInRect([event locationInWindow], winRect) )  
  321. SDL_PrivateMouseButton (SDL_PRESSED, button, 0, 0);  
  322. }                                                                        
  323. else {  
  324. QZ_DoActivate (this);                                            
  325. }  
  326. [ NSApp sendEvent:event ];                          
  327. } while(0)
  328. #define DO_MOUSE_UP(button, sendToWindow) do {  
  329. if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) ||  
  330.  !NSPointInRect([event locationInWindow], titleBarRect) )        
  331. SDL_PrivateMouseButton (SDL_RELEASED, button, 0, 0);          
  332. [ NSApp sendEvent:event ];  
  333. } while(0)
  334. type = [ event type ];
  335. isForGameWin = (qz_window == [ event window ]);
  336. switch (type) {
  337. case NSLeftMouseDown:
  338. if ( NSCommandKeyMask & currentMods ) {
  339. last_virtual_button = 3;
  340. DO_MOUSE_DOWN (3, 0);
  341. }
  342. else if ( NSAlternateKeyMask & currentMods ) {
  343. last_virtual_button = 2;
  344. DO_MOUSE_DOWN (2, 0);
  345. }
  346. else {
  347. DO_MOUSE_DOWN (1, 1);
  348. }
  349. break;
  350. case NSOtherMouseDown: DO_MOUSE_DOWN (2, 0); break;
  351. case NSRightMouseDown: DO_MOUSE_DOWN (3, 0); break;
  352. case NSLeftMouseUp:
  353. if ( last_virtual_button != 0 ) {
  354. DO_MOUSE_UP (last_virtual_button, 0);
  355. last_virtual_button = 0;
  356. }
  357. else {
  358. DO_MOUSE_UP (1, 1);
  359. }
  360. break;
  361. case NSOtherMouseUp:   DO_MOUSE_UP (2, 0);  break;
  362. case NSRightMouseUp:   DO_MOUSE_UP (3, 0);  break;
  363. case NSSystemDefined:
  364. //if ([event subtype] == 7) {
  365. //   unsigned int buttons;   // up to 32 mouse button states!
  366. //   buttons = [ event data2 ];
  367. //}
  368. break;
  369. case NSLeftMouseDragged:
  370. case NSRightMouseDragged:
  371. case 27:
  372. case NSMouseMoved:
  373.                             
  374.                                 if (currentGrabMode == SDL_GRAB_ON) { 
  375.                                     
  376.                                     /** 
  377.                                      *  If input is grabbed, we'll wing it and try to send some mouse
  378.                                      *  moved events with CGGetLastMouseDelta(). Not optimal, but better
  379.                                      *  than nothing.
  380.                                      **/ 
  381.                                      CGMouseDelta dx1, dy1;
  382.                                      CGGetLastMouseDelta (&dx1, &dy1);
  383.                                      dx += dx1;
  384.                                      dy += dy1;
  385.                                 }
  386.                                 else if (warp_flag) {
  387.                                 
  388.                                     Uint32 ticks;
  389.                 
  390.                                     ticks = SDL_GetTicks();
  391.                                     if (ticks - warp_ticks < 150) {
  392.                                     
  393.                                         CGMouseDelta dx1, dy1;
  394.                                         CGGetLastMouseDelta (&dx1, &dy1);
  395.                                         dx += dx1;
  396.                                         dy += dy1;
  397.                                     }
  398.                                     else {
  399.                                         
  400.                                         warp_flag = 0;
  401.                                     }
  402.                                 }
  403.                                 
  404. break;
  405. case NSScrollWheel:
  406. {
  407. if (NSPointInRect([ event locationInWindow ], winRect)) {
  408. float dy;
  409. dy = [ event deltaY ];
  410. if ( dy > 0.0 ) /* Scroll up */
  411. SDL_PrivateMouseButton (SDL_PRESSED, 4, 0, 0);
  412. else /* Scroll down */
  413. SDL_PrivateMouseButton (SDL_PRESSED, 5, 0, 0);
  414. }
  415. }
  416. break;
  417. case NSKeyUp:
  418. QZ_DoKey (SDL_RELEASED, event);
  419. break;
  420. case NSKeyDown:
  421. QZ_DoKey (SDL_PRESSED, event);
  422. break;
  423. case NSFlagsChanged:
  424. QZ_DoModifiers( [ event modifierFlags ] );
  425. break;
  426. case NSAppKitDefined:
  427. switch ( [ event subtype ] ) {
  428. case NSApplicationActivatedEventType:
  429. QZ_DoActivate (this);
  430. break;
  431. case NSApplicationDeactivatedEventType:
  432. QZ_DoDeactivate (this);
  433. break;
  434. }
  435. [ NSApp sendEvent:event ];
  436. break;
  437. /* case NSApplicationDefined: break; */
  438. /* case NSPeriodic: break; */
  439. /* case NSCursorUpdate: break; */
  440.                         
  441.                         default:
  442. [ NSApp sendEvent:event ];
  443. }
  444. }
  445.   } while (event != nil);
  446.           /* check for accumulated mouse events */
  447.           if (dx != 0 || dy != 0)
  448.             SDL_PrivateMouseMotion (0, 1, dx, dy);
  449.         
  450.   [ pool release ];
  451. }