Blame src/StrToCurs.c

Packit cd2a55
/*
Packit cd2a55
Packit cd2a55
Copyright 1987, 1988, 1998  The Open Group
Packit cd2a55
Packit cd2a55
Permission to use, copy, modify, distribute, and sell this software and its
Packit cd2a55
documentation for any purpose is hereby granted without fee, provided that
Packit cd2a55
the above copyright notice appear in all copies and that both that
Packit cd2a55
copyright notice and this permission notice appear in supporting
Packit cd2a55
documentation.
Packit cd2a55
Packit cd2a55
The above copyright notice and this permission notice shall be included in
Packit cd2a55
all copies or substantial portions of the Software.
Packit cd2a55
Packit cd2a55
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Packit cd2a55
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Packit cd2a55
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
Packit cd2a55
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
Packit cd2a55
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
Packit cd2a55
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Packit cd2a55
Packit cd2a55
Except as contained in this notice, the name of The Open Group shall not be
Packit cd2a55
used in advertising or otherwise to promote the sale, use or other dealings
Packit cd2a55
in this Software without prior written authorization from The Open Group.
Packit cd2a55
Packit cd2a55
*/
Packit cd2a55
Packit cd2a55
/***********************************************************
Packit cd2a55
Packit cd2a55
Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
Packit cd2a55
Packit cd2a55
                        All Rights Reserved
Packit cd2a55
Packit cd2a55
Permission to use, copy, modify, and distribute this software and its
Packit cd2a55
documentation for any purpose and without fee is hereby granted,
Packit cd2a55
provided that the above copyright notice appear in all copies and that
Packit cd2a55
both that copyright notice and this permission notice appear in
Packit cd2a55
supporting documentation, and that the name of Digital not be
Packit cd2a55
used in advertising or publicity pertaining to distribution of the
Packit cd2a55
software without specific, written prior permission.
Packit cd2a55
Packit cd2a55
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
Packit cd2a55
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
Packit cd2a55
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
Packit cd2a55
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
Packit cd2a55
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
Packit cd2a55
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
Packit cd2a55
SOFTWARE.
Packit cd2a55
Packit cd2a55
******************************************************************/
Packit cd2a55
Packit cd2a55
#ifdef HAVE_CONFIG_H
Packit cd2a55
#include <config.h>
Packit cd2a55
#endif
Packit cd2a55
#include	<X11/Intrinsic.h>
Packit cd2a55
#include	<X11/StringDefs.h>
Packit cd2a55
#include	<X11/Xmu/Converters.h>
Packit cd2a55
#include	<X11/Xmu/Drawing.h>
Packit cd2a55
#include	<X11/Xmu/CurUtil.h>
Packit cd2a55
#include	<X11/Xmu/CharSet.h>
Packit cd2a55
Packit cd2a55
#include <stdlib.h>
Packit cd2a55
Packit cd2a55
#ifdef _POSIX_SOURCE
Packit cd2a55
#include <limits.h>
Packit cd2a55
#else
Packit cd2a55
#define _POSIX_SOURCE
Packit cd2a55
#include <limits.h>
Packit cd2a55
#undef _POSIX_SOURCE
Packit cd2a55
#endif
Packit cd2a55
Packit cd2a55
#ifndef PATH_MAX
Packit cd2a55
#ifdef WIN32
Packit cd2a55
#define PATH_MAX 512
Packit cd2a55
#else
Packit cd2a55
#include <sys/param.h>
Packit cd2a55
#endif
Packit cd2a55
#ifndef PATH_MAX
Packit cd2a55
#ifdef MAXPATHLEN
Packit cd2a55
#define PATH_MAX MAXPATHLEN
Packit cd2a55
#else
Packit cd2a55
#define PATH_MAX 1024
Packit cd2a55
#endif
Packit cd2a55
#endif
Packit cd2a55
#endif /* PATH_MAX */
Packit cd2a55
Packit cd2a55
/* Kludge source to avoid encountering broken shared library linkers
Packit cd2a55
   which insist on resolving references unused by the application,
Packit cd2a55
   and broken object file formats that don't correctly distinguish
Packit cd2a55
   references to procedures from references to data.
Packit cd2a55
 */
