src/video/quartz/SDL_QuartzWM.m
branchSDL-1.3
changeset 1708 cd14138a8703
parent 1662 782fd950bd46
     1.1 --- a/src/video/quartz/SDL_QuartzWM.m	Sat Jun 24 17:01:29 2006 +0000
     1.2 +++ b/src/video/quartz/SDL_QuartzWM.m	Sat Jun 24 17:31:46 2006 +0000
     1.3 @@ -26,57 +26,82 @@
     1.4  
     1.5  struct WMcursor
     1.6  {
     1.7 -    Cursor curs;
     1.8 +    NSCursor *nscursor;
     1.9  };
    1.10  
    1.11  void
    1.12 -QZ_FreeWMCursor (_THIS, WMcursor * cursor)
    1.13 +QZ_FreeWMCursor(_THIS, WMcursor * cursor)
    1.14  {
    1.15  
    1.16 -    if (cursor != NULL)
    1.17 -        free (cursor);
    1.18 +    if (cursor != NULL) {
    1.19 +        [cursor->nscursor release];
    1.20 +        free(cursor);
    1.21 +    }
    1.22  }
    1.23  
    1.24 -/* Use the Carbon cursor routines for now */
    1.25  WMcursor *
    1.26 -QZ_CreateWMCursor (_THIS, Uint8 * data, Uint8 * mask,
    1.27 -                   int w, int h, int hot_x, int hot_y)
    1.28 +QZ_CreateWMCursor(_THIS, Uint8 * data, Uint8 * mask,
    1.29 +                  int w, int h, int hot_x, int hot_y)
    1.30  {
    1.31      WMcursor *cursor;
    1.32 -    int row, bytes;
    1.33 +    NSBitmapImageRep *imgrep;
    1.34 +    NSImage *img;
    1.35 +    unsigned char *planes[5];
    1.36 +    int i;
    1.37 +    NSAutoreleasePool *pool;
    1.38 +
    1.39 +    pool =[[NSAutoreleasePool alloc] init];
    1.40  
    1.41      /* Allocate the cursor memory */
    1.42 -    cursor = (WMcursor *) SDL_malloc (sizeof (WMcursor));
    1.43 -    if (cursor == NULL) {
    1.44 -        SDL_OutOfMemory ();
    1.45 -        return (NULL);
    1.46 +    cursor = (WMcursor *) SDL_malloc(sizeof(WMcursor));
    1.47 +    if (cursor == NULL)
    1.48 +        goto outOfMemory;
    1.49 +
    1.50 +    /* create the image representation and get the pointers to its storage */
    1.51 +  imgrep =[[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL pixelsWide: w pixelsHigh: h bitsPerSample: 1 samplesPerPixel: 2 hasAlpha: YES isPlanar: YES colorSpaceName: NSDeviceBlackColorSpace bytesPerRow: (w + 7) / 8 bitsPerPixel:0] autorelease];
    1.52 +    if (imgrep == nil)
    1.53 +        goto outOfMemory;
    1.54 +  [imgrep getBitmapDataPlanes:planes];
    1.55 +
    1.56 +    /* copy data and mask, extending the mask to all black pixels because the inversion effect doesn't work with Cocoa's alpha-blended cursors */
    1.57 +    for (i = 0; i < (w + 7) / 8 * h; i++) {
    1.58 +        planes[0][i] = data[i];
    1.59 +        planes[1][i] = mask[i] | data[i];
    1.60      }
    1.61 -    SDL_memset (cursor, 0, sizeof (*cursor));
    1.62  
    1.63 -    if (w > 16)
    1.64 -        w = 16;
    1.65 +    /* create image and cursor */
    1.66 +  img =[[[NSImage alloc] initWithSize:NSMakeSize(w, h)] autorelease];
    1.67 +    if (img == nil)
    1.68 +        goto outOfMemory;
    1.69 +  [img addRepresentation:imgrep];
    1.70 +    if (system_version < 0x1030) {      /* on 10.2, cursors must be 16*16 */
    1.71 +        if (w > 16 || h > 16) { /* too big: scale it down */
    1.72 +          [img setScalesWhenResized:YES];
    1.73 +            hot_x = hot_x * 16 / w;
    1.74 +            hot_y = hot_y * 16 / h;
    1.75 +        } else {                /* too small (or just right): extend it (from the bottom left corner, so hot_y must be adjusted) */
    1.76 +            hot_y += 16 - h;
    1.77 +        }
    1.78 +      [img setSize:NSMakeSize(16, 16)];
    1.79 +    }
    1.80 +  cursor->nscursor =[[NSCursor alloc] initWithImage: img hotSpot:NSMakePoint(hot_x,
    1.81 +                hot_y)];
    1.82 +    if (cursor->nscursor == nil)
    1.83 +        goto outOfMemory;
    1.84  
    1.85 -    if (h > 16)
    1.86 -        h = 16;
    1.87 +    [pool release];
    1.88 +    return (cursor);
    1.89  
    1.90 -    bytes = (w + 7) / 8;
    1.91 -
    1.92 -    for (row = 0; row < h; ++row) {
    1.93 -        SDL_memcpy (&cursor->curs.data[row], data, bytes);
    1.94 -        data += bytes;
    1.95 -    }
    1.96 -    for (row = 0; row < h; ++row) {
    1.97 -        SDL_memcpy (&cursor->curs.mask[row], mask, bytes);
    1.98 -        mask += bytes;
    1.99 -    }
   1.100 -    cursor->curs.hotSpot.h = hot_x;
   1.101 -    cursor->curs.hotSpot.v = hot_y;
   1.102 -
   1.103 -    return (cursor);
   1.104 +  outOfMemory:
   1.105 +    [pool release];
   1.106 +    if (cursor != NULL)
   1.107 +        SDL_free(cursor);
   1.108 +    SDL_OutOfMemory();
   1.109 +    return (NULL);
   1.110  }
   1.111  
   1.112  void
   1.113 -QZ_ShowMouse (_THIS)
   1.114 +QZ_ShowMouse(_THIS)
   1.115  {
   1.116      if (!cursor_visible) {
   1.117          [NSCursor unhide];
   1.118 @@ -85,42 +110,42 @@
   1.119  }
   1.120  
   1.121  void
   1.122 -QZ_HideMouse (_THIS)
   1.123 +QZ_HideMouse(_THIS)
   1.124  {
   1.125 -    if ((SDL_GetAppState () & SDL_APPMOUSEFOCUS) && cursor_visible) {
   1.126 +    if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) && cursor_visible) {
   1.127          [NSCursor hide];
   1.128          cursor_visible = NO;
   1.129      }
   1.130  }
   1.131  
   1.132  BOOL
   1.133 -QZ_IsMouseInWindow (_THIS)
   1.134 +QZ_IsMouseInWindow(_THIS)
   1.135  {
   1.136      if (qz_window == nil)
   1.137          return YES;             /*fullscreen */
   1.138      else {
   1.139          NSPoint p =[qz_window mouseLocationOutsideOfEventStream];
   1.140          p.y -= 1.0f;            /* Apparently y goes from 1 to h, not from 0 to h-1 (i.e. the "location of the mouse" seems to be defined as "the location of the top left corner of the mouse pointer's hot pixel" */
   1.141 -        return NSPointInRect (p,[window_view frame]);
   1.142 +        return NSPointInRect(p,[window_view frame]);
   1.143      }
   1.144  }
   1.145  
   1.146  int
   1.147 -QZ_ShowWMCursor (_THIS, WMcursor * cursor)
   1.148 +QZ_ShowWMCursor(_THIS, WMcursor * cursor)
   1.149  {
   1.150  
   1.151      if (cursor == NULL) {
   1.152          if (cursor_should_be_visible) {
   1.153 -            QZ_HideMouse (this);
   1.154 +            QZ_HideMouse(this);
   1.155              cursor_should_be_visible = NO;
   1.156 -            QZ_ChangeGrabState (this, QZ_HIDECURSOR);
   1.157 +            QZ_ChangeGrabState(this, QZ_HIDECURSOR);
   1.158          }
   1.159      } else {
   1.160 -        SetCursor (&cursor->curs);
   1.161 +        [cursor->nscursor set];
   1.162          if (!cursor_should_be_visible) {
   1.163 -            QZ_ShowMouse (this);
   1.164 +            QZ_ShowMouse(this);
   1.165              cursor_should_be_visible = YES;
   1.166 -            QZ_ChangeGrabState (this, QZ_SHOWCURSOR);
   1.167 +            QZ_ChangeGrabState(this, QZ_SHOWCURSOR);
   1.168          }
   1.169      }
   1.170  
   1.171 @@ -137,7 +162,7 @@
   1.172  
   1.173  /* Convert Cocoa screen coordinate to Cocoa window coordinate */
   1.174  void
   1.175 -QZ_PrivateGlobalToLocal (_THIS, NSPoint * p)
   1.176 +QZ_PrivateGlobalToLocal(_THIS, NSPoint * p)
   1.177  {
   1.178  
   1.179    *p =[qz_window convertScreenToBase:*p];
   1.180 @@ -146,7 +171,7 @@
   1.181  
   1.182  /* Convert Cocoa window coordinate to Cocoa screen coordinate */
   1.183  void
   1.184 -QZ_PrivateLocalToGlobal (_THIS, NSPoint * p)
   1.185 +QZ_PrivateLocalToGlobal(_THIS, NSPoint * p)
   1.186  {
   1.187  
   1.188    *p =[qz_window convertBaseToScreen:*p];
   1.189 @@ -154,18 +179,18 @@
   1.190  
   1.191  /* Convert SDL coordinate to Cocoa coordinate */
   1.192  void
   1.193 -QZ_PrivateSDLToCocoa (_THIS, NSPoint * p)
   1.194 +QZ_PrivateSDLToCocoa(_THIS, NSPoint * p)
   1.195  {
   1.196  
   1.197 -    if (CGDisplayIsCaptured (display_id)) {     /* capture signals fullscreen */
   1.198 +    if (CGDisplayIsCaptured(display_id)) {      /* capture signals fullscreen */
   1.199  
   1.200 -        p->y = CGDisplayPixelsHigh (display_id) - p->y;
   1.201 +        p->y = CGDisplayPixelsHigh(display_id) - p->y;
   1.202      } else {
   1.203  
   1.204        *p =[window_view convertPoint: *p toView:nil];
   1.205  
   1.206          /* We need a workaround in OpenGL mode */
   1.207 -        if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL) {
   1.208 +        if (SDL_VideoSurface->flags & SDL_OPENGL) {
   1.209              p->y =[window_view frame].size.height - p->y;
   1.210          }
   1.211      }
   1.212 @@ -173,19 +198,19 @@
   1.213  
   1.214  /* Convert Cocoa coordinate to SDL coordinate */
   1.215  void
   1.216 -QZ_PrivateCocoaToSDL (_THIS, NSPoint * p)
   1.217 +QZ_PrivateCocoaToSDL(_THIS, NSPoint * p)
   1.218  {
   1.219  
   1.220 -    if (CGDisplayIsCaptured (display_id)) {     /* capture signals fullscreen */
   1.221 +    if (CGDisplayIsCaptured(display_id)) {      /* capture signals fullscreen */
   1.222  
   1.223 -        p->y = CGDisplayPixelsHigh (display_id) - p->y;
   1.224 +        p->y = CGDisplayPixelsHigh(display_id) - p->y;
   1.225      } else {
   1.226  
   1.227        *p =[window_view convertPoint: *p fromView:nil];
   1.228  
   1.229          /* We need a workaround in OpenGL mode */
   1.230          if (SDL_VideoSurface != NULL
   1.231 -            && (SDL_VideoSurface->flags & SDL_INTERNALOPENGL)) {
   1.232 +            && (SDL_VideoSurface->flags & SDL_OPENGL)) {
   1.233              p->y =[window_view frame].size.height - p->y;
   1.234          }
   1.235      }
   1.236 @@ -193,19 +218,19 @@
   1.237  
   1.238  /* Convert SDL coordinate to window server (CoreGraphics) coordinate */
   1.239  CGPoint
   1.240 -QZ_PrivateSDLToCG (_THIS, NSPoint * p)
   1.241 +QZ_PrivateSDLToCG(_THIS, NSPoint * p)
   1.242  {
   1.243  
   1.244      CGPoint cgp;
   1.245  
   1.246 -    if (!CGDisplayIsCaptured (display_id)) {    /* not captured => not fullscreen => local coord */
   1.247 +    if (!CGDisplayIsCaptured(display_id)) {     /* not captured => not fullscreen => local coord */
   1.248  
   1.249          int height;
   1.250  
   1.251 -        QZ_PrivateSDLToCocoa (this, p);
   1.252 -        QZ_PrivateLocalToGlobal (this, p);
   1.253 +        QZ_PrivateSDLToCocoa(this, p);
   1.254 +        QZ_PrivateLocalToGlobal(this, p);
   1.255  
   1.256 -        height = CGDisplayPixelsHigh (display_id);
   1.257 +        height = CGDisplayPixelsHigh(display_id);
   1.258          p->y = height - p->y;
   1.259      }
   1.260  
   1.261 @@ -218,40 +243,40 @@
   1.262  #if 0                           /* Dead code */
   1.263  /* Convert window server (CoreGraphics) coordinate to SDL coordinate */
   1.264  void
   1.265 -QZ_PrivateCGToSDL (_THIS, NSPoint * p)
   1.266 +QZ_PrivateCGToSDL(_THIS, NSPoint * p)
   1.267  {
   1.268  
   1.269 -    if (!CGDisplayIsCaptured (display_id)) {    /* not captured => not fullscreen => local coord */
   1.270 +    if (!CGDisplayIsCaptured(display_id)) {     /* not captured => not fullscreen => local coord */
   1.271  
   1.272          int height;
   1.273  
   1.274          /* Convert CG Global to Cocoa Global */
   1.275 -        height = CGDisplayPixelsHigh (display_id);
   1.276 +        height = CGDisplayPixelsHigh(display_id);
   1.277          p->y = height - p->y;
   1.278  
   1.279 -        QZ_PrivateGlobalToLocal (this, p);
   1.280 -        QZ_PrivateCocoaToSDL (this, p);
   1.281 +        QZ_PrivateGlobalToLocal(this, p);
   1.282 +        QZ_PrivateCocoaToSDL(this, p);
   1.283      }
   1.284  }
   1.285  #endif /* Dead code */
   1.286  
   1.287  void
   1.288 -QZ_PrivateWarpCursor (_THIS, int x, int y)
   1.289 +QZ_PrivateWarpCursor(_THIS, int x, int y)
   1.290  {
   1.291  
   1.292      NSPoint p;
   1.293      CGPoint cgp;
   1.294  
   1.295 -    p = NSMakePoint (x, y);
   1.296 -    cgp = QZ_PrivateSDLToCG (this, &p);
   1.297 +    p = NSMakePoint(x, y);
   1.298 +    cgp = QZ_PrivateSDLToCG(this, &p);
   1.299  
   1.300      /* this is the magic call that fixes cursor "freezing" after warp */
   1.301 -    CGSetLocalEventsSuppressionInterval (0.0);
   1.302 -    CGWarpMouseCursorPosition (cgp);
   1.303 +    CGSetLocalEventsSuppressionInterval(0.0);
   1.304 +    CGWarpMouseCursorPosition(cgp);
   1.305  }
   1.306  
   1.307  void
   1.308 -QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y)
   1.309 +QZ_WarpWMCursor(_THIS, Uint16 x, Uint16 y)
   1.310  {
   1.311  
   1.312      /* Only allow warping when in foreground */
   1.313 @@ -260,23 +285,23 @@
   1.314  
   1.315      /* Do the actual warp */
   1.316      if (grab_state != QZ_INVISIBLE_GRAB)
   1.317 -        QZ_PrivateWarpCursor (this, x, y);
   1.318 +        QZ_PrivateWarpCursor(this, x, y);
   1.319  
   1.320      /* Generate the mouse moved event */
   1.321 -    SDL_PrivateMouseMotion (0, 0, x, y);
   1.322 +    SDL_PrivateMouseMotion(0, 0, x, y);
   1.323  }
   1.324  
   1.325  void
   1.326 -QZ_MoveWMCursor (_THIS, int x, int y)
   1.327 +QZ_MoveWMCursor(_THIS, int x, int y)
   1.328  {
   1.329  }
   1.330  void
   1.331 -QZ_CheckMouseMode (_THIS)
   1.332 +QZ_CheckMouseMode(_THIS)
   1.333  {
   1.334  }
   1.335  
   1.336  void
   1.337 -QZ_SetCaption (_THIS, const char *title, const char *icon)
   1.338 +QZ_SetCaption(_THIS, const char *title, const char *icon)
   1.339  {
   1.340  
   1.341      if (qz_window != nil) {
   1.342 @@ -295,7 +320,7 @@
   1.343  }
   1.344  
   1.345  void
   1.346 -QZ_SetIcon (_THIS, SDL_Surface * icon, Uint8 * mask)
   1.347 +QZ_SetIcon(_THIS, SDL_Surface * icon, Uint8 * mask)
   1.348  {
   1.349      NSBitmapImageRep *imgrep;
   1.350      NSImage *img;
   1.351 @@ -312,7 +337,7 @@
   1.352      if (imgrep == nil)
   1.353          goto freePool;
   1.354      pixels =[imgrep bitmapData];
   1.355 -    SDL_memset (pixels, 0, 4 * icon->w * icon->h);      /* make the background, which will survive in colorkeyed areas, completely transparent */
   1.356 +    SDL_memset(pixels, 0, 4 * icon->w * icon->h);       /* make the background, which will survive in colorkeyed areas, completely transparent */
   1.357  
   1.358  #if SDL_BYTEORDER == SDL_BIG_ENDIAN
   1.359  #define BYTEORDER_DEPENDENT_RGBA_MASKS 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF
   1.360 @@ -320,20 +345,20 @@
   1.361  #define BYTEORDER_DEPENDENT_RGBA_MASKS 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000
   1.362  #endif
   1.363      mergedSurface =
   1.364 -        SDL_CreateRGBSurfaceFrom (pixels, icon->w, icon->h, 32, 4 * icon->w,
   1.365 -                                  BYTEORDER_DEPENDENT_RGBA_MASKS);
   1.366 +        SDL_CreateRGBSurfaceFrom(pixels, icon->w, icon->h, 32, 4 * icon->w,
   1.367 +                                 BYTEORDER_DEPENDENT_RGBA_MASKS);
   1.368      if (mergedSurface == NULL)
   1.369          goto freePool;
   1.370  
   1.371      /* blit, with temporarily cleared SRCALPHA flag because we want to copy, not alpha-blend */
   1.372      iconSrcAlpha = ((icon->flags & SDL_SRCALPHA) != 0);
   1.373      iconAlphaValue = icon->format->alpha;
   1.374 -    SDL_SetAlpha (icon, 0, 255);
   1.375 -    SDL_BlitSurface (icon, NULL, mergedSurface, NULL);
   1.376 +    SDL_SetAlpha(icon, 0, 255);
   1.377 +    SDL_BlitSurface(icon, NULL, mergedSurface, NULL);
   1.378      if (iconSrcAlpha)
   1.379 -        SDL_SetAlpha (icon, SDL_SRCALPHA, iconAlphaValue);
   1.380 +        SDL_SetAlpha(icon, SDL_SRCALPHA, iconAlphaValue);
   1.381  
   1.382 -    SDL_FreeSurface (mergedSurface);
   1.383 +    SDL_FreeSurface(mergedSurface);
   1.384  
   1.385      /* apply mask, source alpha, and premultiply color values by alpha */
   1.386      maskPitch = (icon->w + 7) / 8;
   1.387 @@ -361,8 +386,8 @@
   1.388          }
   1.389      }
   1.390  
   1.391 -  img =[[[NSImage alloc] initWithSize:NSMakeSize (icon->w,
   1.392 -                icon->h)] autorelease];
   1.393 +  img =[[[NSImage alloc] initWithSize:NSMakeSize(icon->w,
   1.394 +               icon->h)] autorelease];
   1.395      if (img == nil)
   1.396          goto freePool;
   1.397    [img addRepresentation:imgrep];
   1.398 @@ -373,14 +398,14 @@
   1.399  }
   1.400  
   1.401  int
   1.402 -QZ_IconifyWindow (_THIS)
   1.403 +QZ_IconifyWindow(_THIS)
   1.404  {
   1.405  
   1.406      if (![qz_window isMiniaturized]) {
   1.407        [qz_window miniaturize:nil];
   1.408          return 1;
   1.409      } else {
   1.410 -        SDL_SetError ("window already iconified");
   1.411 +        SDL_SetError("window already iconified");
   1.412          return 0;
   1.413      }
   1.414  }
   1.415 @@ -392,7 +417,7 @@
   1.416  }*/
   1.417  
   1.418  void
   1.419 -QZ_ChangeGrabState (_THIS, int action)
   1.420 +QZ_ChangeGrabState(_THIS, int action)
   1.421  {
   1.422  
   1.423      /* 
   1.424 @@ -412,7 +437,7 @@
   1.425          else if (action == QZ_HIDECURSOR)
   1.426              grab_state = QZ_INVISIBLE_GRAB;
   1.427      } else {
   1.428 -        assert (grab_state == QZ_INVISIBLE_GRAB);
   1.429 +        assert(grab_state == QZ_INVISIBLE_GRAB);
   1.430  
   1.431          if (action == QZ_DISABLE_GRAB)
   1.432              grab_state = QZ_UNGRABBED;
   1.433 @@ -423,28 +448,28 @@
   1.434      /* now apply the new state */
   1.435      if (grab_state == QZ_UNGRABBED) {
   1.436  
   1.437 -        CGAssociateMouseAndMouseCursorPosition (1);
   1.438 +        CGAssociateMouseAndMouseCursorPosition(1);
   1.439      } else if (grab_state == QZ_VISIBLE_GRAB) {
   1.440  
   1.441 -        CGAssociateMouseAndMouseCursorPosition (1);
   1.442 +        CGAssociateMouseAndMouseCursorPosition(1);
   1.443      } else {
   1.444 -        assert (grab_state == QZ_INVISIBLE_GRAB);
   1.445 +        assert(grab_state == QZ_INVISIBLE_GRAB);
   1.446  
   1.447 -        QZ_PrivateWarpCursor (this, SDL_VideoSurface->w / 2,
   1.448 -                              SDL_VideoSurface->h / 2);
   1.449 -        CGAssociateMouseAndMouseCursorPosition (0);
   1.450 +        QZ_PrivateWarpCursor(this, SDL_VideoSurface->w / 2,
   1.451 +                             SDL_VideoSurface->h / 2);
   1.452 +        CGAssociateMouseAndMouseCursorPosition(0);
   1.453      }
   1.454  }
   1.455  
   1.456  SDL_GrabMode
   1.457 -QZ_GrabInput (_THIS, SDL_GrabMode grab_mode)
   1.458 +QZ_GrabInput(_THIS, SDL_GrabMode grab_mode)
   1.459  {
   1.460  
   1.461      int doGrab = grab_mode & SDL_GRAB_ON;
   1.462      /*int fullscreen = grab_mode & SDL_GRAB_FULLSCREEN; */
   1.463  
   1.464      if (this->screen == NULL) {
   1.465 -        SDL_SetError ("QZ_GrabInput: screen is NULL");
   1.466 +        SDL_SetError("QZ_GrabInput: screen is NULL");
   1.467          return SDL_GRAB_OFF;
   1.468      }
   1.469  
   1.470 @@ -456,9 +481,9 @@
   1.471  
   1.472      if (grab_mode != SDL_GRAB_QUERY) {
   1.473          if (doGrab)
   1.474 -            QZ_ChangeGrabState (this, QZ_ENABLE_GRAB);
   1.475 +            QZ_ChangeGrabState(this, QZ_ENABLE_GRAB);
   1.476          else
   1.477 -            QZ_ChangeGrabState (this, QZ_DISABLE_GRAB);
   1.478 +            QZ_ChangeGrabState(this, QZ_DISABLE_GRAB);
   1.479  
   1.480          current_grab_mode = doGrab ? SDL_GRAB_ON : SDL_GRAB_OFF;
   1.481      }