1/* 2 * tkWinCursor.c -- 3 * 4 * This file contains Win32 specific cursor related routines. 5 * 6 * Copyright (c) 1995 Sun Microsystems, Inc. 7 * 8 * See the file "license.terms" for information on usage and redistribution 9 * of this file, and for a DISCLAIMER OF ALL WARRANTIES. 10 * 11 * RCS: @(#) $Id: tkWinCursor.c,v 1.10.2.2 2004/01/28 23:37:28 patthoyts Exp $ 12 */ 13 14#include "tkWinInt.h" 15 16/* 17 * The following data structure contains the system specific data 18 * necessary to control Windows cursors. 19 */ 20 21typedef struct { 22 TkCursor info; /* Generic cursor info used by tkCursor.c */ 23 HCURSOR winCursor; /* Win32 cursor handle. */ 24 int system; /* 1 if cursor is a system cursor, else 0. */ 25} TkWinCursor; 26 27/* 28 * The HAND cursor is only present when WINVER >= 0x0500. If this is 29 * not available at runtime, it will default to the unix-style cursor. 30 */ 31#ifndef IDC_HAND 32#define IDC_HAND MAKEINTRESOURCE(32649) 33#endif 34 35/* 36 * The table below is used to map from the name of a predefined cursor 37 * to its resource identifier. 38 */ 39 40static struct CursorName { 41 char *name; 42 LPCTSTR id; 43} cursorNames[] = { 44 {"starting", IDC_APPSTARTING}, 45 {"arrow", IDC_ARROW}, 46 {"ibeam", IDC_IBEAM}, 47 {"icon", IDC_ICON}, 48 {"no", IDC_NO}, 49 {"size", IDC_SIZEALL}, 50 {"size_ne_sw", IDC_SIZENESW}, 51 {"size_ns", IDC_SIZENS}, 52 {"size_nw_se", IDC_SIZENWSE}, 53 {"size_we", IDC_SIZEWE}, 54 {"uparrow", IDC_UPARROW}, 55 {"wait", IDC_WAIT}, 56 {"crosshair", IDC_CROSS}, 57 {"fleur", IDC_SIZEALL}, 58 {"sb_v_double_arrow", IDC_SIZENS}, 59 {"sb_h_double_arrow", IDC_SIZEWE}, 60 {"center_ptr", IDC_UPARROW}, 61 {"watch", IDC_WAIT}, 62 {"xterm", IDC_IBEAM}, 63 {"hand2", IDC_HAND}, 64 {NULL, 0} 65}; 66 67/* 68 * The default cursor is used whenever no other cursor has been specified. 69 */ 70 71#define TK_DEFAULT_CURSOR IDC_ARROW 72 73 74/* 75 *---------------------------------------------------------------------- 76 * 77 * TkGetCursorByName -- 78 * 79 * Retrieve a system cursor by name. 80 * 81 * Results: 82 * Returns a new cursor, or NULL on errors. 83 * 84 * Side effects: 85 * Allocates a new cursor. 86 * 87 *---------------------------------------------------------------------- 88 */ 89 90TkCursor * 91TkGetCursorByName(interp, tkwin, string) 92 Tcl_Interp *interp; /* Interpreter to use for error reporting. */ 93 Tk_Window tkwin; /* Window in which cursor will be used. */ 94 Tk_Uid string; /* Description of cursor. See manual entry 95 * for details on legal syntax. */ 96{ 97 struct CursorName *namePtr; 98 TkWinCursor *cursorPtr; 99 int argc; 100 CONST char **argv = NULL; 101 102 /* 103 * All cursor names are valid lists of one element (for 104 * Unix-compatability), even unadorned system cursor names. 105 */ 106 107 if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) { 108 return NULL; 109 } 110 if (argc == 0) { 111 goto badCursorSpec; 112 } 113 114 cursorPtr = (TkWinCursor *) ckalloc(sizeof(TkWinCursor)); 115 cursorPtr->info.cursor = (Tk_Cursor) cursorPtr; 116 cursorPtr->winCursor = NULL; 117 cursorPtr->system = 0; 118 119 if (argv[0][0] == '@') { 120 /* 121 * Check for system cursor of type @<filename>, where only 122 * the name is allowed. This accepts any of: 123 * -cursor @/winnt/cursors/globe.ani 124 * -cursor @C:/Winnt/cursors/E_arrow.cur 125 * -cursor {@C:/Program\ Files/Cursors/bart.ani} 126 * -cursor {{@C:/Program Files/Cursors/bart.ani}} 127 * -cursor [list @[file join "C:/Program Files" Cursors bart.ani]] 128 */ 129 130 if (Tcl_IsSafe(interp)) { 131 Tcl_AppendResult(interp, "can't get cursor from a file in", 132 " a safe interpreter", (char *) NULL); 133 ckfree((char *) argv); 134 ckfree((char *) cursorPtr); 135 return NULL; 136 } 137 cursorPtr->winCursor = LoadCursorFromFile(&(argv[0][1])); 138 } else { 139 /* 140 * Check for the cursor in the system cursor set. 141 */ 142 for (namePtr = cursorNames; namePtr->name != NULL; namePtr++) { 143 if (strcmp(namePtr->name, argv[0]) == 0) { 144 cursorPtr->winCursor = LoadCursor(NULL, namePtr->id); 145 break; 146 } 147 } 148 149 if (cursorPtr->winCursor == NULL) { 150 /* 151 * Hmm, it is not in the system cursor set. Check to see 152 * if it is one of our application resources. 153 */ 154 cursorPtr->winCursor = LoadCursor(Tk_GetHINSTANCE(), argv[0]); 155 } else { 156 cursorPtr->system = 1; 157 } 158 } 159 160 if (cursorPtr->winCursor == NULL) { 161 ckfree((char *) cursorPtr); 162 badCursorSpec: 163 ckfree((char *) argv); 164 Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"", 165 (char *) NULL); 166 return NULL; 167 } else { 168 ckfree((char *) argv); 169 return (TkCursor *) cursorPtr; 170 } 171} 172 173/* 174 *---------------------------------------------------------------------- 175 * 176 * TkCreateCursorFromData -- 177 * 178 * Creates a cursor from the source and mask bits. 179 * 180 * Results: 181 * Returns a new cursor, or NULL on errors. 182 * 183 * Side effects: 184 * Allocates a new cursor. 185 * 186 *---------------------------------------------------------------------- 187 */ 188 189TkCursor * 190TkCreateCursorFromData(tkwin, source, mask, width, height, xHot, yHot, 191 fgColor, bgColor) 192 Tk_Window tkwin; /* Window in which cursor will be used. */ 193 CONST char *source; /* Bitmap data for cursor shape. */ 194 CONST char *mask; /* Bitmap data for cursor mask. */ 195 int width, height; /* Dimensions of cursor. */ 196 int xHot, yHot; /* Location of hot-spot in cursor. */ 197 XColor fgColor; /* Foreground color for cursor. */ 198 XColor bgColor; /* Background color for cursor. */ 199{ 200 return NULL; 201} 202 203/* 204 *---------------------------------------------------------------------- 205 * 206 * TkpFreeCursor -- 207 * 208 * This procedure is called to release a cursor allocated by 209 * TkGetCursorByName. 210 * 211 * Results: 212 * None. 213 * 214 * Side effects: 215 * The cursor data structure is deallocated. 216 * 217 *---------------------------------------------------------------------- 218 */ 219 220void 221TkpFreeCursor(cursorPtr) 222 TkCursor *cursorPtr; 223{ 224 TkWinCursor *winCursorPtr = (TkWinCursor *) cursorPtr; 225} 226 227/* 228 *---------------------------------------------------------------------- 229 * 230 * TkpSetCursor -- 231 * 232 * Set the global cursor. If the cursor is None, then use the 233 * default Tk cursor. 234 * 235 * Results: 236 * None. 237 * 238 * Side effects: 239 * Changes the mouse cursor. 240 * 241 *---------------------------------------------------------------------- 242 */ 243 244void 245TkpSetCursor(cursor) 246 TkpCursor cursor; 247{ 248 HCURSOR hcursor; 249 TkWinCursor *winCursor = (TkWinCursor *) cursor; 250 251 if (winCursor == NULL || winCursor->winCursor == NULL) { 252 hcursor = LoadCursor(NULL, TK_DEFAULT_CURSOR); 253 } else { 254 hcursor = winCursor->winCursor; 255 } 256 257 if (hcursor != NULL) { 258 SetCursor(hcursor); 259 } 260} 261