summaryrefslogtreecommitdiffstats
path: root/macosx/tkMacOSXCursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/tkMacOSXCursor.c')
-rw-r--r--macosx/tkMacOSXCursor.c406
1 files changed, 406 insertions, 0 deletions
diff --git a/macosx/tkMacOSXCursor.c b/macosx/tkMacOSXCursor.c
new file mode 100644
index 0000000..a1bbbb4
--- /dev/null
+++ b/macosx/tkMacOSXCursor.c
@@ -0,0 +1,406 @@
+/*
+ * tkMacOSXCursor.c --
+ *
+ * This file contains Macintosh specific cursor related routines.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * RCS: @(#) $Id: tkMacOSXCursor.c,v 1.2 2002/08/31 06:12:29 das Exp $
+ */
+
+#include "tkPort.h"
+#include "tkInt.h"
+#include "tkMacOSXInt.h"
+
+#include <Carbon/Carbon.h>
+
+/*
+ * 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 */
+} TkMacOSXCursor;
+
+/*
+ * 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 TkMacOSXCursor * 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_ ((TkMacOSXCursor *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(
+ TkMacOSXCursor *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;
+ TkMacOSXCursor *macCursorPtr;
+
+ macCursorPtr = (TkMacOSXCursor *) ckalloc(sizeof(TkMacOSXCursor));
+ 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)
+{
+ TkMacOSXCursor *macCursorPtr = (TkMacOSXCursor *) cursorPtr;
+
+ switch (macCursorPtr->type) {
+ case COLOR:
+ DisposeCCursor((CCrsrHandle) macCursorPtr->macCursor);
+ break;
+ case NORMAL:
+ ReleaseResource(macCursorPtr->macCursor);
+ break;
+ }
+
+ if (macCursorPtr == gCurrentCursor) {
+ gCurrentCursor = NULL;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXInstallCursor --
+ *
+ * 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
+TkMacOSXInstallCursor(
+ int resizeOverride)
+{
+ TkMacOSXCursor *macCursorPtr = gCurrentCursor;
+ CCrsrHandle ccursor;
+ CursHandle cursor;
+
+ gResizeOverride = resizeOverride;
+
+ if (resizeOverride) {
+ cursor = (CursHandle) GetNamedResource('CURS', "\presize");
+ if (cursor) {
+ SetCursor(*cursor);
+ } else {
+ /*
+ fprintf(stderr,"Resize cursor failed, %d\n", ResError());
+ */
+ }
+ } else if (macCursorPtr == NULL || macCursorPtr->type == ARROW) {
+ SetThemeCursor(kThemeArrowCursor);
+ } 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 = (TkMacOSXCursor *) cursor;
+ }
+
+ if (Tk_MacOSXIsAppInFront()) {
+ TkMacOSXInstallCursor(gResizeOverride);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tk_MacOSXTkOwnsCursor --
+ *
+ * Sets whether Tk has the right to adjust the cursor.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May keep Tk from changing the cursor.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tk_MacOSXTkOwnsCursor(
+ int tkOwnsIt)
+{
+ gTkOwnsCursor = tkOwnsIt;
+}