1/*
2 * tkMacOSXCursor.c --
3 *
4 *	This file contains Macintosh specific cursor related routines.
5 *
6 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
7 * Copyright 2001-2009, Apple Inc.
8 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
9 *
10 * See the file "license.terms" for information on usage and redistribution
11 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 *
13 * RCS: @(#) $Id$
14 */
15
16#include "tkMacOSXPrivate.h"
17#include "tkMacOSXCursors.h"
18#include "tkMacOSXXCursors.h"
19
20/*
21 * Mac Cursor Types.
22 */
23
24#define NONE		-1	/* Hidden cursor */
25#define SELECTOR	1	/* NSCursor class method */
26#define IMAGENAMED	2	/* Named NSImage */
27#define IMAGEPATH	3	/* Path to NSImage */
28#define IMAGEBITMAP	4	/* Pointer to 16x16 cursor bitmap data */
29
30#define pix		16	/* Pixel width & height of cursor bitmap data */
31
32/*
33 * The following data structure contains the system specific data necessary to
34 * control Windows cursors.
35 */
36
37typedef struct {
38    TkCursor info;		/* Generic cursor info used by tkCursor.c */
39    NSCursor *macCursor;	/* Macintosh cursor */
40    int type;			/* Type of Mac cursor */
41} TkMacOSXCursor;
42
43/*
44 * The table below is used to map from the name of a predefined cursor
45 * to a NSCursor.
46 */
47
48struct CursorName {
49    const char *name;
50    const int kind;
51    id id1, id2;
52    NSPoint hotspot;
53};
54
55#define MacCursorData(n)	((id)tkMacOSXCursors[TK_MAC_CURSOR_##n])
56#define MacXCursorData(n)	((id)tkMacOSXXCursors[TK_MAC_XCURSOR_##n])
57
58static const struct CursorName cursorNames[] = {
59    {"none",			NONE,	    nil},
60    {"arrow",			SELECTOR,    @"arrowCursor"},
61    {"top_left_arrow",		SELECTOR,    @"arrowCursor"},
62    {"left_ptr",		SELECTOR,    @"arrowCursor"},
63    {"copyarrow",		SELECTOR,    @"dragCopyCursor", @"_copyDragCursor"},
64    {"aliasarrow",		SELECTOR,    @"dragLinkCursor", @"_linkDragCursor"},
65    {"contextualmenuarrow",	SELECTOR,    @"contextualMenuCursor"},
66    {"movearrow",		SELECTOR,    @"_moveCursor"},
67    {"ibeam",			SELECTOR,    @"IBeamCursor"},
68    {"text",			SELECTOR,    @"IBeamCursor"},
69    {"xterm",			SELECTOR,    @"IBeamCursor"},
70    {"cross",			SELECTOR,    @"crosshairCursor"},
71    {"crosshair",		SELECTOR,    @"crosshairCursor"},
72    {"cross-hair",		SELECTOR,    @"crosshairCursor"},
73    {"tcross",			SELECTOR,    @"crosshairCursor"},
74    {"hand",			SELECTOR,    @"openHandCursor"},
75    {"openhand",		SELECTOR,    @"openHandCursor"},
76    {"closedhand",		SELECTOR,    @"closedHandCursor"},
77    {"fist",			SELECTOR,    @"closedHandCursor"},
78    {"pointinghand",		SELECTOR,    @"pointingHandCursor"},
79    {"resize",			SELECTOR,    @"arrowCursor"},
80    {"resizeleft",		SELECTOR,    @"resizeLeftCursor"},
81    {"resizeright",		SELECTOR,    @"resizeRightCursor"},
82    {"resizeleftright",		SELECTOR,    @"resizeLeftRightCursor"},
83    {"resizeup",		SELECTOR,    @"resizeUpCursor"},
84    {"resizedown",		SELECTOR,    @"resizeDownCursor"},
85    {"resizeupdown",		SELECTOR,    @"resizeUpDownCursor"},
86    {"resizebottomleft",	SELECTOR,    @"_bottomLeftResizeCursor"},
87    {"resizetopleft",		SELECTOR,    @"_topLeftResizeCursor"},
88    {"resizebottomright",	SELECTOR,    @"_bottomRightResizeCursor"},
89    {"resizetopright",		SELECTOR,    @"_topRightResizeCursor"},
90    {"notallowed",		SELECTOR,    @"operationNotAllowedCursor"},
91    {"poof",			SELECTOR,    @"disappearingItemCursor"},
92    {"wait",			SELECTOR,    @"busyButClickableCursor"},
93    {"spinning",		SELECTOR,    @"busyButClickableCursor"},
94    {"countinguphand",		SELECTOR,    @"busyButClickableCursor"},
95    {"countingdownhand",	SELECTOR,    @"busyButClickableCursor"},
96    {"countingupanddownhand",	SELECTOR,    @"busyButClickableCursor"},
97    {"help",			IMAGENAMED,  @"NSHelpCursor", nil, {8, 8}},
98//  {"hand",			IMAGEBITMAP, MacCursorData(hand)},
99    {"bucket",			IMAGEBITMAP, MacCursorData(bucket)},
100    {"cancel",			IMAGEBITMAP, MacCursorData(cancel)},
101//  {"resize",			IMAGEBITMAP, MacCursorData(resize)},
102    {"eyedrop",			IMAGEBITMAP, MacCursorData(eyedrop)},
103    {"eyedrop-full",		IMAGEBITMAP, MacCursorData(eyedrop_full)},
104    {"zoom-in",			IMAGEBITMAP, MacCursorData(zoom_in)},
105    {"zoom-out",		IMAGEBITMAP, MacCursorData(zoom_out)},
106    {"X_cursor",		IMAGEBITMAP, MacXCursorData(X_cursor)},
107//  {"arrow",			IMAGEBITMAP, MacXCursorData(arrow)},
108    {"based_arrow_down",	IMAGEBITMAP, MacXCursorData(based_arrow_down)},
109    {"based_arrow_up",		IMAGEBITMAP, MacXCursorData(based_arrow_up)},
110    {"boat",			IMAGEBITMAP, MacXCursorData(boat)},
111    {"bogosity",		IMAGEBITMAP, MacXCursorData(bogosity)},
112    {"bottom_left_corner",	IMAGEBITMAP, MacXCursorData(bottom_left_corner)},
113    {"bottom_right_corner",	IMAGEBITMAP, MacXCursorData(bottom_right_corner)},
114    {"bottom_side",		IMAGEBITMAP, MacXCursorData(bottom_side)},
115    {"bottom_tee",		IMAGEBITMAP, MacXCursorData(bottom_tee)},
116    {"box_spiral",		IMAGEBITMAP, MacXCursorData(box_spiral)},
117    {"center_ptr",		IMAGEBITMAP, MacXCursorData(center_ptr)},
118    {"circle",			IMAGEBITMAP, MacXCursorData(circle)},
119    {"clock",			IMAGEBITMAP, MacXCursorData(clock)},
120    {"coffee_mug",		IMAGEBITMAP, MacXCursorData(coffee_mug)},
121//  {"cross",			IMAGEBITMAP, MacXCursorData(cross)},
122    {"cross_reverse",		IMAGEBITMAP, MacXCursorData(cross_reverse)},
123//  {"crosshair",		IMAGEBITMAP, MacXCursorData(crosshair)},
124    {"diamond_cross",		IMAGEBITMAP, MacXCursorData(diamond_cross)},
125    {"dot",			IMAGEBITMAP, MacXCursorData(dot)},
126    {"dotbox",			IMAGEBITMAP, MacXCursorData(dotbox)},
127    {"double_arrow",		IMAGEBITMAP, MacXCursorData(double_arrow)},
128    {"draft_large",		IMAGEBITMAP, MacXCursorData(draft_large)},
129    {"draft_small",		IMAGEBITMAP, MacXCursorData(draft_small)},
130    {"draped_box",		IMAGEBITMAP, MacXCursorData(draped_box)},
131    {"exchange",		IMAGEBITMAP, MacXCursorData(exchange)},
132    {"fleur",			IMAGEBITMAP, MacXCursorData(fleur)},
133    {"gobbler",			IMAGEBITMAP, MacXCursorData(gobbler)},
134    {"gumby",			IMAGEBITMAP, MacXCursorData(gumby)},
135    {"hand1",			IMAGEBITMAP, MacXCursorData(hand1)},
136    {"hand2",			IMAGEBITMAP, MacXCursorData(hand2)},
137    {"heart",			IMAGEBITMAP, MacXCursorData(heart)},
138    {"icon",			IMAGEBITMAP, MacXCursorData(icon)},
139    {"iron_cross",		IMAGEBITMAP, MacXCursorData(iron_cross)},
140//  {"left_ptr",		IMAGEBITMAP, MacXCursorData(left_ptr)},
141    {"left_side",		IMAGEBITMAP, MacXCursorData(left_side)},
142    {"left_tee",		IMAGEBITMAP, MacXCursorData(left_tee)},
143    {"leftbutton",		IMAGEBITMAP, MacXCursorData(leftbutton)},
144    {"ll_angle",		IMAGEBITMAP, MacXCursorData(ll_angle)},
145    {"lr_angle",		IMAGEBITMAP, MacXCursorData(lr_angle)},
146    {"man",			IMAGEBITMAP, MacXCursorData(man)},
147    {"middlebutton",		IMAGEBITMAP, MacXCursorData(middlebutton)},
148    {"mouse",			IMAGEBITMAP, MacXCursorData(mouse)},
149    {"pencil",			IMAGEBITMAP, MacXCursorData(pencil)},
150    {"pirate",			IMAGEBITMAP, MacXCursorData(pirate)},
151    {"plus",			IMAGEBITMAP, MacXCursorData(plus)},
152    {"question_arrow",		IMAGEBITMAP, MacXCursorData(question_arrow)},
153    {"right_ptr",		IMAGEBITMAP, MacXCursorData(right_ptr)},
154    {"right_side",		IMAGEBITMAP, MacXCursorData(right_side)},
155    {"right_tee",		IMAGEBITMAP, MacXCursorData(right_tee)},
156    {"rightbutton",		IMAGEBITMAP, MacXCursorData(rightbutton)},
157    {"rtl_logo",		IMAGEBITMAP, MacXCursorData(rtl_logo)},
158    {"sailboat",		IMAGEBITMAP, MacXCursorData(sailboat)},
159    {"sb_down_arrow",		IMAGEBITMAP, MacXCursorData(sb_down_arrow)},
160    {"sb_h_double_arrow",	IMAGEBITMAP, MacXCursorData(sb_h_double_arrow)},
161    {"sb_left_arrow",		IMAGEBITMAP, MacXCursorData(sb_left_arrow)},
162    {"sb_right_arrow",		IMAGEBITMAP, MacXCursorData(sb_right_arrow)},
163    {"sb_up_arrow",		IMAGEBITMAP, MacXCursorData(sb_up_arrow)},
164    {"sb_v_double_arrow",	IMAGEBITMAP, MacXCursorData(sb_v_double_arrow)},
165    {"shuttle",			IMAGEBITMAP, MacXCursorData(shuttle)},
166    {"sizing",			IMAGEBITMAP, MacXCursorData(sizing)},
167    {"spider",			IMAGEBITMAP, MacXCursorData(spider)},
168    {"spraycan",		IMAGEBITMAP, MacXCursorData(spraycan)},
169    {"star",			IMAGEBITMAP, MacXCursorData(star)},
170    {"target",			IMAGEBITMAP, MacXCursorData(target)},
171//  {"tcross",			IMAGEBITMAP, MacXCursorData(tcross)},
172//  {"top_left_arrow",		IMAGEBITMAP, MacXCursorData(top_left_arrow)},
173    {"top_left_corner",		IMAGEBITMAP, MacXCursorData(top_left_corner)},
174    {"top_right_corner",	IMAGEBITMAP, MacXCursorData(top_right_corner)},
175    {"top_side",		IMAGEBITMAP, MacXCursorData(top_side)},
176    {"top_tee",			IMAGEBITMAP, MacXCursorData(top_tee)},
177    {"trek",			IMAGEBITMAP, MacXCursorData(trek)},
178    {"ul_angle",		IMAGEBITMAP, MacXCursorData(ul_angle)},
179    {"umbrella",		IMAGEBITMAP, MacXCursorData(umbrella)},
180    {"ur_angle",		IMAGEBITMAP, MacXCursorData(ur_angle)},
181    {"watch",			IMAGEBITMAP, MacXCursorData(watch)},
182//  {"xterm",			IMAGEBITMAP, MacXCursorData(xterm)},
183    {NULL}
184};
185
186/*
187 * Declarations of static variables used in this file.
188 */
189
190static TkMacOSXCursor * gCurrentCursor = NULL;
191				/* A pointer to the current cursor. */
192static int gResizeOverride = false;
193				/* A boolean indicating whether we should use
194				 * the resize cursor during installations. */
195static int gTkOwnsCursor = true;/* A boolean indicating whether Tk owns the
196				 * cursor. If not (for instance, in the case
197				 * where a Tk window is embedded in another
198				 * app's window, and the cursor is out of the
199				 * tk window, we will not attempt to adjust
200				 * the cursor. */
201
202/*
203 * Declarations of procedures local to this file
204 */
205
206static void FindCursorByName(TkMacOSXCursor *macCursorPtr, const char *string);
207
208/*
209 *----------------------------------------------------------------------
210 *
211 * FindCursorByName --
212 *
213 *	Retrieve a system cursor by name, and fill the macCursorPtr
214 *	structure. If the cursor cannot be found, the macCursor field
215 *	will be nil.
216 *
217 * Results:
218 *	Fills the macCursorPtr record.
219 *
220 * Side effects:
221 *	None
222 *
223 *----------------------------------------------------------------------
224 */
225
226void
227FindCursorByName(
228    TkMacOSXCursor *macCursorPtr,
229    const char *name)
230{
231    NSString *path = nil;
232    NSImage *image = nil;
233    NSPoint hotSpot = NSZeroPoint;
234    int haveHotSpot = 0, result = TCL_ERROR;
235    NSCursor *macCursor = nil;
236
237    if (name[0] == '@') {
238	/*
239	 * System cursor of type @filename
240	 */
241
242	macCursorPtr->type = IMAGEPATH;
243	path = [NSString stringWithUTF8String:&name[1]];
244    } else {
245	Tcl_Obj *strPtr = Tcl_NewStringObj(name, -1);
246	int idx;
247
248	result = Tcl_GetIndexFromObjStruct(NULL, strPtr, cursorNames,
249		    sizeof(struct CursorName), NULL, TCL_EXACT, &idx);
250	Tcl_DecrRefCount(strPtr);
251	if (result == TCL_OK) {
252	    macCursorPtr->type = cursorNames[idx].kind;
253	    switch (cursorNames[idx].kind) {
254	    case SELECTOR: {
255		SEL selector = NSSelectorFromString(cursorNames[idx].id1);
256		if ([NSCursor respondsToSelector:selector]) {
257		    macCursor = [[NSCursor performSelector:selector] retain];
258		} else if (cursorNames[idx].id2) {
259		    selector = NSSelectorFromString(cursorNames[idx].id2);
260		    if ([NSCursor respondsToSelector:selector]) {
261			macCursor = [[NSCursor performSelector:selector] retain];
262		    }
263		}
264		break;
265	    }
266	    case IMAGENAMED:
267		image = [[NSImage imageNamed:cursorNames[idx].id1] retain];
268		hotSpot = cursorNames[idx].hotspot;
269		haveHotSpot = 1;
270		break;
271	    case IMAGEPATH:
272		path = [NSApp tkFrameworkImagePath:cursorNames[idx].id1];
273		break;
274	    case IMAGEBITMAP: {
275		unsigned char *bitmap = (unsigned char *)(cursorNames[idx].id1);
276		NSBitmapImageRep *bitmapImageRep = NULL;
277		CGImageRef img = NULL, mask = NULL, maskedImg = NULL;
278		static const CGFloat decodeWB[] = {1, 0};
279		CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(
280			kCGColorSpaceGenericGray);
281		CGDataProviderRef provider = CGDataProviderCreateWithData(NULL,
282			bitmap, pix*pix/8, NULL);
283		if (provider) {
284		    img = CGImageCreate(pix, pix, 1, 1, pix/8, colorspace,
285			    kCGBitmapByteOrderDefault, provider, decodeWB, 0,
286			    kCGRenderingIntentDefault);
287		    CFRelease(provider);
288		}
289		provider = CGDataProviderCreateWithData(NULL, bitmap +
290			pix*pix/8, pix*pix/8, NULL);
291		if (provider) {
292		    mask = CGImageMaskCreate(pix, pix, 1, 1, pix/8, provider,
293			    decodeWB, 0);
294		    CFRelease(provider);
295		}
296		if (img && mask) {
297		    maskedImg = CGImageCreateWithMask(img, mask);
298		}
299		if (maskedImg) {
300		    bitmapImageRep = [[NSBitmapImageRep alloc]
301			    initWithCGImage:maskedImg];
302		    CFRelease(maskedImg);
303		}
304		if (mask) { CFRelease(mask); }
305		if (img)  { CFRelease(img); }
306		if (colorspace) { CFRelease(colorspace); }
307		if (bitmapImageRep) {
308		    image = [[NSImage alloc] initWithSize:NSMakeSize(pix, pix)];
309		    [image addRepresentation:bitmapImageRep];
310		    [bitmapImageRep release];
311		}
312		uint16_t *hotSpotData = (uint16_t*)(bitmap + 2*pix*pix/8);
313		hotSpot.y = CFSwapInt16BigToHost(*hotSpotData++);
314		hotSpot.x = CFSwapInt16BigToHost(*hotSpotData);
315		haveHotSpot = 1;
316		break;
317	    }
318	    }
319	}
320    }
321    if (path) {
322	image = [[NSImage alloc] initWithContentsOfFile:path];
323    }
324    if (!image && !macCursor && result != TCL_OK) {
325	macCursorPtr->type = IMAGENAMED;
326	image = [[NSImage imageNamed:[NSString stringWithUTF8String:name]]
327		retain];
328	haveHotSpot = 0;
329    }
330    if (image) {
331	if (!haveHotSpot && [[path pathExtension] isEqualToString:@"cur"]) {
332	    NSData *data = [NSData dataWithContentsOfFile:path];
333	    if ([data length] > 14) {
334		uint16_t *hotSpotData = (uint16_t*)((char*) [data bytes] + 10);
335		hotSpot.x = CFSwapInt16LittleToHost(*hotSpotData++);
336		hotSpot.y = CFSwapInt16LittleToHost(*hotSpotData);
337		haveHotSpot = 1;
338	    }
339	}
340	if (!haveHotSpot) {
341	    NSSize size = [image size];
342	    hotSpot.x = size.width * 0.5;
343	    hotSpot.y = size.height * 0.5;
344	}
345	hotSpot.y = -hotSpot.y;
346	macCursor = [[NSCursor alloc] initWithImage:image hotSpot:hotSpot];
347	[image release];
348    }
349    macCursorPtr->macCursor = TkMacOSXMakeUncollectable(macCursor);
350}
351
352/*
353 *----------------------------------------------------------------------
354 *
355 * TkGetCursorByName --
356 *
357 *	Retrieve a system cursor by name.
358 *
359 * Results:
360 *	Returns a new cursor, or NULL on errors.
361 *
362 * Side effects:
363 *	Allocates a new cursor.
364 *
365 *----------------------------------------------------------------------
366 */
367
368TkCursor *
369TkGetCursorByName(
370    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
371    Tk_Window tkwin,		/* Window in which cursor will be used. */
372    Tk_Uid string)		/* Description of cursor. See manual entry
373				 * for details on legal syntax. */
374{
375    TkMacOSXCursor *macCursorPtr = NULL;
376    const char **argv = NULL;
377    int argc;
378
379    /*
380     * All cursor names are valid lists of one element (for
381     * TkX11-compatibility), even unadorned system cursor names.
382     */
383
384    if (Tcl_SplitList(interp, string, &argc, &argv) == TCL_OK) {
385	if (argc) {
386	    macCursorPtr = (TkMacOSXCursor *) ckalloc(sizeof(TkMacOSXCursor));
387	    macCursorPtr->info.cursor = (Tk_Cursor) macCursorPtr;
388	    macCursorPtr->macCursor = nil;
389	    macCursorPtr->type = 0;
390	    FindCursorByName(macCursorPtr, argv[0]);
391	}
392	ckfree((char *) argv);
393    }
394    if (!macCursorPtr || (!macCursorPtr->macCursor &&
395	    macCursorPtr->type != NONE)) {
396	Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"", NULL);
397	if (macCursorPtr) {
398	    ckfree((char *)macCursorPtr);
399	    macCursorPtr = NULL;
400	}
401    }
402    return (TkCursor *) macCursorPtr;
403}
404
405/*
406 *----------------------------------------------------------------------
407 *
408 * TkCreateCursorFromData --
409 *
410 *	Creates a cursor from the source and mask bits.
411 *
412 * Results:
413 *	Returns a new cursor, or NULL on errors.
414 *
415 * Side effects:
416 *	Allocates a new cursor.
417 *
418 *----------------------------------------------------------------------
419 */
420
421TkCursor *
422TkCreateCursorFromData(
423    Tk_Window tkwin,		/* Window in which cursor will be used. */
424    const char *source,		/* Bitmap data for cursor shape. */
425    const char *mask,		/* Bitmap data for cursor mask. */
426    int width, int height,	/* Dimensions of cursor. */
427    int xHot, int yHot,		/* Location of hot-spot in cursor. */
428    XColor fgColor,		/* Foreground color for cursor. */
429    XColor bgColor)		/* Background color for cursor. */
430{
431    return NULL;
432}
433
434/*
435 *----------------------------------------------------------------------
436 *
437 * TkpFreeCursor --
438 *
439 *	This procedure is called to release a cursor allocated by
440 *	TkGetCursorByName.
441 *
442 * Results:
443 *	None.
444 *
445 * Side effects:
446 *	The cursor data structure is deallocated.
447 *
448 *----------------------------------------------------------------------
449 */
450
451void
452TkpFreeCursor(
453    TkCursor *cursorPtr)
454{
455    TkMacOSXCursor *macCursorPtr = (TkMacOSXCursor *) cursorPtr;
456
457    TkMacOSXMakeCollectableAndRelease(macCursorPtr->macCursor);
458    if (macCursorPtr == gCurrentCursor) {
459	gCurrentCursor = NULL;
460    }
461}
462
463/*
464 *----------------------------------------------------------------------
465 *
466 * TkMacOSXInstallCursor --
467 *
468 *	Installs either the current cursor as defined by TkpSetCursor or a
469 *	resize cursor as the cursor the Macintosh should currently display.
470 *
471 * Results:
472 *	None.
473 *
474 * Side effects:
475 *	Changes the Macintosh mouse cursor.
476 *
477 *----------------------------------------------------------------------
478 */
479
480void
481TkMacOSXInstallCursor(
482    int resizeOverride)
483{
484    TkMacOSXCursor *macCursorPtr = gCurrentCursor;
485    static int cursorHidden = 0;
486    int cursorNone = 0;
487
488    gResizeOverride = resizeOverride;
489
490    if (resizeOverride || !macCursorPtr) {
491	[[NSCursor arrowCursor] set];
492    } else {
493	switch (macCursorPtr->type) {
494	case NONE:
495	    if (!cursorHidden) {
496		cursorHidden = 1;
497		[NSCursor hide];
498	    }
499	    cursorNone = 1;
500	    break;
501	case SELECTOR:
502	case IMAGENAMED:
503	case IMAGEPATH:
504	case IMAGEBITMAP:
505	default:
506	    [macCursorPtr->macCursor set];
507	    break;
508	}
509    }
510    if (cursorHidden && !cursorNone) {
511	cursorHidden = 0;
512	[NSCursor unhide];
513    }
514}
515
516/*
517 *----------------------------------------------------------------------
518 *
519 * TkpSetCursor --
520 *
521 *	Set the current cursor and install it.
522 *
523 * Results:
524 *	None.
525 *
526 * Side effects:
527 *	Changes the current cursor.
528 *
529 *----------------------------------------------------------------------
530 */
531
532void
533TkpSetCursor(
534    TkpCursor cursor)
535{
536    int cursorChanged = 1;
537
538    if (!gTkOwnsCursor) {
539	return;
540    }
541
542    if (cursor == None) {
543	/*
544	 * This is a little tricky. We can't really tell whether
545	 * gCurrentCursor is NULL because it was NULL last time around or
546	 * because we just freed the current cursor. So if the input cursor is
547	 * NULL, we always need to reset it, we can't trust the cursorChanged
548	 * logic.
549	 */
550
551	gCurrentCursor = NULL;
552    } else {
553	if (gCurrentCursor == (TkMacOSXCursor *) cursor) {
554	    cursorChanged = 0;
555	}
556	gCurrentCursor = (TkMacOSXCursor *) cursor;
557    }
558
559    if (Tk_MacOSXIsAppInFront() && cursorChanged) {
560	TkMacOSXInstallCursor(gResizeOverride);
561    }
562}
563
564/*
565 *----------------------------------------------------------------------
566 *
567 * Tk_MacOSXTkOwnsCursor --
568 *
569 *	Sets whether Tk has the right to adjust the cursor.
570 *
571 * Results:
572 *	None.
573 *
574 * Side effects:
575 *	May keep Tk from changing the cursor.
576 *
577 *----------------------------------------------------------------------
578 */
579
580void
581Tk_MacOSXTkOwnsCursor(
582    int tkOwnsIt)
583{
584    gTkOwnsCursor = tkOwnsIt;
585}
586
587/*
588 * Local Variables:
589 * mode: c
590 * c-basic-offset: 4
591 * fill-column: 79
592 * coding: utf-8
593 * End:
594 */
595