Packit cd2a55
#if defined(SVR4)
Packit cd2a55
#define XMU_KLUDGE
Packit cd2a55
#endif
Packit cd2a55
Packit cd2a55
/*
Packit cd2a55
 * XmuConvertStringToCursor:
Packit cd2a55
 *
Packit cd2a55
 * allows String to specify a standard cursor name (from cursorfont.h), a
Packit cd2a55
 * font name and glyph index of the form "FONT fontname index [[font] index]",
Packit cd2a55
 * or a bitmap file name (absolute, or relative to the global resource
Packit cd2a55
 * bitmapFilePath, class BitmapFilePath).  If the resource is not
Packit cd2a55
 * defined, the default value is the build symbol BITMAPDIR.
Packit cd2a55
 *
Packit cd2a55
 * shares lots of code with XmuCvtStringToPixmap, but unfortunately
Packit cd2a55
 * can't use it as the hotspot info is lost.
Packit cd2a55
 *
Packit cd2a55
 * To use, include the following in your ClassInitialize procedure:
Packit cd2a55
Packit cd2a55
static XtConvertArgRec screenConvertArg[] = {
Packit cd2a55
    {XtBaseOffset, (XtPointer) XtOffsetOf(WidgetRec, core.screen),
Packit cd2a55
     sizeof(Screen *)}
Packit cd2a55
};
Packit cd2a55
Packit cd2a55
    XtAddConverter(XtRString, XtRCursor, XmuCvtStringToCursor,
Packit cd2a55
		   screenConvertArg, XtNumber(screenConvertArg));
Packit cd2a55
 *
Packit cd2a55
 */
Packit cd2a55
Packit cd2a55
#define	done(address, type) \
Packit cd2a55
	{ (*toVal).size = sizeof(type); (*toVal).addr = (XPointer) address; }
Packit cd2a55
Packit cd2a55
#define FONTSPECIFIER		"FONT "
Packit cd2a55
Packit cd2a55
/*ARGSUSED*/
Packit cd2a55
void
Packit cd2a55
XmuCvtStringToCursor(XrmValuePtr args, Cardinal *num_args,
Packit cd2a55
		     XrmValuePtr fromVal, XrmValuePtr toVal)
