/* * tkMacCursor.c -- * * This file contains Macintosh specific cursor related routines. * * Copyright (c) 1995-1997 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkMacCursor.c,v 1.7 2002/08/05 04:30:40 dgp Exp $ */ #include "tkPort.h" #include "tkInt.h" #include "tkMacInt.h" #include #include #include /* * There are three different ways to set the cursor on the Mac. */ #define ARROW 0 /* The arrow cursor. */ #define COLOR 1 /* Cursors of type crsr. */ #define NORMAL 2 /* Cursors of type CURS. */ /* * The following data structure contains the system specific data * necessary to control Windows cursors. */ typedef struct { TkCursor info; /* Generic cursor info used by tkCursor.c */ Handle macCursor; /* Resource containing Macintosh cursor. */ int type; /* Type of Mac cursor: arrow, crsr, CURS */ } TkMacCursor; /* * The table below is used to map from the name of a predefined cursor * to its resource identifier. */ static struct CursorName { char *name; int id; } cursorNames[] = { {"ibeam", 1}, {"text", 1}, {"xterm", 1}, {"cross", 2}, {"crosshair", 2}, {"cross-hair", 2}, {"plus", 3}, {"watch", 4}, {"arrow", 5}, {NULL, 0} }; /* * Declarations of static variables used in this file. */ static TkMacCursor * gCurrentCursor = NULL; /* A pointer to the current * cursor. */ static int gResizeOverride = false; /* A boolean indicating whether * we should use the resize * cursor during installations. */ static int gTkOwnsCursor = true; /* A boolean indicating whether Tk owns the cursor. If not (for instance, in the case where a Tk window is embedded in another app's window, and the cursor is out of the tk window, we will not attempt to adjust the cursor */ /* * Declarations of procedures local to this file */ static void FindCursorByName _ANSI_ARGS_ ((TkMacCursor *macCursorPtr, CONST char *string)); /* *---------------------------------------------------------------------- * * FindCursorByName -- * * Retrieve a system cursor by name, and fill the macCursorPtr * structure. If the cursor cannot be found, the macCursor field * will be NULL. The function first attempts to load a color * cursor. If that fails it will attempt to load a black & white * cursor. * * Results: * Fills the macCursorPtr record. * * Side effects: * None * *---------------------------------------------------------------------- */ void FindCursorByName( TkMacCursor *macCursorPtr, CONST char *string) { Handle resource; Str255 curName; int destWrote, inCurLen; inCurLen = strlen(string); if (inCurLen > 255) { return; } /* * macRoman is the encoding that the resource fork uses. */ Tcl_UtfToExternal(NULL, Tcl_GetEncoding(NULL, "macRoman"), string, inCurLen, 0, NULL, (char *) &curName[1], 255, NULL, &destWrote, NULL); /* Internalize native */ curName[0] = destWrote; resource = GetNamedResource('crsr', curName); if (resource != NULL) { short id; Str255 theName; ResType theType; HLock(resource); GetResInfo(resource, &id, &theType, theName); HUnlock(resource); macCursorPtr->macCursor = (Handle) GetCCursor(id); macCursorPtr->type = COLOR; } if (resource == NULL) { macCursorPtr->macCursor = GetNamedResource('CURS', curName); macCursorPtr->type = NORMAL; } } /* *---------------------------------------------------------------------- * * TkGetCursorByName -- * * Retrieve a system cursor by name. * * Results: * Returns a new cursor, or NULL on errors. * * Side effects: * Allocates a new cursor. * *---------------------------------------------------------------------- */ TkCursor * TkGetCursorByName( Tcl_Interp *interp, /* Interpreter to use for error reporting. */ Tk_Window tkwin, /* Window in which cursor will be used. */ Tk_Uid string) /* Description of cursor. See manual entry * for details on legal syntax. */ { struct CursorName *namePtr; TkMacCursor *macCursorPtr; macCursorPtr = (TkMacCursor *) ckalloc(sizeof(TkMacCursor)); macCursorPtr->info.cursor = (Tk_Cursor) macCursorPtr; /* * To find a cursor we must first determine if it is one of the * builtin cursors or the standard arrow cursor. Otherwise, we * attempt to load the cursor as a named Mac resource. */ for (namePtr = cursorNames; namePtr->name != NULL; namePtr++) { if (strcmp(namePtr->name, string) == 0) { break; } } if (namePtr->name != NULL) { if (namePtr->id == 5) { macCursorPtr->macCursor = (Handle) -1; macCursorPtr->type = ARROW; } else { macCursorPtr->macCursor = (Handle) GetCursor(namePtr->id); macCursorPtr->type = NORMAL; } } else { FindCursorByName(macCursorPtr, string); if (macCursorPtr->macCursor == NULL) { CONST char **argv; int argc, err; /* * The user may be trying to specify an XCursor with fore * & back colors. We don't want this to be an error, so pick * off the first word, and try again. */ err = Tcl_SplitList(interp, string, &argc, &argv); if (err == TCL_OK ) { if (argc > 1) { FindCursorByName(macCursorPtr, argv[0]); } ckfree((char *) argv); } } } if (macCursorPtr->macCursor == NULL) { ckfree((char *)macCursorPtr); Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"", (char *) NULL); return NULL; } else { return (TkCursor *) macCursorPtr; } } /* *---------------------------------------------------------------------- * * TkCreateCursorFromData -- * * Creates a cursor from the source and mask bits. * * Results: * Returns a new cursor, or NULL on errors. * * Side effects: * Allocates a new cursor. * *---------------------------------------------------------------------- */ TkCursor * TkCreateCursorFromData( Tk_Window tkwin, /* Window in which cursor will be used. */ CONST char *source, /* Bitmap data for cursor shape. */ CONST char *mask, /* Bitmap data for cursor mask. */ int width, int height, /* Dimensions of cursor. */ int xHot, int yHot, /* Location of hot-spot in cursor. */ XColor fgColor, /* Foreground color for cursor. */ XColor bgColor) /* Background color for cursor. */ { return NULL; } /* *---------------------------------------------------------------------- * * TkpFreeCursor -- * * This procedure is called to release a cursor allocated by * TkGetCursorByName. * * Results: * None. * * Side effects: * The cursor data structure is deallocated. * *---------------------------------------------------------------------- */ void TkpFreeCursor( TkCursor *cursorPtr) { TkMacCursor *macCursorPtr = (TkMacCursor *) cursorPtr; switch (macCursorPtr->type) { case COLOR: DisposeCCursor((CCrsrHandle) macCursorPtr->macCursor); break; case NORMAL: ReleaseResource(macCursorPtr->macCursor); break; } if (macCursorPtr == gCurrentCursor) { gCurrentCursor = NULL; } } /* *---------------------------------------------------------------------- * * TkMacInstallCursor -- * * Installs either the current cursor as defined by TkpSetCursor * or a resize cursor as the cursor the Macintosh should currently * display. * * Results: * None. * * Side effects: * Changes the Macintosh mouse cursor. * *---------------------------------------------------------------------- */ void TkMacInstallCursor( int resizeOverride) { TkMacCursor *macCursorPtr = gCurrentCursor; CCrsrHandle ccursor; CursHandle cursor; gResizeOverride = resizeOverride; if (resizeOverride) { cursor = (CursHandle) GetNamedResource('CURS', "\presize"); SetCursor(*cursor); } else if (macCursorPtr == NULL || macCursorPtr->type == ARROW) { SetCursor(&tcl_macQdPtr->arrow); } else { switch (macCursorPtr->type) { case COLOR: ccursor = (CCrsrHandle) macCursorPtr->macCursor; SetCCursor(ccursor); break; case NORMAL: cursor = (CursHandle) macCursorPtr->macCursor; SetCursor(*cursor); break; } } } /* *---------------------------------------------------------------------- * * TkpSetCursor -- * * Set the current cursor and install it. * * Results: * None. * * Side effects: * Changes the current cursor. * *---------------------------------------------------------------------- */ void TkpSetCursor( TkpCursor cursor) { if (!gTkOwnsCursor) { return; } if (cursor == None) { gCurrentCursor = NULL; } else { gCurrentCursor = (TkMacCursor *) cursor; } if (tkMacAppInFront) { TkMacInstallCursor(gResizeOverride); } } /* *---------------------------------------------------------------------- * * Tk_MacTkOwnsCursor -- * * Sets whether Tk has the right to adjust the cursor. * * Results: * None. * * Side effects: * May keep Tk from changing the cursor. * *---------------------------------------------------------------------- */ void Tk_MacTkOwnsCursor( int tkOwnsIt) { gTkOwnsCursor = tkOwnsIt; }