Mercurial > sdl-ios-xcode
comparison src/video/quartz/SDL_QuartzWM.m @ 1883:2780f547f5e7
Fix for bug #240
Christian Walther contributed Cocoa cursor code.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Sat, 24 Jun 2006 17:36:55 +0000 |
parents | 9c882e94b545 |
children | c121d94672cb 0c76e6d1c3d6 |
comparison
equal
deleted
inserted
replaced
1882:339d733e3699 | 1883:2780f547f5e7 |
---|---|
23 | 23 |
24 #include "SDL_QuartzVideo.h" | 24 #include "SDL_QuartzVideo.h" |
25 | 25 |
26 | 26 |
27 struct WMcursor { | 27 struct WMcursor { |
28 Cursor curs; | 28 NSCursor *nscursor; |
29 }; | 29 }; |
30 | 30 |
31 void QZ_FreeWMCursor (_THIS, WMcursor *cursor) { | 31 void QZ_FreeWMCursor (_THIS, WMcursor *cursor) { |
32 | 32 |
33 if ( cursor != NULL ) | 33 if ( cursor != NULL ) { |
34 [ cursor->nscursor release ]; | |
34 free (cursor); | 35 free (cursor); |
35 } | 36 } |
36 | 37 } |
37 /* Use the Carbon cursor routines for now */ | 38 |
38 WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask, | 39 WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask, |
39 int w, int h, int hot_x, int hot_y) { | 40 int w, int h, int hot_x, int hot_y) { |
40 WMcursor *cursor; | 41 WMcursor *cursor; |
41 int row, bytes; | 42 NSBitmapImageRep *imgrep; |
42 | 43 NSImage *img; |
44 unsigned char *planes[5]; | |
45 int i; | |
46 NSAutoreleasePool *pool; | |
47 | |
48 pool = [ [ NSAutoreleasePool alloc ] init ]; | |
49 | |
43 /* Allocate the cursor memory */ | 50 /* Allocate the cursor memory */ |
44 cursor = (WMcursor *)SDL_malloc(sizeof(WMcursor)); | 51 cursor = (WMcursor *)SDL_malloc(sizeof(WMcursor)); |
45 if ( cursor == NULL ) { | 52 if (cursor == NULL) goto outOfMemory; |
46 SDL_OutOfMemory(); | 53 |
47 return(NULL); | 54 /* create the image representation and get the pointers to its storage */ |
48 } | 55 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 ]; |
49 SDL_memset(cursor, 0, sizeof(*cursor)); | 56 if (imgrep == nil) goto outOfMemory; |
50 | 57 [ imgrep getBitmapDataPlanes: planes ]; |
51 if (w > 16) | 58 |
52 w = 16; | 59 /* copy data and mask, extending the mask to all black pixels because the inversion effect doesn't work with Cocoa's alpha-blended cursors */ |
53 | 60 for (i = 0; i < (w+7)/8*h; i++) { |
54 if (h > 16) | 61 planes[0][i] = data[i]; |
55 h = 16; | 62 planes[1][i] = mask[i] | data[i]; |
56 | 63 } |
57 bytes = (w+7)/8; | 64 |
58 | 65 /* create image and cursor */ |
59 for ( row=0; row<h; ++row ) { | 66 img = [ [ [ NSImage alloc ] initWithSize: NSMakeSize(w, h) ] autorelease ]; |
60 SDL_memcpy(&cursor->curs.data[row], data, bytes); | 67 if (img == nil) goto outOfMemory; |
61 data += bytes; | 68 [ img addRepresentation: imgrep ]; |
62 } | 69 if (system_version < 0x1030) { /* on 10.2, cursors must be 16*16 */ |
63 for ( row=0; row<h; ++row ) { | 70 if (w > 16 || h > 16) { /* too big: scale it down */ |
64 SDL_memcpy(&cursor->curs.mask[row], mask, bytes); | 71 [ img setScalesWhenResized: YES ]; |
65 mask += bytes; | 72 hot_x = hot_x*16/w; |
66 } | 73 hot_y = hot_y*16/h; |
67 cursor->curs.hotSpot.h = hot_x; | 74 } |
68 cursor->curs.hotSpot.v = hot_y; | 75 else { /* too small (or just right): extend it (from the bottom left corner, so hot_y must be adjusted) */ |
69 | 76 hot_y += 16 - h; |
77 } | |
78 [ img setSize: NSMakeSize(16, 16) ]; | |
79 } | |
80 cursor->nscursor = [ [ NSCursor alloc ] initWithImage: img hotSpot: NSMakePoint(hot_x, hot_y) ]; | |
81 if (cursor->nscursor == nil) goto outOfMemory; | |
82 | |
83 [ pool release ]; | |
70 return(cursor); | 84 return(cursor); |
85 | |
86 outOfMemory: | |
87 [ pool release ]; | |
88 if (cursor != NULL) SDL_free(cursor); | |
89 SDL_OutOfMemory(); | |
90 return(NULL); | |
71 } | 91 } |
72 | 92 |
73 void QZ_ShowMouse (_THIS) { | 93 void QZ_ShowMouse (_THIS) { |
74 if (!cursor_visible) { | 94 if (!cursor_visible) { |
75 [ NSCursor unhide ]; | 95 [ NSCursor unhide ]; |
101 cursor_should_be_visible = NO; | 121 cursor_should_be_visible = NO; |
102 QZ_ChangeGrabState (this, QZ_HIDECURSOR); | 122 QZ_ChangeGrabState (this, QZ_HIDECURSOR); |
103 } | 123 } |
104 } | 124 } |
105 else { | 125 else { |
106 SetCursor(&cursor->curs); | 126 [ cursor->nscursor set ]; |
107 if ( ! cursor_should_be_visible ) { | 127 if ( ! cursor_should_be_visible ) { |
108 QZ_ShowMouse (this); | 128 QZ_ShowMouse (this); |
109 cursor_should_be_visible = YES; | 129 cursor_should_be_visible = YES; |
110 QZ_ChangeGrabState (this, QZ_SHOWCURSOR); | 130 QZ_ChangeGrabState (this, QZ_SHOWCURSOR); |
111 } | 131 } |