13
Cursors
A cursor is an image that tracks the mouse on the display. Each window has its own cursor
which you can change. There are some cursors defined by OPEN LOOK that correspond to
specific window manager operations such as resizing or dragging windows. For these cases,
you cannot redefine a cursor. However, for windows in your application, you can assign any
cursor image you like.
13.1 Creating Cursors
To use the CURSOR package, include the header file <xview/cursor.h>. It provides the neces-
sary types and definitions for using the package. The cursor object’s type is Xv_Cursor.
Figure 13-1 shows the class hierarchy for a cursor object.
Generic
Object
Cursor
Figure 13-1. Cursor class hierarchy
In general, to create a cursor, create an image and a cursor using that image as the
CURSOR_IMAGE data:
Server_image svr_image;
Xv_Cursor cursor;
cursor = (Xv_Cursor)xv_create(owner, CURSOR,
CURSOR_IMAGE, svr_image,
NULL);
The owner of the cursor may be any XView object. The root window associated with the
XView object is used internally by the CURSOR package. If NULL, then the root window of
the default screen is used.
Cursors
Cursors 327
The cursor is then assigned to a window associated with an XView object such as a frame,
canvas, or panel:
xv_set(
window
, WIN_CURSOR, cursor, NULL);
You must supply the handle of an XView window in the parent parameter when getting
WIN_CURSOR. Getting WIN_CURSOR on the root window will return NULL. It is illegal to
assign a cursor to a window if the screens do not match. This is normally not a problem
unless you are using multiple displays in your application. In this case, you should be sure to
use an XView object that has a common display as the owner for the cursor. In the code line
above,
window
should be the visible window to the application. For canvases and panels,
this should be the paint window, not the canvas or panel object itself.* If you assign your
own cursor to an openwin object (such as a canvas or panel) and the object has been split
(either by the user splitting views or by the application), then the application is responsible
for assigning the cursor to each new paint window.
13.1.1 simple_cursor.c
To introduce how to use the
CURSOR package, we’ll start with a short program that shows
how to set the cursor for a canvas.
Example 13-1. The simple_cursor.c program
/*
* simple_cursor.c -- create a cursor (looks like an hourglass) and
* assign it to a canvas window.
*/
#include <xview/xview.h>
#include <xview/panel.h>
#include <xview/cursor.h>
#include <xview/svrimage.h>
/* data that describes the cursor’s image -- see SERVER_IMAGE below */
short cursor_bits[ ] = {
/* Width=16, Height=16, Depth=1, */
0x7FFE,0x4002,0x200C,0x1A38,0x0FF0,0x07E0,0x03C0,0x0180,
0x0180,0x0240,0x0520,0x0810,0x1108,0x23C4,0x47E2,0x7FFE
};
main(argc, argv)
int argc;
char *argv[ ];
{
Frame frame;
Canvas canvas;
Xv_Cursor cursor;
Server_image svr_image;
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
*See Chapter 5, Canvases and Openwin, for more information about the paint window.
328 XView Programming Manual
Example 13-1. The simple_cursor.c program (continued)
/*
* create a server image to use as the cursor’s image.
*/
svr_image = (Server_image)xv_create(XV_NULL, SERVER_IMAGE,
XV_WIDTH, 16,
XV_HEIGHT, 16,
SERVER_IMAGE_BITS, cursor_bits,
NULL);
/*
* create a cursor based on the image just created
*/
cursor = (Xv_Cursor)xv_create(XV_NULL, CURSOR,
CURSOR_IMAGE, svr_image,
NULL);
/*
* Create a base frame and a canvas
*/
frame = (Frame)xv_create(XV_NULL, FRAME, NULL);
canvas = (Canvas)xv_create(frame, CANVAS,
XV_WIDTH, 100,
XV_HEIGHT, 100,
NULL);
/*
* set the cursor to the paint window for the canvas
* Do not set it for the canvas itself.
*/
xv_set(xv_get(canvas, CANVAS_NTH_PAINT_WINDOW, 0),
WIN_CURSOR, cursor,
NULL);
window_fit(frame);
window_main_loop(frame);
}
Beware that if a canvas (or any openwin object) is split, the new view (which has a corre-
sponding paint window) does not inherit the cursor from the old view window.* Note that
the server images used in cursors must be one-bit deep. Cursors can have two colors associ-
ated with them by specifying foreground and background colors; you cannot specify server
images whose depths are greater than 1. See Section 13.4, “Color Cursors.”
*Chapter 5, Canvases and Openwin, discusses splitting views.
Cursors
Cursors 329
13.2 Predefined Cursors
A number of predefined cursors are available in the CURSOR package for use as OPEN LOOK
cursors. To use these cursors, you may specify the CURSOR_SRC_CHAR and
CURSOR_MASK_CHAR attributes with certain predefined constants as values for these attri-
butes. In <xview/cursor.h>, there are some OPEN LOOK cursor defines prefixed by OLC_.
When using these attributes, you should not use the CURSOR_IMAGE attribute since you can-
not use both simultaneously. Using the previous example, we can remove the
SERVER_IMAGE references and modify the call to create the cursor:
cursor = xv_create(NULL, CURSOR,
CURSOR_SRC_CHAR, OLC_BUSY_PTR,
NULL);
Predefined cursors are really images from a pre-built font. The value in the attribute-value
pair is the character to use from that font—or rather, it is the index into the array of glyphs
that the font contains. The glyph from the font is extracted and used as the image. You can
use the attribute CURSOR_MASK_CHAR similarly. This image is used as the mask for the
source image. If no mask is given, the same image used as the source is used as the mask.*
13.3 The Hotspot and Cursor Location
The hotspot on a cursor is the location in which the cursor is located if the user generates an
event like pressing a mouse button or typing at the keyboard, or if you were to query its posi-
tion. For example, if a cursor is shaped like an arrow, the hotspot should be at the tip of the
arrow. If the hotspot for a cursor were set to (0, 0), then the hotspot would be the upper-left
corner of the image used. A cursor shaped like a bull’s eye (16x16) might have its hotspot
at (7, 7) to indicate that the focus for the cursor is in the middle.† You set a cursor’s hotspot
with the attributes CURSOR_XHOT and CURSOR_YHOT. CURSOR_XHOT specifies the x coordi-
nate of the hotspot. CURSOR_YHOT specifies the y coordinate of the hotspot. You can find out
what the current position of the cursor is by using the attribute
WIN_MOUSE_XY, as in:
r = (Rect *)xv_get(
window
, WIN_MOUSE_XY);
The return value from xv_get() is a pointer to a Rect structure. The r_width and
r_height fields of this structure are unused (0, 0), but the r_top and r_left fields
indicate the position of the hotspot for the cursor with respect to the window, window. The
program in Example 13-2 demonstrates how this is used, and it shows how to create your
own pixmap for a cursor image.
*See XCreateGlyphCursor and XCreatePixmapCursor in Volume Two, Xlib Reference Manual.
†The value 7, 7 is used because the origin is at 0, 0—not 1, 1.
330 XView Programming Manual
Example 13-2. The hot_spot.c program
/*
* hot_spot.c -- create a cursor and query its position on the
* screen and in the panel’s window.
* Our own function, create_cursor(), attaches a new cursor to the
* window parameter passed into the function.
*/
#include <X11/X.h>
#include <X11/Xlib.h> /* for the xlib graphics */
#include <xview/xview.h>
#include <xview/panel.h>
#include <xview/cursor.h>
#include <xview/svrimage.h>
main(argc, argv)
int argc;
char *argv[ ];
{
Frame frame;
Panel panel;
void do_it();
xv_init(XV_INIT_ARGC_PTR_ARGV, &argc, argv, NULL);
/*
* Create a base frame, a panel, and a panel button.
*/
frame = (Frame)xv_create(XV_NULL, FRAME, NULL);
panel = (Panel)xv_create(frame, PANEL, NULL);
create_cursor(xv_get(panel, CANVAS_NTH_PAINT_WINDOW, 0));
(void) xv_create(panel, PANEL_BUTTON,
PANEL_LABEL_STRING, "Push Me",
PANEL_NOTIFY_PROC, do_it,
NULL);
window_fit(panel);
window_fit(frame);
window_main_loop(frame);
}
/*
* When user selects the panel button, the current mouse location is
* printed relative to the panel’s window and to the screen.
* This location is governed by the hot spot on the cursor.
*/
void
do_it(item, event)
{
Rect *r;
Panel panel = (Panel)xv_get(item, PANEL_PARENT_PANEL);
r = (Rect *)xv_get(xv_get(panel, XV_ROOT), WIN_MOUSE_XY);
printf("Root window: %d %d\n", r–>r_left, r–>r_top);
r = (Rect *)xv_get(xv_get(panel,
CANVAS_NTH_PAINT_WINDOW, 0), WIN_MOUSE_XY);
printf("Panel window: %d %d\n", r–>r_left, r–>r_top);
}
Cursors
Cursors 331
Get Volume 7A: XView Programming Manual now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.