OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [start/] [insight/] [tk/] [unix/] [tkUnixCursor.c] - Blame information for rev 579

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tkUnixCursor.c --
3
 *
4
 *      This file contains X specific cursor manipulation 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: tkUnixCursor.c,v 1.1.1.1 2002-01-16 10:26:01 markom Exp $
12
 */
13
 
14
#include "tkPort.h"
15
#include "tkInt.h"
16
 
17
/*
18
 * The following data structure is a superset of the TkCursor structure
19
 * defined in tkCursor.c.  Each system specific cursor module will define
20
 * a different cursor structure.  All of these structures must have the
21
 * same header consisting of the fields in TkCursor.
22
 */
23
 
24
 
25
 
26
typedef struct {
27
    TkCursor info;              /* Generic cursor info used by tkCursor.c */
28
    Display *display;           /* Display for which cursor is valid. */
29
} TkUnixCursor;
30
 
31
/*
32
 * The table below is used to map from the name of a cursor to its
33
 * index in the official cursor font:
34
 */
35
 
36
static struct CursorName {
37
    char                *name;
38
    unsigned int        shape;
39
} cursorNames[] = {
40
    {"X_cursor",                XC_X_cursor},
41
    {"arrow",                   XC_arrow},
42
    {"based_arrow_down",        XC_based_arrow_down},
43
    {"based_arrow_up",          XC_based_arrow_up},
44
    {"boat",                    XC_boat},
45
    {"bogosity",                XC_bogosity},
46
    {"bottom_left_corner",      XC_bottom_left_corner},
47
    {"bottom_right_corner",     XC_bottom_right_corner},
48
    {"bottom_side",             XC_bottom_side},
49
    {"bottom_tee",              XC_bottom_tee},
50
    {"box_spiral",              XC_box_spiral},
51
    {"center_ptr",              XC_center_ptr},
52
    {"circle",                  XC_circle},
53
    {"clock",                   XC_clock},
54
    {"coffee_mug",              XC_coffee_mug},
55
    {"cross",                   XC_cross},
56
    {"cross_reverse",           XC_cross_reverse},
57
    {"crosshair",               XC_crosshair},
58
    {"diamond_cross",           XC_diamond_cross},
59
    {"dot",                     XC_dot},
60
    {"dotbox",                  XC_dotbox},
61
    {"double_arrow",            XC_double_arrow},
62
    {"draft_large",             XC_draft_large},
63
    {"draft_small",             XC_draft_small},
64
    {"draped_box",              XC_draped_box},
65
    {"exchange",                XC_exchange},
66
    {"fleur",                   XC_fleur},
67
    {"gobbler",                 XC_gobbler},
68
    {"gumby",                   XC_gumby},
69
    {"hand1",                   XC_hand1},
70
    {"hand2",                   XC_hand2},
71
    {"heart",                   XC_heart},
72
    {"icon",                    XC_icon},
73
    {"iron_cross",              XC_iron_cross},
74
    {"left_ptr",                XC_left_ptr},
75
    {"left_side",               XC_left_side},
76
    {"left_tee",                XC_left_tee},
77
    {"leftbutton",              XC_leftbutton},
78
    {"ll_angle",                XC_ll_angle},
79
    {"lr_angle",                XC_lr_angle},
80
    {"man",                     XC_man},
81
    {"middlebutton",            XC_middlebutton},
82
    {"mouse",                   XC_mouse},
83
    {"pencil",                  XC_pencil},
84
    {"pirate",                  XC_pirate},
85
    {"plus",                    XC_plus},
86
    {"question_arrow",          XC_question_arrow},
87
    {"right_ptr",               XC_right_ptr},
88
    {"right_side",              XC_right_side},
89
    {"right_tee",               XC_right_tee},
90
    {"rightbutton",             XC_rightbutton},
91
    {"rtl_logo",                XC_rtl_logo},
92
    {"sailboat",                XC_sailboat},
93
    {"sb_down_arrow",           XC_sb_down_arrow},
94
    {"sb_h_double_arrow",       XC_sb_h_double_arrow},
95
    {"sb_left_arrow",           XC_sb_left_arrow},
96
    {"sb_right_arrow",          XC_sb_right_arrow},
97
    {"sb_up_arrow",             XC_sb_up_arrow},
98
    {"sb_v_double_arrow",       XC_sb_v_double_arrow},
99
    {"shuttle",                 XC_shuttle},
100
    {"sizing",                  XC_sizing},
101
    {"spider",                  XC_spider},
102
    {"spraycan",                XC_spraycan},
103
    {"star",                    XC_star},
104
    {"target",                  XC_target},
105
    {"tcross",                  XC_tcross},
106
    {"top_left_arrow",          XC_top_left_arrow},
107
    {"top_left_corner",         XC_top_left_corner},
108
    {"top_right_corner",        XC_top_right_corner},
109
    {"top_side",                XC_top_side},
110
    {"top_tee",                 XC_top_tee},
111
    {"trek",                    XC_trek},
112
    {"ul_angle",                XC_ul_angle},
113
    {"umbrella",                XC_umbrella},
114
    {"ur_angle",                XC_ur_angle},
115
    {"watch",                   XC_watch},
116
    {"xterm",                   XC_xterm},
117
    {NULL,                      0}
118
};
119
 
