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

流媒体/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. struct WMcursor {
  19.     Cursor curs;
  20. };
  21. static void QZ_FreeWMCursor     (_THIS, WMcursor *cursor) { 
  22.     if ( cursor != NULL )
  23.         free (cursor);
  24. }
  25. /* Use the Carbon cursor routines for now */
  26. static WMcursor*    QZ_CreateWMCursor   (_THIS, Uint8 *data, Uint8 *mask, 
  27.                                           int w, int h, int hot_x, int hot_y) { 
  28. WMcursor *cursor;
  29. int row, bytes;
  30. /* Allocate the cursor memory */
  31. cursor = (WMcursor *)malloc(sizeof(WMcursor));
  32. if ( cursor == NULL ) {
  33. SDL_OutOfMemory();
  34. return(NULL);
  35. }
  36. memset(cursor, 0, sizeof(*cursor));
  37.     
  38.     if (w > 16)
  39.         w = 16;
  40.     
  41.     if (h > 16)
  42.         h = 16;
  43.     
  44. bytes = (w+7)/8;
  45. for ( row=0; row<h; ++row ) {
  46. memcpy(&cursor->curs.data[row], data, bytes);
  47. data += bytes;
  48. }
  49. for ( row=0; row<h; ++row ) {
  50. memcpy(&cursor->curs.mask[row], mask, bytes);
  51. mask += bytes;
  52. }
  53. cursor->curs.hotSpot.h = hot_x;
  54. cursor->curs.hotSpot.v = hot_y;
  55.     return(cursor);
  56. }
  57. static int QZ_cursor_visible = 1;
  58.     
  59. static int QZ_ShowWMCursor (_THIS, WMcursor *cursor) { 
  60.     if ( cursor == NULL) {
  61.         if ( QZ_cursor_visible ) {
  62.             HideCursor ();
  63.             QZ_cursor_visible = 0;
  64.         }
  65.     }
  66.     else {
  67.         SetCursor(&cursor->curs);
  68.         if ( ! QZ_cursor_visible ) {
  69.             ShowCursor ();
  70.             QZ_cursor_visible = 1;
  71.         }
  72.     }
  73.     return 1;
  74. }
  75. /**
  76.  * Coordinate conversion functions, for convenience
  77.  * Cocoa sets the origin at the lower left corner of the window/screen
  78.  * SDL, CoreGraphics/WindowServer, and QuickDraw use the origin at the upper left corner
  79.  * The routines were written so they could be called before SetVideoMode() has finished;
  80.  * this might have limited usefulness at the moment, but the extra cost is trivial.
  81.  **/
  82. /* Convert Cocoa screen coordinate to Cocoa window coordinate */
  83. static void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p) {
  84.     *p = [ qz_window convertScreenToBase:*p ];
  85. }
  86. /* Convert Cocoa window coordinate to Cocoa screen coordinate */
  87. static void QZ_PrivateLocalToGlobal (_THIS, NSPoint *p) {
  88.     *p = [ qz_window convertBaseToScreen:*p ];
  89. }
  90. /* Convert SDL coordinate to Cocoa coordinate */
  91. static void QZ_PrivateSDLToCocoa (_THIS, NSPoint *p) {
  92.     int height;
  93.     
  94.     if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */
  95.     
  96.         height = CGDisplayPixelsHigh (display_id);
  97.     }
  98.     else {
  99.         
  100.         height = NSHeight ( [ qz_window frame ] );
  101.         if ( [ qz_window styleMask ] & NSTitledWindowMask ) {
  102.         
  103.             height -= 22;
  104.         }
  105.     }
  106.     
  107.     p->y = height - p->y;
  108. }
  109. /* Convert Cocoa coordinate to SDL coordinate */
  110. static void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p) {
  111.     QZ_PrivateSDLToCocoa (this, p);
  112. }
  113. /* Convert SDL coordinate to window server (CoreGraphics) coordinate */
  114. static CGPoint QZ_PrivateSDLToCG (_THIS, NSPoint *p) {
  115.     
  116.     CGPoint cgp;
  117.     
  118.     if ( ! CGDisplayIsCaptured (display_id) ) { /* not captured => not fullscreen => local coord */
  119.     
  120.         int height;
  121.         
  122.         QZ_PrivateSDLToCocoa (this, p);
  123.         QZ_PrivateLocalToGlobal (this, p);
  124.         
  125.         height = CGDisplayPixelsHigh (display_id);
  126.         p->y = height - p->y;
  127.     }
  128.     
  129.     cgp.x = p->x;
  130.     cgp.y = p->y;
  131.     
  132.     return cgp;
  133. }
  134. /* Convert window server (CoreGraphics) coordinate to SDL coordinate */
  135. static void QZ_PrivateCGToSDL (_THIS, NSPoint *p) {
  136.             
  137.     if ( ! CGDisplayIsCaptured (display_id) ) { /* not captured => not fullscreen => local coord */
  138.     
  139.         int height;
  140.         /* Convert CG Global to Cocoa Global */
  141.         height = CGDisplayPixelsHigh (display_id);
  142.         p->y = height - p->y;
  143.         QZ_PrivateGlobalToLocal (this, p);
  144.         QZ_PrivateCocoaToSDL (this, p);
  145.     }
  146. }
  147. static void  QZ_PrivateWarpCursor (_THIS, int x, int y) {
  148.     
  149.     NSPoint p;
  150.     CGPoint cgp;
  151.     
  152.     p = NSMakePoint (x, y);
  153.     cgp = QZ_PrivateSDLToCG (this, &p);   
  154.     CGDisplayMoveCursorToPoint (display_id, cgp);
  155.     warp_ticks = SDL_GetTicks();
  156.     warp_flag = 1;
  157.     SDL_PrivateMouseMotion(0, 0, x, y);
  158. }
  159. static void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) {
  160.     /* Only allow warping when in foreground */
  161.     if ( ! inForeground )
  162.         return;
  163.             
  164.     /* Do the actual warp */
  165.     QZ_PrivateWarpCursor (this, x, y);
  166. }
  167. static void QZ_MoveWMCursor     (_THIS, int x, int y) { }
  168. static void QZ_CheckMouseMode   (_THIS) { }
  169. static void QZ_SetCaption    (_THIS, const char *title, const char *icon) {
  170.     if ( qz_window != nil ) {
  171.         NSString *string;
  172.         if ( title != NULL ) {
  173.             string = [ [ NSString alloc ] initWithCString:title ];
  174.             [ qz_window setTitle:string ];
  175.             [ string release ];
  176.         }
  177.         if ( icon != NULL ) {
  178.             string = [ [ NSString alloc ] initWithCString:icon ];
  179.             [ qz_window setMiniwindowTitle:string ];
  180.             [ string release ];
  181.         }
  182.     }
  183. }
  184. static void QZ_SetIcon       (_THIS, SDL_Surface *icon, Uint8 *mask)
  185. {
  186.      NSBitmapImageRep *imgrep;
  187.      NSImage *img;
  188.      SDL_Surface *mergedSurface;
  189.      Uint8 *surfPtr;
  190.      int i,j,masksize;
  191.      NSAutoreleasePool *pool;
  192.      SDL_Rect rrect;
  193.      NSSize imgSize = {icon->w, icon->h};
  194.      pool = [ [ NSAutoreleasePool alloc ] init ];
  195.      SDL_GetClipRect(icon, &rrect);
  196.      /* create a big endian RGBA surface */
  197.      mergedSurface = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA, 
  198.                         icon->w, icon->h, 32, 0xff<<24, 0xff<<16, 0xff<<8, 0xff<<0);
  199.      if (mergedSurface==NULL) {
  200.         NSLog(@"Error creating surface for merge");
  201.         goto freePool;
  202.     }
  203.      if (SDL_BlitSurface(icon,&rrect,mergedSurface,&rrect)) {
  204.          NSLog(@"Error blitting to mergedSurface");
  205.          goto freePool;
  206.      }
  207.      if (mask) {
  208.      masksize=icon->w*icon->h;
  209.      surfPtr = (Uint8 *)mergedSurface->pixels;
  210.      #define ALPHASHIFT 3
  211.      for (i=0;i<masksize;i+=8)
  212.          for (j=0;j<8;j++) 
  213. surfPtr[ALPHASHIFT+((i+j)<<2)]=(mask[i>>3]&(1<<(7-j)))?0xFF:0x00;
  214.      }
  215.      imgrep = [[NSBitmapImageRep alloc] 
  216. initWithBitmapDataPlanes:(unsigned char **)&mergedSurface->pixels 
  217. pixelsWide:icon->w pixelsHigh:icon->h bitsPerSample:8 samplesPerPixel:4 
  218. hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace 
  219. bytesPerRow:icon->w<<2 bitsPerPixel:32];
  220.      img = [[NSImage alloc] initWithSize:imgSize];
  221.      [img addRepresentation: imgrep];
  222.      [NSApp setApplicationIconImage:img];
  223.      [img release];
  224.      [imgrep release];
  225.      SDL_FreeSurface(mergedSurface);
  226. freePool:
  227.      [pool release];
  228. }
  229. static int  QZ_IconifyWindow (_THIS) { 
  230.     /* Bug! minimize erases the framebuffer */
  231.     if ( ! [ qz_window isMiniaturized ] ) {
  232.         [ qz_window miniaturize:nil ];
  233.         return 1;
  234.     }
  235.     else {
  236.         SDL_SetError ("qz_window already iconified");
  237.         return 0;
  238.     }
  239. }
  240. /*
  241. static int  QZ_GetWMInfo  (_THIS, SDL_SysWMinfo *info) { 
  242.     info->nsWindowPtr = qz_window;
  243.     return 0; 
  244. }*/
  245. static SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) {
  246.     switch (grab_mode) {
  247. case SDL_GRAB_QUERY:
  248.             break;
  249. case SDL_GRAB_OFF:
  250.             CGAssociateMouseAndMouseCursorPosition (1);
  251.             currentGrabMode = SDL_GRAB_OFF;
  252.             break;
  253. case SDL_GRAB_ON:
  254.             QZ_WarpWMCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
  255.             CGAssociateMouseAndMouseCursorPosition (0);
  256.             currentGrabMode = SDL_GRAB_ON;
  257.             break;
  258.         case SDL_GRAB_FULLSCREEN:
  259.             
  260.             break;
  261.     }
  262.         
  263.     return currentGrabMode;
  264. }