cursor.c revision df1c27a6
1645f5050Syouri/*
2645f5050Syouri * Copyright 1989 Massachusetts Institute of Technology
30bbfda8aSnia * Copyright 1992 Claude Lecommandeur.
4645f5050Syouri */
5645f5050Syouri
6645f5050Syouri/***********************************************************************
7645f5050Syouri *
8645f5050Syouri * $XConsortium: cursor.c,v 1.10 89/12/14 14:52:23 jim Exp $
9645f5050Syouri *
10645f5050Syouri * cursor creation code
11645f5050Syouri *
120bbfda8aSnia * 05-Apr-89 Thomas E. LaStrange        File created
13645f5050Syouri *
14645f5050Syouri * Do the necessary modification to be integrated in ctwm.
15645f5050Syouri * Can no longer be used for the standard twm.
16645f5050Syouri *
17645f5050Syouri * 22-April-92 Claude Lecommandeur.
18645f5050Syouri *
19645f5050Syouri *
20645f5050Syouri ***********************************************************************/
21645f5050Syouri
220bbfda8aSnia#include "ctwm.h"
230bbfda8aSnia
24645f5050Syouri#include <stdio.h>
250bbfda8aSnia
260bbfda8aSnia#include <X11/cursorfont.h>
270bbfda8aSnia
28645f5050Syouri#include "screen.h"
29645f5050Syouri#include "cursor.h"
300bbfda8aSnia#include "image_bitmap.h"
31645f5050Syouri
32645f5050Syouristatic struct _CursorName {
330bbfda8aSnia	const char          *name;
340bbfda8aSnia	unsigned int        shape;
350bbfda8aSnia	Cursor              cursor;
36645f5050Syouri} cursor_names[] = {
37645f5050Syouri
380bbfda8aSnia	{"X_cursor",            XC_X_cursor,            None},
390bbfda8aSnia	{"arrow",               XC_arrow,               None},
400bbfda8aSnia	{"based_arrow_down",    XC_based_arrow_down,    None},
410bbfda8aSnia	{"based_arrow_up",      XC_based_arrow_up,      None},
420bbfda8aSnia	{"boat",                XC_boat,                None},
430bbfda8aSnia	{"bogosity",            XC_bogosity,            None},
440bbfda8aSnia	{"bottom_left_corner",  XC_bottom_left_corner,  None},
450bbfda8aSnia	{"bottom_right_corner", XC_bottom_right_corner, None},
460bbfda8aSnia	{"bottom_side",         XC_bottom_side,         None},
470bbfda8aSnia	{"bottom_tee",          XC_bottom_tee,          None},
480bbfda8aSnia	{"box_spiral",          XC_box_spiral,          None},
490bbfda8aSnia	{"center_ptr",          XC_center_ptr,          None},
500bbfda8aSnia	{"circle",              XC_circle,              None},
510bbfda8aSnia	{"clock",               XC_clock,               None},
520bbfda8aSnia	{"coffee_mug",          XC_coffee_mug,          None},
530bbfda8aSnia	{"cross",               XC_cross,               None},
540bbfda8aSnia	{"cross_reverse",       XC_cross_reverse,       None},
550bbfda8aSnia	{"crosshair",           XC_crosshair,           None},
560bbfda8aSnia	{"diamond_cross",       XC_diamond_cross,       None},
570bbfda8aSnia	{"dot",                 XC_dot,                 None},
580bbfda8aSnia	{"dotbox",              XC_dotbox,              None},
590bbfda8aSnia	{"double_arrow",        XC_double_arrow,        None},
600bbfda8aSnia	{"draft_large",         XC_draft_large,         None},
610bbfda8aSnia	{"draft_small",         XC_draft_small,         None},
620bbfda8aSnia	{"draped_box",          XC_draped_box,          None},
630bbfda8aSnia	{"exchange",            XC_exchange,            None},
640bbfda8aSnia	{"fleur",               XC_fleur,               None},
650bbfda8aSnia	{"gobbler",             XC_gobbler,             None},
660bbfda8aSnia	{"gumby",               XC_gumby,               None},
670bbfda8aSnia	{"hand1",               XC_hand1,               None},
680bbfda8aSnia	{"hand2",               XC_hand2,               None},
690bbfda8aSnia	{"heart",               XC_heart,               None},
700bbfda8aSnia	{"icon",                XC_icon,                None},
710bbfda8aSnia	{"iron_cross",          XC_iron_cross,          None},
720bbfda8aSnia	{"left_ptr",            XC_left_ptr,            None},
730bbfda8aSnia	{"left_side",           XC_left_side,           None},
740bbfda8aSnia	{"left_tee",            XC_left_tee,            None},
750bbfda8aSnia	{"leftbutton",          XC_leftbutton,          None},
760bbfda8aSnia	{"ll_angle",            XC_ll_angle,            None},
770bbfda8aSnia	{"lr_angle",            XC_lr_angle,            None},
780bbfda8aSnia	{"man",                 XC_man,                 None},
790bbfda8aSnia	{"middlebutton",        XC_middlebutton,        None},
800bbfda8aSnia	{"mouse",               XC_mouse,               None},
810bbfda8aSnia	{"pencil",              XC_pencil,              None},
820bbfda8aSnia	{"pirate",              XC_pirate,              None},
830bbfda8aSnia	{"plus",                XC_plus,                None},
840bbfda8aSnia	{"question_arrow",      XC_question_arrow,      None},
850bbfda8aSnia	{"right_ptr",           XC_right_ptr,           None},
860bbfda8aSnia	{"right_side",          XC_right_side,          None},
870bbfda8aSnia	{"right_tee",           XC_right_tee,           None},
880bbfda8aSnia	{"rightbutton",         XC_rightbutton,         None},
890bbfda8aSnia	{"rtl_logo",            XC_rtl_logo,            None},
900bbfda8aSnia	{"sailboat",            XC_sailboat,            None},
910bbfda8aSnia	{"sb_down_arrow",       XC_sb_down_arrow,       None},
920bbfda8aSnia	{"sb_h_double_arrow",   XC_sb_h_double_arrow,   None},
930bbfda8aSnia	{"sb_left_arrow",       XC_sb_left_arrow,       None},
940bbfda8aSnia	{"sb_right_arrow",      XC_sb_right_arrow,      None},
950bbfda8aSnia	{"sb_up_arrow",         XC_sb_up_arrow,         None},
960bbfda8aSnia	{"sb_v_double_arrow",   XC_sb_v_double_arrow,   None},
970bbfda8aSnia	{"shuttle",             XC_shuttle,             None},
980bbfda8aSnia	{"sizing",              XC_sizing,              None},
990bbfda8aSnia	{"spider",              XC_spider,              None},
1000bbfda8aSnia	{"spraycan",            XC_spraycan,            None},
1010bbfda8aSnia	{"star",                XC_star,                None},
1020bbfda8aSnia	{"target",              XC_target,              None},
1030bbfda8aSnia	{"tcross",              XC_tcross,              None},
1040bbfda8aSnia	{"top_left_arrow",      XC_top_left_arrow,      None},
1050bbfda8aSnia	{"top_left_corner",     XC_top_left_corner,     None},
1060bbfda8aSnia	{"top_right_corner",    XC_top_right_corner,    None},
1070bbfda8aSnia	{"top_side",            XC_top_side,            None},
1080bbfda8aSnia	{"top_tee",             XC_top_tee,             None},
1090bbfda8aSnia	{"trek",                XC_trek,                None},
1100bbfda8aSnia	{"ul_angle",            XC_ul_angle,            None},
1110bbfda8aSnia	{"umbrella",            XC_umbrella,            None},
1120bbfda8aSnia	{"ur_angle",            XC_ur_angle,            None},
1130bbfda8aSnia	{"watch",               XC_watch,               None},
1140bbfda8aSnia	{"xterm",               XC_xterm,               None},
115645f5050Syouri};
116645f5050Syouri
1170bbfda8aSniavoid NewFontCursor(Cursor *cp, const char *str)
118645f5050Syouri{
1190bbfda8aSnia	int i;
120df1c27a6Snia	const Display *ldpy = dpy;  // Give compiler help to hoist
1210bbfda8aSnia
1220bbfda8aSnia	for(i = 0; i < sizeof(cursor_names) / sizeof(struct _CursorName); i++) {
1230bbfda8aSnia		if(strcmp(str, cursor_names[i].name) == 0) {
124df1c27a6Snia			if(ldpy == NULL) {
125df1c27a6Snia				// No display connection, but we found it
126df1c27a6Snia				*cp = None;
127df1c27a6Snia				return;
128df1c27a6Snia			}
129df1c27a6Snia			if(cursor_names[i].cursor == None) {
1300bbfda8aSnia				cursor_names[i].cursor = XCreateFontCursor(dpy,
1310bbfda8aSnia				                         cursor_names[i].shape);
132df1c27a6Snia			}
1330bbfda8aSnia			*cp = cursor_names[i].cursor;
1340bbfda8aSnia			return;
1350bbfda8aSnia		}
136645f5050Syouri	}
1370bbfda8aSnia	fprintf(stderr, "%s:  unable to find font cursor \"%s\"\n",
1380bbfda8aSnia	        ProgramName, str);
139645f5050Syouri}
140645f5050Syouri
141645f5050Syouriint NewBitmapCursor(Cursor *cp, char *source, char *mask)
142645f5050Syouri{
1430bbfda8aSnia	XColor fore, back;
1440bbfda8aSnia	int hotx, hoty;
1450bbfda8aSnia	int sx, sy, mx, my;
1460bbfda8aSnia	unsigned int sw, sh, mw, mh;
1470bbfda8aSnia	Pixmap spm, mpm;
1480bbfda8aSnia	Colormap cmap = Scr->RootColormaps.cwins[0]->colormap->c;
1490bbfda8aSnia
150df1c27a6Snia	if(dpy == NULL) {
151df1c27a6Snia		// Handle special cases like --cfgchk
152df1c27a6Snia		*cp = None;
153df1c27a6Snia		return 0;
154df1c27a6Snia	}
155df1c27a6Snia
1560bbfda8aSnia	fore.pixel = Scr->Black;
1570bbfda8aSnia	XQueryColor(dpy, cmap, &fore);
1580bbfda8aSnia	back.pixel = Scr->White;
1590bbfda8aSnia	XQueryColor(dpy, cmap, &back);
1600bbfda8aSnia
1610bbfda8aSnia	spm = GetBitmap(source);
1620bbfda8aSnia	if((hotx = HotX) < 0) {
1630bbfda8aSnia		hotx = 0;
1640bbfda8aSnia	}
1650bbfda8aSnia	if((hoty = HotY) < 0) {
1660bbfda8aSnia		hoty = 0;
1670bbfda8aSnia	}
1680bbfda8aSnia	mpm = GetBitmap(mask);
1690bbfda8aSnia
1700bbfda8aSnia	/* make sure they are the same size */
1710bbfda8aSnia
1720bbfda8aSnia	XGetGeometry(dpy, spm, &JunkRoot, &sx, &sy, &sw, &sh, &JunkBW, &JunkDepth);
1730bbfda8aSnia	XGetGeometry(dpy, mpm, &JunkRoot, &mx, &my, &mw, &mh, &JunkBW, &JunkDepth);
1740bbfda8aSnia	if(sw != mw || sh != mh) {
1750bbfda8aSnia		fprintf(stderr,
1760bbfda8aSnia		        "%s:  cursor bitmaps \"%s\" and \"%s\" not the same size\n",
1770bbfda8aSnia		        ProgramName, source, mask);
1780bbfda8aSnia		return (1);
1790bbfda8aSnia	}
1800bbfda8aSnia	*cp = XCreatePixmapCursor(dpy, spm, mpm, &fore, &back, hotx, hoty);
1810bbfda8aSnia	return (0);
182645f5050Syouri}
183645f5050Syouri
1840bbfda8aSniaCursor MakeStringCursor(char *string)
185645f5050Syouri{
1860bbfda8aSnia	Cursor      cursor;
1870bbfda8aSnia	XColor      black, white;
1880bbfda8aSnia	Pixmap      bitmap;
1890bbfda8aSnia	unsigned int width, height, middle;
1900bbfda8aSnia	GC          gc;
1910bbfda8aSnia	Colormap    cmap = Scr->RootColormaps.cwins[0]->colormap->c;
1920bbfda8aSnia	MyFont      myfont = Scr->TitleBarFont;
1930bbfda8aSnia	XRectangle inc_rect;
1940bbfda8aSnia	XRectangle logical_rect;
1950bbfda8aSnia
1960bbfda8aSnia	black.pixel = Scr->Black;
1970bbfda8aSnia	XQueryColor(dpy, cmap, &black);
1980bbfda8aSnia	white.pixel = Scr->White;
1990bbfda8aSnia	XQueryColor(dpy, cmap, &white);
2000bbfda8aSnia
2010bbfda8aSnia	XmbTextExtents(myfont.font_set, string, strlen(string),
2020bbfda8aSnia	               &inc_rect, &logical_rect);
2030bbfda8aSnia	width  = logical_rect.width  + 4;
2040bbfda8aSnia	height = logical_rect.height + 2;
2050bbfda8aSnia	middle = myfont.ascent;
2060bbfda8aSnia	/*XQueryBestCursor (dpy, Scr->Root, width, height, &rwidth, &rheight);*/
2070bbfda8aSnia
2080bbfda8aSnia	bitmap = XCreatePixmap(dpy, Scr->Root, width, height, 1);
2090bbfda8aSnia	gc     = XCreateGC(dpy, bitmap, 0L, NULL);
2100bbfda8aSnia
2110bbfda8aSnia	XSetForeground(dpy, gc, 0L);
2120bbfda8aSnia	XFillRectangle(dpy, bitmap, gc, 0, 0, width, height);
2130bbfda8aSnia	XSetForeground(dpy, gc, 1L);
2140bbfda8aSnia	XDrawRectangle(dpy, bitmap, gc, 0, 0, width - 1, height - 1);
2150bbfda8aSnia
2160bbfda8aSnia	XmbDrawString(dpy, bitmap, myfont.font_set,
2170bbfda8aSnia	              gc, 2, middle, string, strlen(string));
2180bbfda8aSnia
2190bbfda8aSnia	cursor = XCreatePixmapCursor(dpy, bitmap, None, &black, &white, 0, 0);
2200bbfda8aSnia	XFreePixmap(dpy, bitmap);
2210bbfda8aSnia	XFreeGC(dpy, gc);
2220bbfda8aSnia	return (cursor);
223645f5050Syouri}
224