Packit cd2a55
{
Packit cd2a55
    static Cursor cursor;		/* static for cvt magic */
Packit cd2a55
    char *name = (char *)fromVal->addr;
Packit cd2a55
    Screen *screen;
Packit cd2a55
    register int i;
Packit cd2a55
    char maskname[PATH_MAX];
Packit cd2a55
    Pixmap source, mask = 0;
Packit cd2a55
    /* XXX - make fg/bg resources */
Packit cd2a55
    static XColor bgColor = {0, 0xffff, 0xffff, 0xffff};
Packit cd2a55
    static XColor fgColor = {0, 0, 0, 0};
Packit cd2a55
    int xhot, yhot;
Packit cd2a55
    int len;
Packit cd2a55
Packit cd2a55
Packit cd2a55
    if (*num_args != 1)
Packit cd2a55
     XtErrorMsg("wrongParameters","cvtStringToCursor","XtToolkitError",
Packit cd2a55
             "String to cursor conversion needs screen argument",
Packit cd2a55
              (String *)NULL, (Cardinal *)NULL);
Packit cd2a55
Packit cd2a55
    if (XmuCompareISOLatin1(name, "None") == 0)
Packit cd2a55
      {
Packit cd2a55
	cursor = None;
Packit cd2a55
	done(&cursor, Cursor);
Packit cd2a55
	return;
Packit cd2a55
      }
Packit cd2a55
Packit cd2a55
    screen = *((Screen **) args[0].addr);
Packit cd2a55
Packit cd2a55
    if (0 == strncmp(FONTSPECIFIER, name, strlen(FONTSPECIFIER))) {
Packit cd2a55
	char source_name[PATH_MAX], mask_name[PATH_MAX];
Packit cd2a55
	int source_char, mask_char, fields = 0;
Packit cd2a55
	Font source_font, mask_font;
Packit cd2a55
	XrmValue fromString, toFont;
Packit cd2a55
	XrmValue cvtArg;
Packit cd2a55
	Boolean success;
Packit cd2a55
	Display *dpy = DisplayOfScreen(screen);
Packit cd2a55
	char *strspec = NULL;
Packit cd2a55
	int strspeclen;
Packit cd2a55
#ifdef XMU_KLUDGE
Packit cd2a55
	Cardinal num;
Packit cd2a55
#endif
Packit cd2a55
Packit cd2a55
	strspeclen = strlen("FONT %s %d %s %d") + 21;
Packit cd2a55
	strspec = XtMalloc(strspeclen);
Packit cd2a55
	if (strspec != NULL) {
Packit cd2a55
	    snprintf(strspec, strspeclen, "FONT %%%lds %%d %%%lds %%d",
Packit cd2a55
		     (unsigned long)sizeof(source_name) - 1,
Packit cd2a55
		     (unsigned long)sizeof(mask_name) - 1);
Packit cd2a55
	    fields = sscanf(name, strspec,
Packit cd2a55
			    source_name, &source_char,
Packit cd2a55
			    mask_name, &mask_char);
Packit cd2a55
	    XtFree(strspec);
Packit cd2a55
	}
Packit cd2a55
	if (fields < 2) {
Packit cd2a55
	    XtStringConversionWarning(name, XtRCursor);
Packit cd2a55
	    return;
Packit cd2a55
	}
Packit cd2a55
Packit cd2a55
	fromString.addr = source_name;
Packit cd2a55
	fromString.size = strlen(source_name) + 1;
Packit cd2a55
	toFont.addr = (XPointer) &source_font;
Packit cd2a55
	toFont.size = sizeof(Font);
Packit cd2a55
	cvtArg.addr = (XPointer) &dp;;
Packit cd2a55
	cvtArg.size = sizeof(Display *);
Packit cd2a55
	/* XXX using display of screen argument as message display */
Packit cd2a55
#ifdef XMU_KLUDGE
Packit cd2a55
	/* XXX Sacrifice caching */
Packit cd2a55
	num = 1;
Packit cd2a55
	success = XtCvtStringToFont(dpy, &cvtArg, &num, &fromString, &toFont,
Packit cd2a55
				    NULL);
Packit cd2a55
#else
Packit cd2a55
	success = XtCallConverter(dpy, XtCvtStringToFont, &cvtArg,
Packit cd2a55
				  (Cardinal)1, &fromString, &toFont, NULL);
Packit cd2a55
#endif
Packit cd2a55
	if (!success) {
Packit cd2a55
	    XtStringConversionWarning(name, XtRCursor);
Packit cd2a55
	    return;
Packit cd2a55
	}
Packit cd2a55
Packit cd2a55
	switch (fields) {
Packit cd2a55
	  case 2:		/* defaulted mask font & char */
Packit cd2a55
	    mask_font = source_font;
Packit cd2a55
	    mask_char = source_char;
Packit cd2a55
	    break;
Packit cd2a55
Packit cd2a55
	  case 3:		/* defaulted mask font */
Packit cd2a55
	    mask_font = source_font;
Packit cd2a55
	    mask_char = atoi(mask_name);
Packit cd2a55
	    break;
Packit cd2a55
Packit cd2a55
	  case 4:		/* specified mask font & char */
Packit cd2a55
	    fromString.addr = mask_name;
Packit cd2a55
	    fromString.size = strlen(mask_name) + 1;
Packit cd2a55
	    toFont.addr = (XPointer) &mask_font;
Packit cd2a55
	    toFont.size = sizeof(Font);
Packit cd2a55
	    /* XXX using display of screen argument as message display */
Packit cd2a55
#ifdef XMU_KLUDGE
Packit cd2a55
	    /* XXX Sacrifice caching */
Packit cd2a55
	    num = 1;
Packit cd2a55
	    success = XtCvtStringToFont(dpy, &cvtArg, &num, &fromString,
Packit cd2a55
					&toFont, NULL);
Packit cd2a55
#else
Packit cd2a55
	    success = XtCallConverter(dpy, XtCvtStringToFont, &cvtArg,
Packit cd2a55
				      (Cardinal)1, &fromString, &toFont, NULL);
Packit cd2a55
#endif
Packit cd2a55
	    if (!success) {
Packit cd2a55
		XtStringConversionWarning(name, XtRCursor);
Packit cd2a55
		return;
Packit cd2a55
	    }
Packit cd2a55
	}
Packit cd2a55
Packit cd2a55
	cursor = XCreateGlyphCursor( DisplayOfScreen(screen), source_font,
Packit cd2a55
				     mask_font, source_char, mask_char,
Packit cd2a55
				     &fgColor, &bgColor );
Packit cd2a55
	done(&cursor, Cursor);
Packit cd2a55
	return;
Packit cd2a55
    }
Packit cd2a55
Packit cd2a55
    i = XmuCursorNameToIndex (name);
Packit cd2a55
    if (i != -1) {
Packit cd2a55
	cursor = XCreateFontCursor (DisplayOfScreen(screen), i);
Packit cd2a55
	done(&cursor, Cursor);
Packit cd2a55
	return;
Packit cd2a55
    }
Packit cd2a55
Packit cd2a55
    if ((source = XmuLocateBitmapFile (screen, name,
Packit cd2a55
				       maskname, (sizeof maskname) - 4,
Packit cd2a55
				       NULL, NULL, &xhot, &yhot)) == None) {
Packit cd2a55
	XtStringConversionWarning (name, XtRCursor);
Packit cd2a55
	cursor = None;
Packit cd2a55
	done(&cursor, Cursor);
Packit cd2a55
	return;
Packit cd2a55
    }
Packit cd2a55
    len = strlen (maskname);
Packit cd2a55
    for (i = 0; i < 2; i++) {
Packit cd2a55
	strcpy (maskname + len, i == 0 ? "Mask" : "msk");
Packit cd2a55
	if ((mask = XmuLocateBitmapFile (screen, maskname, NULL, 0,
Packit cd2a55
					 NULL, NULL, NULL, NULL)) != None)
Packit cd2a55
	  break;
Packit cd2a55
    }
Packit cd2a55
Packit cd2a55
    cursor = XCreatePixmapCursor( DisplayOfScreen(screen), source, mask,
Packit cd2a55
				  &fgColor, &bgColor, xhot, yhot );
Packit cd2a55
    XFreePixmap( DisplayOfScreen(screen), source );
Packit cd2a55
    if (mask != None) XFreePixmap( DisplayOfScreen(screen), mask );
Packit cd2a55
Packit cd2a55
    done(&cursor, Cursor);
Packit cd2a55
}
Packit cd2a55
Packit cd2a55
#define	new_done(type, value) \
Packit cd2a55
	{							\
Packit cd2a55
	    if (toVal->addr != NULL) {				\
Packit cd2a55
		if (toVal->size < sizeof(type)) {		\
Packit cd2a55
		    toVal->size = sizeof(type);			\
Packit cd2a55
		    return False;				\
Packit cd2a55
		}						\
Packit cd2a55
		*(type*)(toVal->addr) = (value);		\
Packit cd2a55
	    }							\
Packit cd2a55
	    else {						\
Packit cd2a55
		static type static_val;				\
Packit cd2a55
		static_val = (value);				\
Packit cd2a55
		toVal->addr = (XPointer)&static_val;		\
Packit cd2a55
	    }							\
Packit cd2a55
	    toVal->size = sizeof(type);				\
Packit cd2a55
	    return True;					\
Packit cd2a55
	}