120
/*
121
 * Font to use for cursors:
122
 */
123
 
124
#ifndef CURSORFONT
125
#define CURSORFONT "cursor"
126
#endif
127
 
128
 
129
/*
130
 *----------------------------------------------------------------------
131
 *
132
 * TkGetCursorByName --
133
 *
134
 *      Retrieve a cursor by name.  Parse the cursor name into fields
135
 *      and create a cursor, either from the standard cursor font or
136
 *      from bitmap files.
137
 *
138
 * Results:
139
 *      Returns a new cursor, or NULL on errors.
140
 *
141
 * Side effects:
142
 *      Allocates a new cursor.
143
 *
144
 *----------------------------------------------------------------------
145
 */
146
 
147
TkCursor *
148
TkGetCursorByName(interp, tkwin, string)
149
    Tcl_Interp *interp;         /* Interpreter to use for error reporting. */
150
    Tk_Window tkwin;            /* Window in which cursor will be used. */
151
    Tk_Uid string;              /* Description of cursor.  See manual entry
152
                                 * for details on legal syntax. */
153
{
154
    TkUnixCursor *cursorPtr = NULL;
155
    Cursor cursor = None;
156
    int argc;
157
    char **argv = NULL;
158
    Pixmap source = None;
159
    Pixmap mask = None;
160
    Display *display = Tk_Display(tkwin);
161
 
162
    if (Tcl_SplitList(interp, string, &argc, &argv) != TCL_OK) {
163
        return NULL;
164
    }
165
    if (argc == 0) {
166
        goto badString;
167
    }
168
    if (argv[0][0] != '@') {
169
        XColor fg, bg;
170
        unsigned int maskIndex;
171
        register struct CursorName *namePtr;
172
        TkDisplay *dispPtr;
173
 
174
        /*
175
         * The cursor is to come from the standard cursor font.  If one
176
         * arg, it is cursor name (use black and white for fg and bg).
177
         * If two args, they are name and fg color (ignore mask).  If
178
         * three args, they are name, fg, bg.  Some of the code below
179
         * is stolen from the XCreateFontCursor Xlib procedure.
180
         */
181
 
182
        if (argc > 3) {
183
            goto badString;
184
        }
185
        for (namePtr = cursorNames; ; namePtr++) {
186
            if (namePtr->name == NULL) {
187
                goto badString;
188
            }
189
            if ((namePtr->name[0] == argv[0][0])
190
                    && (strcmp(namePtr->name, argv[0]) == 0)) {
191
                break;
192
            }
193
        }
194
        maskIndex = namePtr->shape + 1;
195
        if (argc == 1) {
196
            fg.red = fg.green = fg.blue = 0;
197
            bg.red = bg.green = bg.blue = 65535;
198
        } else {
199
            if (XParseColor(display, Tk_Colormap(tkwin), argv[1],
200
                    &fg) == 0) {
201
                Tcl_AppendResult(interp, "invalid color name \"", argv[1],
202
                        "\"", (char *) NULL);
203
                goto cleanup;
204
            }
205
            if (argc == 2) {
206
                bg.red = bg.green = bg.blue = 0;
207
                maskIndex = namePtr->shape;
208
            } else {
209
                if (XParseColor(display, Tk_Colormap(tkwin), argv[2],
210
                        &bg) == 0) {
211
                    Tcl_AppendResult(interp, "invalid color name \"", argv[2],
212
                            "\"", (char *) NULL);
213
                    goto cleanup;
214
                }
215
            }
216
        }
217
        dispPtr = ((TkWindow *) tkwin)->dispPtr;
218
        if (dispPtr->cursorFont == None) {
219
            dispPtr->cursorFont = XLoadFont(display, CURSORFONT);
220
            if (dispPtr->cursorFont == None) {
221
                interp->result = "couldn't load cursor font";
222
                goto cleanup;
223
            }
224
        }
225
        cursor = XCreateGlyphCursor(display, dispPtr->cursorFont,
226
                dispPtr->cursorFont, namePtr->shape, maskIndex,
227
                &fg, &bg);
228
    } else {
229
        int width, height, maskWidth, maskHeight;
230
        int xHot, yHot, dummy1, dummy2;
231
        XColor fg, bg;
232
 
233
        /*
234
         * Prevent file system access in safe interpreters.
235
         */
236
 
237
        if (Tcl_IsSafe(interp)) {
238
            Tcl_AppendResult(interp, "can't get cursor from a file in",
239
                    " a safe interpreter", (char *) NULL);
240
            cursorPtr = NULL;
241
            goto cleanup;
242
        }
243
 
244
        /*
245
         * The cursor is to be created by reading bitmap files.  There
246
         * should be either two elements in the list (source, color) or
247
         * four (source mask fg bg).
248
         */
249
 
250
        if ((argc != 2) && (argc != 4)) {
251
            goto badString;
252
        }
253
        if (TkReadBitmapFile(display,
254
                RootWindowOfScreen(Tk_Screen(tkwin)), &argv[0][1],
255
                (unsigned int *) &width, (unsigned int *) &height,
256
                &source, &xHot, &yHot) != BitmapSuccess) {
257
            Tcl_AppendResult(interp, "cleanup reading bitmap file \"",
258
                    &argv[0][1], "\"", (char *) NULL);
259
            goto cleanup;
260
        }
261
        if ((xHot < 0) || (yHot < 0) || (xHot >= width) || (yHot >= height)) {
262
            Tcl_AppendResult(interp, "bad hot spot in bitmap file \"",
263
                    &argv[0][1], "\"", (char *) NULL);
264
            goto cleanup;
265
        }
266
        if (argc == 2) {
267
            if (XParseColor(display, Tk_Colormap(tkwin), argv[1],
268
                    &fg) == 0) {
269
                Tcl_AppendResult(interp, "invalid color name \"",
270
                        argv[1], "\"", (char *) NULL);
271
                goto cleanup;
272
            }
273
            cursor = XCreatePixmapCursor(display, source, source,
274
                    &fg, &fg, (unsigned) xHot, (unsigned) yHot);
275
        } else {
276
            if (TkReadBitmapFile(display,
277
                    RootWindowOfScreen(Tk_Screen(tkwin)), argv[1],
278
                    (unsigned int *) &maskWidth, (unsigned int *) &maskHeight,
279
                    &mask, &dummy1, &dummy2) != BitmapSuccess) {
280
                Tcl_AppendResult(interp, "cleanup reading bitmap file \"",
281
                        argv[1], "\"", (char *) NULL);
282
                goto cleanup;
283
            }
284
            if ((maskWidth != width) && (maskHeight != height)) {
285
                interp->result =
286
                        "source and mask bitmaps have different sizes";
287
                goto cleanup;
288
            }
289
            if (XParseColor(display, Tk_Colormap(tkwin), argv[2],
290
                    &fg) == 0) {
291
                Tcl_AppendResult(interp, "invalid color name \"", argv[2],
292
                        "\"", (char *) NULL);
293
                goto cleanup;
294
            }
295
            if (XParseColor(display, Tk_Colormap(tkwin), argv[3],
296
                    &bg) == 0) {
297
                Tcl_AppendResult(interp, "invalid color name \"", argv[3],
298
                        "\"", (char *) NULL);
299
                goto cleanup;
300
            }
301
            cursor = XCreatePixmapCursor(display, source, mask,
302
                    &fg, &bg, (unsigned) xHot, (unsigned) yHot);
303
        }
304
    }
305
 
306
    if (cursor != None) {
307
        cursorPtr = (TkUnixCursor *) ckalloc(sizeof(TkUnixCursor));
308
        cursorPtr->info.cursor = (Tk_Cursor) cursor;
309
        cursorPtr->display = display;
310
    }
311
 
312
    cleanup:
313
    if (argv != NULL) {
314
        ckfree((char *) argv);
315
    }
316
    if (source != None) {
317
        Tk_FreePixmap(display, source);
318
    }
319
    if (mask != None) {
320
        Tk_FreePixmap(display, mask);
321
    }
322
    return (TkCursor *) cursorPtr;
323
 
324
 
325
    badString:
326
    Tcl_AppendResult(interp, "bad cursor spec \"", string, "\"",
327
            (char *) NULL);
328
    return NULL;
329
}
330
 
