Skip to content

Latest commit

 

History

History
407 lines (316 loc) · 11.2 KB

SDL_QuartzWM.m

File metadata and controls

407 lines (316 loc) · 11.2 KB
 
1
2
/*
SDL - Simple DirectMedia Layer
Jan 4, 2004
Jan 4, 2004
3
Copyright (C) 1997-2003 Sam Lantinga
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Sam Lantinga
Dec 14, 2001
Dec 14, 2001
20
slouken@libsdl.org
Jan 4, 2004
Jan 4, 2004
23
24
#include "SDL_QuartzVideo.h"
Dec 27, 2002
Dec 27, 2002
25
26
27
28
29
struct WMcursor {
Cursor curs;
};
Jan 4, 2004
Jan 4, 2004
30
void QZ_FreeWMCursor (_THIS, WMcursor *cursor) {
31
32
33
34
35
36
if ( cursor != NULL )
free (cursor);
}
/* Use the Carbon cursor routines for now */
Jan 4, 2004
Jan 4, 2004
37
WMcursor* QZ_CreateWMCursor (_THIS, Uint8 *data, Uint8 *mask,
Jun 1, 2002
Jun 1, 2002
38
39
40
41
42
43
44
45
46
47
48
int w, int h, int hot_x, int hot_y) {
WMcursor *cursor;
int row, bytes;
/* Allocate the cursor memory */
cursor = (WMcursor *)malloc(sizeof(WMcursor));
if ( cursor == NULL ) {
SDL_OutOfMemory();
return(NULL);
}
memset(cursor, 0, sizeof(*cursor));
Sep 4, 2001
Sep 4, 2001
49
50
51
52
53
54
55
if (w > 16)
w = 16;
if (h > 16)
h = 16;
Jun 1, 2002
Jun 1, 2002
56
57
58
59
60
61
62
63
64
65
66
67
68
bytes = (w+7)/8;
for ( row=0; row<h; ++row ) {
memcpy(&cursor->curs.data[row], data, bytes);
data += bytes;
}
for ( row=0; row<h; ++row ) {
memcpy(&cursor->curs.mask[row], mask, bytes);
mask += bytes;
}
cursor->curs.hotSpot.h = hot_x;
cursor->curs.hotSpot.v = hot_y;
Sep 4, 2001
Sep 4, 2001
69
return(cursor);
Jan 4, 2004
Jan 4, 2004
72
73
74
75
76
77
78
79
void QZ_ShowMouse (_THIS) {
if (!cursor_visible) {
[ NSCursor unhide ];
cursor_visible = YES;
}
}
void QZ_HideMouse (_THIS) {
Jan 7, 2004
Jan 7, 2004
80
81
BOOL isInGameWin = QZ_IsMouseInWindow (this);
if (isInGameWin && cursor_visible) {
Jan 4, 2004
Jan 4, 2004
82
83
84
85
86
[ NSCursor hide ];
cursor_visible = NO;
}
}
Jan 7, 2004
Jan 7, 2004
87
88
89
90
BOOL QZ_IsMouseInWindow (_THIS) {
return (mode_flags & SDL_FULLSCREEN) ? true : NSPointInRect([ qz_window mouseLocationOutsideOfEventStream ], [ window_view frame ]);
}
Jan 4, 2004
Jan 4, 2004
91
int QZ_ShowWMCursor (_THIS, WMcursor *cursor) {
92
93
if ( cursor == NULL) {
Jan 4, 2004
Jan 4, 2004
94
95
96
if ( cursor_should_be_visible ) {
QZ_HideMouse (this);
cursor_should_be_visible = NO;
Dec 27, 2002
Dec 27, 2002
97
QZ_ChangeGrabState (this, QZ_HIDECURSOR);
98
99
100
101
}
}
else {
SetCursor(&cursor->curs);
Jan 4, 2004
Jan 4, 2004
102
103
104
if ( ! cursor_should_be_visible ) {
QZ_ShowMouse (this);
cursor_should_be_visible = YES;
Dec 27, 2002
Dec 27, 2002
105
QZ_ChangeGrabState (this, QZ_SHOWCURSOR);
106
107
108
109
110
111
}
}
return 1;
}
Oct 5, 2002
Oct 5, 2002
112
113
114
115
116
117
118
/*
Coordinate conversion functions, for convenience
Cocoa sets the origin at the lower left corner of the window/screen
SDL, CoreGraphics/WindowServer, and QuickDraw use the origin at the upper left corner
The routines were written so they could be called before SetVideoMode() has finished;
this might have limited usefulness at the moment, but the extra cost is trivial.
*/
Jan 22, 2002
Jan 22, 2002
120
/* Convert Cocoa screen coordinate to Cocoa window coordinate */
Jan 4, 2004
Jan 4, 2004
121
void QZ_PrivateGlobalToLocal (_THIS, NSPoint *p) {
Jan 22, 2002
Jan 22, 2002
122
123
124
125
126
127
*p = [ qz_window convertScreenToBase:*p ];
}
/* Convert Cocoa window coordinate to Cocoa screen coordinate */
Jan 4, 2004
Jan 4, 2004
128
void QZ_PrivateLocalToGlobal (_THIS, NSPoint *p) {
Jan 22, 2002
Jan 22, 2002
129
130
131
132
133
*p = [ qz_window convertBaseToScreen:*p ];
}
/* Convert SDL coordinate to Cocoa coordinate */
Jan 4, 2004
Jan 4, 2004
134
void QZ_PrivateSDLToCocoa (_THIS, NSPoint *p) {
Jan 22, 2002
Jan 22, 2002
135
136
137
if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */
Mar 22, 2004
Mar 22, 2004
138
p->y = CGDisplayPixelsHigh (display_id) - p->y;
Jan 22, 2002
Jan 22, 2002
139
}
Aug 20, 2004
Aug 20, 2004
141
142
*p = [ window_view convertPoint:*p toView: nil ];
Jan 22, 2002
Jan 22, 2002
146
/* Convert Cocoa coordinate to SDL coordinate */
Jan 4, 2004
Jan 4, 2004
147
void QZ_PrivateCocoaToSDL (_THIS, NSPoint *p) {
Jan 22, 2002
Jan 22, 2002
148
Aug 10, 2003
Aug 10, 2003
149
150
if ( CGDisplayIsCaptured (display_id) ) { /* capture signals fullscreen */
Mar 22, 2004
Mar 22, 2004
151
p->y = CGDisplayPixelsHigh (display_id) - p->y;
Aug 10, 2003
Aug 10, 2003
152
153
}
else {
Mar 22, 2004
Mar 22, 2004
154
Aug 20, 2004
Aug 20, 2004
155
156
157
158
*p = [ window_view convertPoint:*p fromView: nil ];
/* The coordinates need to be inverted */
p->y = [window_view frame].size.height - p->y - 1;
Aug 10, 2003
Aug 10, 2003
159
}
Jan 22, 2002
Jan 22, 2002
160
161
162
}
/* Convert SDL coordinate to window server (CoreGraphics) coordinate */
Jan 4, 2004
Jan 4, 2004
163
CGPoint QZ_PrivateSDLToCG (_THIS, NSPoint *p) {
Jan 22, 2002
Jan 22, 2002
164
165
166
167
CGPoint cgp;
if ( ! CGDisplayIsCaptured (display_id) ) { /* not captured => not fullscreen => local coord */
Jan 22, 2002
Jan 22, 2002
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
int height;
QZ_PrivateSDLToCocoa (this, p);
QZ_PrivateLocalToGlobal (this, p);
height = CGDisplayPixelsHigh (display_id);
p->y = height - p->y;
}
cgp.x = p->x;
cgp.y = p->y;
return cgp;
}
Aug 10, 2003
Aug 10, 2003
184
#if 0 /* Dead code */
Jan 22, 2002
Jan 22, 2002
185
/* Convert window server (CoreGraphics) coordinate to SDL coordinate */
Jan 4, 2004
Jan 4, 2004
186
void QZ_PrivateCGToSDL (_THIS, NSPoint *p) {
Jan 22, 2002
Jan 22, 2002
187
188
189
190
191
192
193
194
195
196
197
198
199
if ( ! CGDisplayIsCaptured (display_id) ) { /* not captured => not fullscreen => local coord */
int height;
/* Convert CG Global to Cocoa Global */
height = CGDisplayPixelsHigh (display_id);
p->y = height - p->y;
QZ_PrivateGlobalToLocal (this, p);
QZ_PrivateCocoaToSDL (this, p);
}
}
Aug 10, 2003
Aug 10, 2003
200
#endif /* Dead code */
Jan 22, 2002
Jan 22, 2002
201
Jan 4, 2004
Jan 4, 2004
202
void QZ_PrivateWarpCursor (_THIS, int x, int y) {
Jan 22, 2002
Jan 22, 2002
203
204
205
206
207
NSPoint p;
CGPoint cgp;
p = NSMakePoint (x, y);
Dec 27, 2002
Dec 27, 2002
208
209
210
211
212
cgp = QZ_PrivateSDLToCG (this, &p);
/* this is the magic call that fixes cursor "freezing" after warp */
CGSetLocalEventsSuppressionInterval (0.0);
CGWarpMouseCursorPosition (cgp);
Jan 22, 2002
Jan 22, 2002
213
214
}
Jan 4, 2004
Jan 4, 2004
215
void QZ_WarpWMCursor (_THIS, Uint16 x, Uint16 y) {
Jan 22, 2002
Jan 22, 2002
216
217
/* Only allow warping when in foreground */
Jan 4, 2004
Jan 4, 2004
218
if ( ! [ NSApp isActive ] )
219
220
221
return;
/* Do the actual warp */
Jan 22, 2002
Jan 22, 2002
222
QZ_PrivateWarpCursor (this, x, y);
Dec 27, 2002
Dec 27, 2002
223
224
225
/* Generate the mouse moved event */
SDL_PrivateMouseMotion (0, 0, x, y);
Jan 4, 2004
Jan 4, 2004
228
229
void QZ_MoveWMCursor (_THIS, int x, int y) { }
void QZ_CheckMouseMode (_THIS) { }
Jan 4, 2004
Jan 4, 2004
231
void QZ_SetCaption (_THIS, const char *title, const char *icon) {
Aug 21, 2001
Aug 21, 2001
233
if ( qz_window != nil ) {
Jun 11, 2001
Jun 11, 2001
234
235
236
NSString *string;
if ( title != NULL ) {
string = [ [ NSString alloc ] initWithCString:title ];
Aug 21, 2001
Aug 21, 2001
237
[ qz_window setTitle:string ];
Jun 11, 2001
Jun 11, 2001
238
239
240
241
[ string release ];
}
if ( icon != NULL ) {
string = [ [ NSString alloc ] initWithCString:icon ];
Aug 21, 2001
Aug 21, 2001
242
[ qz_window setMiniwindowTitle:string ];
Jun 11, 2001
Jun 11, 2001
243
244
245
[ string release ];
}
}
Jan 4, 2004
Jan 4, 2004
248
void QZ_SetIcon (_THIS, SDL_Surface *icon, Uint8 *mask)
Jan 18, 2002
Jan 18, 2002
249
{
Oct 5, 2002
Oct 5, 2002
250
251
252
NSBitmapImageRep *imgrep;
NSImage *img;
SDL_Surface *mergedSurface;
Feb 1, 2003
Feb 1, 2003
253
int i,j;
Oct 5, 2002
Oct 5, 2002
254
255
256
257
258
259
260
261
262
263
264
NSAutoreleasePool *pool;
SDL_Rect rrect;
NSSize imgSize = {icon->w, icon->h};
pool = [ [ NSAutoreleasePool alloc ] init ];
SDL_GetClipRect(icon, &rrect);
/* create a big endian RGBA surface */
mergedSurface = SDL_CreateRGBSurface(SDL_SWSURFACE|SDL_SRCALPHA,
icon->w, icon->h, 32, 0xff<<24, 0xff<<16, 0xff<<8, 0xff<<0);
if (mergedSurface==NULL) {
Mar 30, 2002
Mar 30, 2002
265
266
267
NSLog(@"Error creating surface for merge");
goto freePool;
}
Oct 5, 2002
Oct 5, 2002
268
Feb 1, 2003
Feb 1, 2003
269
270
271
272
273
274
275
if (mergedSurface->pitch !=
mergedSurface->format->BytesPerPixel * mergedSurface->w) {
SDL_SetError ("merged surface has wrong format");
SDL_FreeSurface (mergedSurface);
goto freePool;
}
Oct 5, 2002
Oct 5, 2002
276
277
278
279
280
281
if (SDL_BlitSurface(icon,&rrect,mergedSurface,&rrect)) {
NSLog(@"Error blitting to mergedSurface");
goto freePool;
}
if (mask) {
Feb 1, 2003
Feb 1, 2003
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
Uint32 *pixels = mergedSurface->pixels;
for (i = 0; i < mergedSurface->h; i++) {
for (j = 0; j < mergedSurface->w; j++) {
int index = i * mergedSurface->w + j;
int mindex = index >> 3;
int bindex = 7 - (index & 0x7);
if (mask[mindex] & (1 << bindex))
pixels[index] |= 0x000000FF;
else
pixels[index] &= 0xFFFFFF00;
}
}
Oct 5, 2002
Oct 5, 2002
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
}
imgrep = [ [ NSBitmapImageRep alloc]
initWithBitmapDataPlanes:(unsigned char **)&mergedSurface->pixels
pixelsWide:icon->w pixelsHigh:icon->h bitsPerSample:8 samplesPerPixel:4
hasAlpha:YES isPlanar:NO colorSpaceName:NSDeviceRGBColorSpace
bytesPerRow:icon->w<<2 bitsPerPixel:32 ];
img = [ [ NSImage alloc ] initWithSize:imgSize ];
[ img addRepresentation: imgrep ];
[ NSApp setApplicationIconImage:img ];
[ img release ];
[ imgrep release ];
SDL_FreeSurface(mergedSurface);
Jan 18, 2002
Jan 18, 2002
313
freePool:
Oct 5, 2002
Oct 5, 2002
314
[pool release];
Jan 4, 2004
Jan 4, 2004
317
int QZ_IconifyWindow (_THIS) {
Aug 21, 2001
Aug 21, 2001
319
320
if ( ! [ qz_window isMiniaturized ] ) {
[ qz_window miniaturize:nil ];
321
322
323
return 1;
}
else {
Oct 5, 2002
Oct 5, 2002
324
SDL_SetError ("window already iconified");
325
326
327
328
329
return 0;
}
}
/*
Jan 4, 2004
Jan 4, 2004
330
int QZ_GetWMInfo (_THIS, SDL_SysWMinfo *info) {
Aug 21, 2001
Aug 21, 2001
331
info->nsWindowPtr = qz_window;
332
333
334
return 0;
}*/
Jan 4, 2004
Jan 4, 2004
335
void QZ_ChangeGrabState (_THIS, int action) {
Dec 27, 2002
Dec 27, 2002
336
337
338
339
340
341
342
/*
Figure out what the next state should be based on the action.
Ignore actions that can't change the current state.
*/
if ( grab_state == QZ_UNGRABBED ) {
if ( action == QZ_ENABLE_GRAB ) {
Jan 4, 2004
Jan 4, 2004
343
if ( cursor_should_be_visible )
Dec 27, 2002
Dec 27, 2002
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
grab_state = QZ_VISIBLE_GRAB;
else
grab_state = QZ_INVISIBLE_GRAB;
}
}
else if ( grab_state == QZ_VISIBLE_GRAB ) {
if ( action == QZ_DISABLE_GRAB )
grab_state = QZ_UNGRABBED;
else if ( action == QZ_HIDECURSOR )
grab_state = QZ_INVISIBLE_GRAB;
}
else {
assert( grab_state == QZ_INVISIBLE_GRAB );
if ( action == QZ_DISABLE_GRAB )
grab_state = QZ_UNGRABBED;
else if ( action == QZ_SHOWCURSOR )
grab_state = QZ_VISIBLE_GRAB;
}
/* now apply the new state */
if (grab_state == QZ_UNGRABBED) {
CGAssociateMouseAndMouseCursorPosition (1);
}
else if (grab_state == QZ_VISIBLE_GRAB) {
CGAssociateMouseAndMouseCursorPosition (1);
}
else {
assert( grab_state == QZ_INVISIBLE_GRAB );
QZ_PrivateWarpCursor (this, SDL_VideoSurface->w / 2, SDL_VideoSurface->h / 2);
CGAssociateMouseAndMouseCursorPosition (0);
}
}
Jan 4, 2004
Jan 4, 2004
381
SDL_GrabMode QZ_GrabInput (_THIS, SDL_GrabMode grab_mode) {
Dec 27, 2002
Dec 27, 2002
383
384
385
386
387
388
389
390
391
392
393
394
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");
return SDL_GRAB_OFF;
}
if ( ! video_set ) {
/*SDL_SetError ("QZ_GrabInput: video is not set, grab will take effect on mode switch"); */
current_grab_mode = grab_mode;
return grab_mode; /* Will be set later on mode switch */
Dec 27, 2002
Dec 27, 2002
396
397
398
399
400
401
if ( grab_mode != SDL_GRAB_QUERY ) {
if ( doGrab )
QZ_ChangeGrabState (this, QZ_ENABLE_GRAB);
else
QZ_ChangeGrabState (this, QZ_DISABLE_GRAB);
Dec 27, 2002
Dec 27, 2002
403
404
405
current_grab_mode = doGrab ? SDL_GRAB_ON : SDL_GRAB_OFF;
}
Oct 5, 2002
Oct 5, 2002
406
return current_grab_mode;