cursor.c revision df1c27a6
1/*
2 * Copyright 1989 Massachusetts Institute of Technology
3 * Copyright 1992 Claude Lecommandeur.
4 */
5
6/***********************************************************************
7 *
8 * $XConsortium: cursor.c,v 1.10 89/12/14 14:52:23 jim Exp $
9 *
10 * cursor creation code
11 *
12 * 05-Apr-89 Thomas E. LaStrange        File created
13 *
14 * Do the necessary modification to be integrated in ctwm.
15 * Can no longer be used for the standard twm.
16 *
17 * 22-April-92 Claude Lecommandeur.
18 *
19 *
20 ***********************************************************************/
21
22#include "ctwm.h"
23
24#include <stdio.h>
25
26#include <X11/cursorfont.h>
27
28#include "screen.h"
29#include "cursor.h"
30#include "image_bitmap.h"
31
32static struct _CursorName {
33	const char          *name;
34	unsigned int        shape;
35	Cursor              cursor;
36} cursor_names[] = {
37
38	{"X_cursor",            XC_X_cursor,            None},
39	{"arrow",               XC_arrow,               None},
40	{"based_arrow_down",    XC_based_arrow_down,    None},
41	{"based_arrow_up",      XC_based_arrow_up,      None},
42	{"boat",                XC_boat,                None},
43	{"bogosity",            XC_bogosity,            None},
44	{"bottom_left_corner",  XC_bottom_left_corner,  None},
45	{"bottom_right_corner", XC_bottom_right_corner, None},
46	{"bottom_side",         XC_bottom_side,         None},
47	{"bottom_tee",          XC_bottom_tee,          None},
48	{"box_spiral",          XC_box_spiral,          None},
49	{"center_ptr",          XC_center_ptr,          None},
50	{"circle",              XC_circle,              None},
51	{"clock",               XC_clock,               None},
52	{"coffee_mug",          XC_coffee_mug,          None},
53	{"cross",               XC_cross,               None},
54	{"cross_reverse",       XC_cross_reverse,       None},
55	{"crosshair",           XC_crosshair,           None},
56	{"diamond_cross",       XC_diamond_cross,       None},
57	{"dot",                 XC_dot,                 None},
58	{"dotbox",              XC_dotbox,              None},
59	{"double_arrow",        XC_double_arrow,        None},
60	{"draft_large",         XC_draft_large,         None},
61	{"draft_small",         XC_draft_small,         None},
62	{"draped_box",          XC_draped_box,          None},
63	{"exchange",            XC_exchange,            None},
64	{"fleur",               XC_fleur,               None},
65	{"gobbler",             XC_gobbler,             None},
66	{"gumby",               XC_gumby,               None},
67	{"hand1",               XC_hand1,               None},
68	{"hand2",               XC_hand2,               None},
69	{"heart",               XC_heart,               None},
70	{"icon",                XC_icon,                None},
71	{"iron_cross",          XC_iron_cross,          None},
72	{"left_ptr",            XC_left_ptr,            None},
73	{"left_side",           XC_left_side,           None},
74	{"left_tee",            XC_left_tee,            None},
75	{"leftbutton",          XC_leftbutton,          None},
76	{"ll_angle",            XC_ll_angle,            None},
77	{"lr_angle",            XC_lr_angle,            None},
78	{"man",                 XC_man,                 None},
79	{"middlebutton",        XC_middlebutton,        None},
80	{"mouse",               XC_mouse,               None},
81	{"pencil",              XC_pencil,              None},
82	{"pirate",              XC_pirate,              None},
83	{"plus",                XC_plus,                None},
84	{"question_arrow",      XC_question_arrow,      None},
85	{"right_ptr",           XC_right_ptr,           None},
86	{"right_side",          XC_right_side,          None},
87	{"right_tee",           XC_right_tee,           None},
88	{"rightbutton",         XC_rightbutton,         None},
89	{"rtl_logo",            XC_rtl_logo,            None},
90	{"sailboat",            XC_sailboat,            None},
91	{"sb_down_arrow",       XC_sb_down_arrow,       None},
92	{"sb_h_double_arrow",   XC_sb_h_double_arrow,   None},
93	{"sb_left_arrow",       XC_sb_left_arrow,       None},
94	{"sb_right_arrow",      XC_sb_right_arrow,      None},
95	{"sb_up_arrow",         XC_sb_up_arrow,         None},
96	{"sb_v_double_arrow",   XC_sb_v_double_arrow,   None},
97	{"shuttle",             XC_shuttle,             None},
98	{"sizing",              XC_sizing,              None},
99	{"spider",              XC_spider,              None},
100	{"spraycan",            XC_spraycan,            None},
101	{"star",                XC_star,                None},
102	{"target",              XC_target,              None},
103	{"tcross",              XC_tcross,              None},
104	{"top_left_arrow",      XC_top_left_arrow,      None},
105	{"top_left_corner",     XC_top_left_corner,     None},
106	{"top_right_corner",    XC_top_right_corner,    None},
107	{"top_side",            XC_top_side,            None},
108	{"top_tee",             XC_top_tee,             None},
109	{"trek",                XC_trek,                None},
110	{"ul_angle",            XC_ul_angle,            None},
111	{"umbrella",            XC_umbrella,            None},
112	{"ur_angle",            XC_ur_angle,            None},
113	{"watch",               XC_watch,               None},
114	{"xterm",               XC_xterm,               None},
115};
116
117void NewFontCursor(Cursor *cp, const char *str)
118{
119	int i;
120	const Display *ldpy = dpy;  // Give compiler help to hoist
121
122	for(i = 0; i < sizeof(cursor_names) / sizeof(struct _CursorName); i++) {
123		if(strcmp(str, cursor_names[i].name) == 0) {
124			if(ldpy == NULL) {
125				// No display connection, but we found it
126				*cp = None;
127				return;
128			}
129			if(cursor_names[i].cursor == None) {
130				cursor_names[i].cursor = XCreateFontCursor(dpy,
131				                         cursor_names[i].shape);
132			}
133			*cp = cursor_names[i].cursor;
134			return;
135		}
136	}
137	fprintf(stderr, "%s:  unable to find font cursor \"%s\"\n",
138	        ProgramName, str);
139}
140
141int NewBitmapCursor(Cursor *cp, char *source, char *mask)
142{
143	XColor fore, back;
144	int hotx, hoty;
145	int sx, sy, mx, my;
146	unsigned int sw, sh, mw, mh;
147	Pixmap spm, mpm;
148	Colormap cmap = Scr->RootColormaps.cwins[0]->colormap->c;
149
150	if(dpy == NULL) {
151		// Handle special cases like --cfgchk
152		*cp = None;
153		return 0;
154	}
155
156	fore.pixel = Scr->Black;
157	XQueryColor(dpy, cmap, &fore);
158	back.pixel = Scr->White;
159	XQueryColor(dpy, cmap, &back);
160
161	spm = GetBitmap(source);
162	if((hotx = HotX) < 0) {
163		hotx = 0;
164	}
165	if((hoty = HotY) < 0) {
166		hoty = 0;
167	}
168	mpm = GetBitmap(mask);
169
170	/* make sure they are the same size */
171
172	XGetGeometry(dpy, spm, &JunkRoot, &sx, &sy, &sw, &sh, &JunkBW, &JunkDepth);
173	XGetGeometry(dpy, mpm, &JunkRoot, &mx, &my, &mw, &mh, &JunkBW, &JunkDepth);
174	if(sw != mw || sh != mh) {
175		fprintf(stderr,
176		        "%s:  cursor bitmaps \"%s\" and \"%s\" not the same size\n",
177		        ProgramName, source, mask);
178		return (1);
179	}
180	*cp = XCreatePixmapCursor(dpy, spm, mpm, &fore, &back, hotx, hoty);
181	return (0);
182}
183
184Cursor MakeStringCursor(char *string)
185{
186	Cursor      cursor;
187	XColor      black, white;
188	Pixmap      bitmap;
189	unsigned int width, height, middle;
190	GC          gc;
191	Colormap    cmap = Scr->RootColormaps.cwins[0]->colormap->c;
192	MyFont      myfont = Scr->TitleBarFont;
193	XRectangle inc_rect;
194	XRectangle logical_rect;
195
196	black.pixel = Scr->Black;
197	XQueryColor(dpy, cmap, &black);
198	white.pixel = Scr->White;
199	XQueryColor(dpy, cmap, &white);
200
201	XmbTextExtents(myfont.font_set, string, strlen(string),
202	               &inc_rect, &logical_rect);
203	width  = logical_rect.width  + 4;
204	height = logical_rect.height + 2;
205	middle = myfont.ascent;
206	/*XQueryBestCursor (dpy, Scr->Root, width, height, &rwidth, &rheight);*/
207
208	bitmap = XCreatePixmap(dpy, Scr->Root, width, height, 1);
209	gc     = XCreateGC(dpy, bitmap, 0L, NULL);
210
211	XSetForeground(dpy, gc, 0L);
212	XFillRectangle(dpy, bitmap, gc, 0, 0, width, height);
213	XSetForeground(dpy, gc, 1L);
214	XDrawRectangle(dpy, bitmap, gc, 0, 0, width - 1, height - 1);
215
216	XmbDrawString(dpy, bitmap, myfont.font_set,
217	              gc, 2, middle, string, strlen(string));
218
219	cursor = XCreatePixmapCursor(dpy, bitmap, None, &black, &white, 0, 0);
220	XFreePixmap(dpy, bitmap);
221	XFreeGC(dpy, gc);
222	return (cursor);
223}
224