331
/*
332
 *----------------------------------------------------------------------
333
 *
334
 * TkCreateCursorFromData --
335
 *
336
 *      Creates a cursor from the source and mask bits.
337
 *
338
 * Results:
339
 *      Returns a new cursor, or NULL on errors.
340
 *
341
 * Side effects:
342
 *      Allocates a new cursor.
343
 *
344
 *----------------------------------------------------------------------
345
 */
346
 
347
TkCursor *
348
TkCreateCursorFromData(tkwin, source, mask, width, height, xHot, yHot,
349
        fgColor, bgColor)
350
    Tk_Window tkwin;            /* Window in which cursor will be used. */
351
    char *source;               /* Bitmap data for cursor shape. */
352
    char *mask;                 /* Bitmap data for cursor mask. */
353
    int width, height;          /* Dimensions of cursor. */
354
    int xHot, yHot;             /* Location of hot-spot in cursor. */
355
    XColor fgColor;             /* Foreground color for cursor. */
356
    XColor bgColor;             /* Background color for cursor. */
357
{
358
    Cursor cursor;
359
    Pixmap sourcePixmap, maskPixmap;
360
    TkUnixCursor *cursorPtr = NULL;
361
    Display *display = Tk_Display(tkwin);
362
 
363
    sourcePixmap = XCreateBitmapFromData(display,
364
            RootWindowOfScreen(Tk_Screen(tkwin)), source, (unsigned) width,
365
            (unsigned) height);
366
    maskPixmap = XCreateBitmapFromData(display,
367
            RootWindowOfScreen(Tk_Screen(tkwin)), mask, (unsigned) width,
368
            (unsigned) height);
369
    cursor = XCreatePixmapCursor(display, sourcePixmap,
370
            maskPixmap, &fgColor, &bgColor, (unsigned) xHot, (unsigned) yHot);
371
    Tk_FreePixmap(display, sourcePixmap);
372
    Tk_FreePixmap(display, maskPixmap);
373
 
374
    if (cursor != None) {
375
        cursorPtr = (TkUnixCursor *) ckalloc(sizeof(TkUnixCursor));
376
        cursorPtr->info.cursor = (Tk_Cursor) cursor;
377
        cursorPtr->display = display;
378
    }
379
    return (TkCursor *) cursorPtr;
380
}
381
 
382
/*
383
 *----------------------------------------------------------------------
384
 *
385
 * TkFreeCursor --
386
 *
387
 *      This procedure is called to release a cursor allocated by
388
 *      TkGetCursorByName.
389
 *
390
 * Results:
391
 *      None.
392
 *
393
 * Side effects:
394
 *      The cursor data structure is deallocated.
395
 *
396
 *----------------------------------------------------------------------
397
 */
398
 
399
void
400
TkFreeCursor(cursorPtr)
401
    TkCursor *cursorPtr;
402
{
403
    TkUnixCursor *unixCursorPtr = (TkUnixCursor *) cursorPtr;
404
    XFreeCursor(unixCursorPtr->display, (Cursor) unixCursorPtr->info.cursor);
405
    Tk_FreeXId(unixCursorPtr->display, (XID) unixCursorPtr->info.cursor);
406
    ckfree((char *) unixCursorPtr);
407
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.