Packit cd2a55
Packit cd2a55
/*	Function Name: XmuCvtStringToColorCursor
Packit cd2a55
 *	Description: Converts a string into a colored cursor.
Packit cd2a55
 *	Arguments: dpy
Packit cd2a55
 *		   args - an argument list (see below).
Packit cd2a55
 *                 num_args - number of elements in the argument list.
Packit cd2a55
 *                 fromVal - value to convert from.
Packit cd2a55
 *                 toVal - value to convert to.
Packit cd2a55
 *		   data
Packit cd2a55
 *	Returns:   True or False
Packit cd2a55
 */
Packit cd2a55
Packit cd2a55
/*ARGSUSED*/
Packit cd2a55
Boolean
Packit cd2a55
XmuCvtStringToColorCursor(Display *dpy, XrmValuePtr args, Cardinal *num_args,
Packit cd2a55
			  XrmValuePtr fromVal, XrmValuePtr toVal,
Packit cd2a55
			  XtPointer *converter_data)
Packit cd2a55
{
Packit cd2a55
    Cursor cursor;
Packit cd2a55
    Screen *screen;
Packit cd2a55
    Pixel fg, bg;
Packit cd2a55
    Colormap c_map;
Packit cd2a55
    XColor colors[2];
Packit cd2a55
    Cardinal number;
Packit cd2a55
    XrmValue ret_val;
Packit cd2a55
Packit cd2a55
    if (*num_args != 4) {
Packit cd2a55
	XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
Packit cd2a55
	    "wrongParameters","cvtStringToColorCursor","XmuError",
Packit cd2a55
            "String to color cursor conversion needs four arguments",
Packit cd2a55
	    (String *)NULL, (Cardinal *)NULL);
Packit cd2a55
	return False;
Packit cd2a55
    }
Packit cd2a55
Packit cd2a55
    screen = *((Screen **) args[0].addr);
Packit cd2a55
    fg = *((Pixel *) args[1].addr);
Packit cd2a55
    bg = *((Pixel *) args[2].addr);
Packit cd2a55
    c_map = *((Colormap *) args[3].addr);
Packit cd2a55
Packit cd2a55
    number = 1;
Packit cd2a55
    XmuCvtStringToCursor(args, &number, fromVal, &ret_val);
Packit cd2a55
Packit cd2a55
    cursor = *((Cursor *) ret_val.addr);
Packit cd2a55
Packit cd2a55
    if (cursor == None || (fg == BlackPixelOfScreen(screen)
Packit cd2a55
			   && bg == WhitePixelOfScreen(screen)))
Packit cd2a55
	new_done(Cursor, cursor);
Packit cd2a55
Packit cd2a55
    colors[0].pixel = fg;
Packit cd2a55
    colors[1].pixel = bg;
Packit cd2a55
Packit cd2a55
    XQueryColors (dpy, c_map, colors, 2);
Packit cd2a55
    XRecolorCursor(dpy, cursor, colors, colors + 1);
Packit cd2a55
    new_done(Cursor, cursor);
Packit cd2a55
}
Packit cd2a55
Packit cd2a55
Packit cd2a55