Mercurial > sdl-ios-xcode
diff src/video/quartz/SDL_QuartzWM.m @ 1708:cd14138a8703 SDL-1.3
Merged fix for bug #240 from SDL 1.2
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 24 Jun 2006 17:31:46 +0000 |
parents | 782fd950bd46 |
children |
line wrap: on
line diff
--- a/src/video/quartz/SDL_QuartzWM.m Sat Jun 24 17:01:29 2006 +0000 +++ b/src/video/quartz/SDL_QuartzWM.m Sat Jun 24 17:31:46 2006 +0000 @@ -26,57 +26,82 @@ struct WMcursor { - Cursor curs; + NSCursor *nscursor; }; void -QZ_FreeWMCursor (_THIS, WMcursor * cursor) +QZ_FreeWMCursor(_THIS, WMcursor * cursor) { - if (cursor != NULL) - free (cursor); + if (cursor != NULL) { + [cursor->nscursor release]; + free(cursor); + } } -/* Use the Carbon cursor routines for now */ WMcursor * -QZ_CreateWMCursor (_THIS, Uint8 * data, Uint8 * mask, - int w, int h, int hot_x, int hot_y) +QZ_CreateWMCursor(_THIS, Uint8 * data, Uint8 * mask, + int w, int h, int hot_x, int hot_y) { WMcursor *cursor; - int row, bytes; + NSBitmapImageRep *imgrep; + NSImage *img; + unsigned char *planes[5]; + int i; + NSAutoreleasePool *pool; + + pool =[[NSAutoreleasePool alloc] init]; /* Allocate the cursor memory */ - cursor = (WMcursor *) SDL_malloc (sizeof (WMcursor)); - if (cursor == NULL) { - SDL_OutOfMemory (); - return (NULL); + cursor = (WMcursor *) SDL_malloc(sizeof(WMcursor)); + if (cursor == NULL) + goto outOfMemory; + + /* create the image representation and get the pointers to its storage */ + 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]; + if (imgrep == nil) + goto outOfMemory; + [imgrep getBitmapDataPlanes:planes]; + + /* copy data and mask, extending the mask to all black pixels because the inversion effect doesn't work with Cocoa's alpha-blended cursors */ + for (i = 0; i < (w + 7) / 8 * h; i++) { + planes[0][i] = data[i]; + planes[1][i] = mask[i] | data[i]; } - SDL_memset (cursor, 0, sizeof (*cursor)); - - if (w > 16) - w = 16; - - if (h > 16) - h = 16; - bytes = (w + 7) / 8; - - for (row = 0; row < h; ++row) { - SDL_memcpy (&cursor->curs.data[row], data, bytes); - data += bytes; + /* create image and cursor */ + img =[[[NSImage alloc] initWithSize:NSMakeSize(w, h)] autorelease]; + if (img == nil) + goto outOfMemory; + [img addRepresentation:imgrep]; + if (system_version < 0x1030) { /* on 10.2, cursors must be 16*16 */ + if (w > 16 || h > 16) { /* too big: scale it down */ + [img setScalesWhenResized:YES]; + hot_x = hot_x * 16 / w; + hot_y = hot_y * 16 / h; + } else { /* too small (or just right): extend it (from the bottom left corner, so hot_y must be adjusted) */ + hot_y += 16 - h; + } + [img setSize:NSMakeSize(16, 16)]; } - for (row = 0; row < h; ++row) { - SDL_memcpy (&cursor->curs.mask[row], mask, bytes); - mask += bytes; - } - cursor->curs.hotSpot.h = hot_x; - cursor->curs.hotSpot.v = hot_y; + cursor->nscursor =[[NSCursor alloc] initWithImage: img hotSpot:NSMakePoint(hot_x, + hot_y)]; + if (cursor->nscursor == nil) + goto outOfMemory; + [pool release]; return (cursor); + + outOfMemory: + [pool release]; + if (cursor != NULL) + SDL_free(cursor); + SDL_OutOfMemory(); + return (NULL); } void -QZ_ShowMouse (_THIS) +QZ_ShowMouse(_THIS) { if (!cursor_visible) { [NSCursor unhide]; @@ -85,42 +110,42 @@ } void -QZ_HideMouse (_THIS) +QZ_HideMouse(_THIS) { - if ((SDL_GetAppState () & SDL_APPMOUSEFOCUS) && cursor_visible) { + if ((SDL_GetAppState() & SDL_APPMOUSEFOCUS) && cursor_visible) { [NSCursor hide]; cursor_visible = NO; } } BOOL -QZ_IsMouseInWindow (_THIS) +QZ_IsMouseInWindow(_THIS) { if (qz_window == nil) return YES; /*fullscreen */ else { NSPoint p =[qz_window mouseLocationOutsideOfEventStream]; 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" */ - return NSPointInRect (p,[window_view frame]); + return NSPointInRect(p,[window_view frame]); } } int -QZ_ShowWMCursor (_THIS, WMcursor * cursor) +QZ_ShowWMCursor(_THIS, WMcursor * cursor) { if (cursor == NULL) { if (cursor_should_be_visible) { - QZ_HideMouse (this); + QZ_HideMouse(this); cursor_should_be_visible = NO; - QZ_ChangeGrabState (this, QZ_HIDECURSOR); + QZ_ChangeGrabState(this, QZ_HIDECURSOR); } } else { - SetCursor (&cursor->curs); + [cursor->nscursor set]; if (!cursor_should_be_visible) { - QZ_ShowMouse (this); + QZ_ShowMouse(this); cursor_should_be_visible = YES; - QZ_ChangeGrabState (this, QZ_SHOWCURSOR); + QZ_ChangeGrabState(this, QZ_SHOWCURSOR); } } @@ -137,7 +162,7 @@ /* Convert Cocoa screen coordinate to Cocoa window coordinate */ void -QZ_PrivateGlobalToLocal (_THIS, NSPoint * p) +QZ_PrivateGlobalToLocal(_THIS, NSPoint * p) { *p =[qz_window convertScreenToBase:*p]; @@ -146,7 +171,7 @@ /* Convert Cocoa window coordinate to Cocoa screen coordinate */ void -QZ_PrivateLocalToGlobal (_THIS, NSPoint * p) +QZ_PrivateLocalToGlobal(_THIS, NSPoint * p) { *p =[qz_window convertBaseToScreen:*p]; @@ -154,18 +179,18 @@ /* Convert SDL coordinate to Cocoa coordinate */ void -QZ_PrivateSDLToCocoa (_THIS, NSPoint * p) +QZ_PrivateSDLToCocoa(_THIS, NSPoint * p) { - if (CGDisplayIsCaptured (display_id)) { /* capture signals fullscreen */ + if (CGDisplayIsCaptured(display_id)) { /* capture signals fullscreen */ - p->y = CGDisplayPixelsHigh (display_id) - p->y; + p->y = CGDisplayPixelsHigh(display_id) - p->y; } else { *p =[window_view convertPoint: *p toView:nil]; /* We need a workaround in OpenGL mode */ - if (SDL_VideoSurface->flags & SDL_INTERNALOPENGL) { + if (SDL_VideoSurface->flags & SDL_OPENGL) { p->y =[window_view frame].size.height - p->y; } } @@ -173,19 +198,19 @@ /* Convert Cocoa coordinate to SDL coordinate */ void -QZ_PrivateCocoaToSDL (_THIS, NSPoint * p) +QZ_PrivateCocoaToSDL(_THIS, NSPoint * p) { - if (CGDisplayIsCaptured (display_id)) { /* capture signals fullscreen */ + if (CGDisplayIsCaptured(display_id)) { /* capture signals fullscreen */ - p->y = CGDisplayPixelsHigh (display_id) - p->y; + p->y = CGDisplayPixelsHigh(display_id) - p->y; } else { *p =[window_view convertPoint: *p fromView:nil]; /* We need a workaround in OpenGL mode */ if (SDL_VideoSurface != NULL - && (SDL_VideoSurface->flags & SDL_INTERNALOPENGL)) { + && (SDL_VideoSurface->flags & SDL_OPENGL)) { p->y =[window_view frame].size.height - p->y; } } @@ -193,19 +218,19 @@ /* Convert SDL coordinate to window server (CoreGraphics) coordinate */ CGPoint -QZ_PrivateSDLToCG (_THIS, NSPoint * p) +QZ_PrivateSDLToCG(_THIS, NSPoint * p) { CGPoint cgp; - if (!CGDisplayIsCaptured (display_id)) { /* not captured => not fullscreen => local coord */ + if (!CGDisplayIsCaptured(display_id)) { /* not captured => not fullscreen => local coord */ int height; - QZ_PrivateSDLToCocoa (this, p); - QZ_PrivateLocalToGlobal (this, p); + QZ_PrivateSDLToCocoa(this, p); + QZ_PrivateLocalToGlobal(this, p); - height = CGDisplayPixelsHigh (display_id); + height = CGDisplayPixelsHigh(display_id); p->y = height - p->y; } @@ -218,40 +243,40 @@ #if 0 /* Dead code */ /* Convert window server (CoreGraphics) coordinate to SDL coordinate */ void -QZ_PrivateCGToSDL (_THIS, NSPoint * p) +QZ_PrivateCGToSDL(_THIS, NSPoint * p) { - if (!CGDisplayIsCaptured (display_id)) { /* not captured => not fullscreen => local coord */ + if (!CGDisplayIsCaptured(display_id)) { /* not captured => not fullscreen => local coord */ int height; /* Convert CG Global to Cocoa Global */ - height = CGDisplayPixelsHigh (display_id); + height = CGDisplayPixelsHigh(display_id); p->y = height - p->y; - QZ_PrivateGlobalToLocal (this, p); - QZ_PrivateCocoaToSDL (this, p); + QZ_PrivateGlobalToLocal(this, p); + QZ_PrivateCocoaToSDL(this, p); } } #endif /* Dead code */ void -QZ_PrivateWarpCursor (_THIS, int x, int y) +QZ_PrivateWarpCursor(_THIS, int x, int y) { NSPoint p; CGPoint cgp; - p = NSMakePoint (x, y); - cgp = QZ_PrivateSDLToCG (this, &p); + p = NSMakePoint(x, y); + cgp = QZ_PrivateSDLToCG(this, &p); /* this is the magic call that fixes cursor "freezing" after warp */ - CGSetLocalEventsSuppressionInterval (0.0); - CGWarpMouseCursorPosition (cgp); + CGSetLocalEventsSuppressionInterval(0.0); + CGWarpMouseCursorPosition(cgp); } void -QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) +QZ_WarpWMCursor(_THIS, Uint16 x, Uint16 y) { /* Only allow warping when in foreground */ @@ -260,23 +285,23 @@ /* Do the actual warp */ if (grab_state != QZ_INVISIBLE_GRAB) - QZ_PrivateWarpCursor (this, x, y); + QZ_PrivateWarpCursor(this, x, y); /* Generate the mouse moved event */ - SDL_PrivateMouseMotion (0, 0, x, y); + SDL_PrivateMouseMotion(0, 0, x, y); } void -QZ_MoveWMCursor (_THIS, int x, int y) +QZ_MoveWMCursor(_THIS, int x, int y) { } void -QZ_CheckMouseMode (_THIS) +QZ_CheckMouseMode(_THIS) { } void -QZ_SetCaption (_THIS, const char *title, const char *icon) +QZ_SetCaption(_THIS, const char *title, const char *icon) { if (qz_window != nil) { @@ -295,7 +320,7 @@ } void -QZ_SetIcon (_THIS, SDL_Surface * icon, Uint8 * mask) +QZ_SetIcon(_THIS, SDL_Surface * icon, Uint8 * mask) { NSBitmapImageRep *imgrep; NSImage *img; @@ -312,7 +337,7 @@ if (imgrep == nil) goto freePool; pixels =[imgrep bitmapData]; - SDL_memset (pixels, 0, 4 * icon->w * icon->h); /* make the background, which will survive in colorkeyed areas, completely transparent */ + SDL_memset(pixels, 0, 4 * icon->w * icon->h); /* make the background, which will survive in colorkeyed areas, completely transparent */ #if SDL_BYTEORDER == SDL_BIG_ENDIAN #define BYTEORDER_DEPENDENT_RGBA_MASKS 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF @@ -320,20 +345,20 @@ #define BYTEORDER_DEPENDENT_RGBA_MASKS 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 #endif mergedSurface = - SDL_CreateRGBSurfaceFrom (pixels, icon->w, icon->h, 32, 4 * icon->w, - BYTEORDER_DEPENDENT_RGBA_MASKS); + SDL_CreateRGBSurfaceFrom(pixels, icon->w, icon->h, 32, 4 * icon->w, + BYTEORDER_DEPENDENT_RGBA_MASKS); if (mergedSurface == NULL) goto freePool; /* blit, with temporarily cleared SRCALPHA flag because we want to copy, not alpha-blend */ iconSrcAlpha = ((icon->flags & SDL_SRCALPHA) != 0); iconAlphaValue = icon->format->alpha; - SDL_SetAlpha (icon, 0, 255); - SDL_BlitSurface (icon, NULL, mergedSurface, NULL); + SDL_SetAlpha(icon, 0, 255); + SDL_BlitSurface(icon, NULL, mergedSurface, NULL); if (iconSrcAlpha) - SDL_SetAlpha (icon, SDL_SRCALPHA, iconAlphaValue); + SDL_SetAlpha(icon, SDL_SRCALPHA, iconAlphaValue); - SDL_FreeSurface (mergedSurface); + SDL_FreeSurface(mergedSurface); /* apply mask, source alpha, and premultiply color values by alpha */ maskPitch = (icon->w + 7) / 8; @@ -361,8 +386,8 @@ } } - img =[[[NSImage alloc] initWithSize:NSMakeSize (icon->w, - icon->h)] autorelease]; + img =[[[NSImage alloc] initWithSize:NSMakeSize(icon->w, + icon->h)] autorelease]; if (img == nil) goto freePool; [img addRepresentation:imgrep]; @@ -373,14 +398,14 @@ } int -QZ_IconifyWindow (_THIS) +QZ_IconifyWindow(_THIS) { if (![qz_window isMiniaturized]) { [qz_window miniaturize:nil]; return 1; } else { - SDL_SetError ("window already iconified"); + SDL_SetError("window already iconified"); return 0; } } @@ -392,7 +417,7 @@ }*/ void -QZ_ChangeGrabState (_THIS, int action) +QZ_ChangeGrabState(_THIS, int action) { /* @@ -412,7 +437,7 @@ else if (action == QZ_HIDECURSOR) grab_state = QZ_INVISIBLE_GRAB; } else { - assert (grab_state == QZ_INVISIBLE_GRAB); + assert(grab_state == QZ_INVISIBLE_GRAB); if (action == QZ_DISABLE_GRAB) grab_state = QZ_UNGRABBED; @@ -423,28 +448,28 @@ /* now apply the new state */ if (grab_state == QZ_UNGRABBED) { - CGAssociateMouseAndMouseCursorPosition (1); + CGAssociateMouseAndMouseCursorPosition(1); } else if (grab_state == QZ_VISIBLE_GRAB) { - CGAssociateMouseAndMouseCursorPosition (1); + CGAssociateMouseAndMouseCursorPosition(1); } else { - assert (grab_state == QZ_INVISIBLE_GRAB); + assert(grab_state == QZ_INVISIBLE_GRAB); - QZ_PrivateWarpCursor (this, SDL_VideoSurface->w / 2, - SDL_VideoSurface->h / 2); - CGAssociateMouseAndMouseCursorPosition (0); + QZ_PrivateWarpCursor(this, SDL_VideoSurface->w / 2, + SDL_VideoSurface->h / 2); + CGAssociateMouseAndMouseCursorPosition(0); } } SDL_GrabMode -QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) +QZ_GrabInput(_THIS, SDL_GrabMode grab_mode) { int doGrab = grab_mode & SDL_GRAB_ON; /*int fullscreen = grab_mode & SDL_GRAB_FULLSCREEN; */ if (this->screen == NULL) { - SDL_SetError ("QZ_GrabInput: screen is NULL"); + SDL_SetError("QZ_GrabInput: screen is NULL"); return SDL_GRAB_OFF; } @@ -456,9 +481,9 @@ if (grab_mode != SDL_GRAB_QUERY) { if (doGrab) - QZ_ChangeGrabState (this, QZ_ENABLE_GRAB); + QZ_ChangeGrabState(this, QZ_ENABLE_GRAB); else - QZ_ChangeGrabState (this, QZ_DISABLE_GRAB); + QZ_ChangeGrabState(this, QZ_DISABLE_GRAB); current_grab_mode = doGrab ? SDL_GRAB_ON : SDL_GRAB_OFF; }