Initial revision

parents
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* $XFree86: xc/lib/Xcursor/display.c,v 1.6 2003/02/20 03:13:50 dawes Exp $
*
* Copyright 2002 Keith Packard, member of The XFree86 Project, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#include "xcursorint.h"
#include <X11/Xlibint.h>
#include <ctype.h>
static XcursorDisplayInfo *_XcursorDisplayInfo;
static int
_XcursorCloseDisplay (Display *dpy, XExtCodes *codes)
{
XcursorDisplayInfo *info, **prev;
/*
* Unhook from the global list
*/
_XLockMutex (_Xglobal_lock);
for (prev = &_XcursorDisplayInfo; (info = *prev); prev = &(*prev)->next)
if (info->display == dpy)
{
*prev = info->next;
break;
}
_XUnlockMutex (_Xglobal_lock);
if (info->theme)
free (info->theme);
free (info);
return 0;
}
static int
_XcursorDefaultParseBool (char *v)
{
char c0, c1;
c0 = *v;
if (isupper ((int)c0))
c0 = tolower (c0);
if (c0 == 't' || c0 == 'y' || c0 == '1')
return 1;
if (c0 == 'f' || c0 == 'n' || c0 == '0')
return 0;
if (c0 == 'o')
{
c1 = v[1];
if (isupper ((int)c1))
c1 = tolower (c1);
if (c1 == 'n')
return 1;
if (c1 == 'f')
return 0;
}
return -1;
}
XcursorDisplayInfo *
_XcursorGetDisplayInfo (Display *dpy)
{
XcursorDisplayInfo *info, **prev, *old;
int event_base, error_base;
int major, minor;
char *v;
int i;
_XLockMutex (_Xglobal_lock);
for (prev = &_XcursorDisplayInfo; (info = *prev); prev = &(*prev)->next)
{
if (info->display == dpy)
{
/*
* MRU the list
*/
if (prev != &_XcursorDisplayInfo)
{
*prev = info->next;
info->next = _XcursorDisplayInfo;
_XcursorDisplayInfo = info;
}
break;
}
}
_XUnlockMutex (_Xglobal_lock);
if (info)
return info;
info = (XcursorDisplayInfo *) malloc (sizeof (XcursorDisplayInfo));
if (!info)
return 0;
info->next = 0;
info->display = dpy;
info->codes = XAddExtension (dpy);
if (!info->codes)
{
free (info);
return 0;
}
(void) XESetCloseDisplay (dpy, info->codes->extension, _XcursorCloseDisplay);
/*
* Check whether the display supports the Render CreateCursor request
*/
info->has_render_cursor = XcursorFalse;
info->has_anim_cursor = XcursorFalse;
if (XRenderQueryExtension (dpy, &event_base, &error_base) &&
XRenderQueryVersion (dpy, &major, &minor))
{
if (major > 0 || minor >= 5)
{
info->has_render_cursor = XcursorTrue;
v = getenv ("XCURSOR_CORE");
if (!v)
v = XGetDefault (dpy, "Xcursor", "core");
if (v && _XcursorDefaultParseBool (v) == 1)
info->has_render_cursor = XcursorFalse;
}
if (info->has_render_cursor && (major > 0 || minor >= 8))
{
info->has_anim_cursor = XcursorTrue;
v = getenv ("XCURSOR_ANIM");
if (!v)
v = XGetDefault (dpy, "Xcursor", "anim");
if (v && _XcursorDefaultParseBool (v) == 0)
info->has_anim_cursor = XcursorFalse;
}
}
info->size = 0;
/*
* Get desired cursor size
*/
v = getenv ("XCURSOR_SIZE");
if (!v)
v = XGetDefault (dpy, "Xcursor", "size");
if (v)
info->size = atoi (v);
/*
* Use the Xft size to guess a size; make cursors 16 "points" tall
*/
if (info->size == 0)
{
int dpi = 0;
v = XGetDefault (dpy, "Xft", "dpi");
if (v)
dpi = atoi (v);
if (dpi)
info->size = dpi * 16 / 72;
}
/*
* Use display size to guess a size
*/
if (info->size == 0)
{
int dim;
if (DisplayHeight (dpy, DefaultScreen (dpy)) <
DisplayWidth (dpy, DefaultScreen (dpy)))
dim = DisplayHeight (dpy, DefaultScreen (dpy));
else
dim = DisplayWidth (dpy, DefaultScreen (dpy));
/*
* 16 pixels on a display of dimension 768
*/
info->size = dim / 48;
}
info->theme = 0;
/*
* Get the desired theme
*/
v = getenv ("XCURSOR_THEME");
if (!v)
v = XGetDefault (dpy, "Xcursor", "theme");
if (v)
{
info->theme = malloc (strlen (v) + 1);
if (info->theme)
strcpy (info->theme, v);
}
/*
* Get the desired dither
*/
info->dither = XcursorDitherThreshold;
v = getenv ("XCURSOR_DITHER");
if (!v)
v = XGetDefault (dpy, "Xcursor", "dither");
if (v)
{
if (!strcmp (v, "threshold"))
info->dither = XcursorDitherThreshold;
if (!strcmp (v, "median"))
info->dither = XcursorDitherMedian;
if (!strcmp (v, "ordered"))
info->dither = XcursorDitherOrdered;
if (!strcmp (v, "diffuse"))
info->dither = XcursorDitherDiffuse;
}
info->theme_core = False;
/*
* Find out if core cursors should
* be themed
*/
v = getenv ("XCURSOR_THEME_CORE");
if (!v)
v = XGetDefault (dpy, "Xcursor", "theme_core");
if (v)
{
i = _XcursorDefaultParseBool (v);
if (i >= 0)
info->theme_core = i;
}
info->fonts = 0;
for (i = 0; i < NUM_BITMAPS; i++)
info->bitmaps[i].bitmap = None;
/*
* Link new info info list, making sure another
* thread hasn't inserted something into the list while
* this one was busy setting up the data
*/
_XLockMutex (_Xglobal_lock);
for (old = _XcursorDisplayInfo; old; old = old->next)
if (old->display == dpy)
break;
if (old)
{
if (info->theme)
free (info->theme);
free (info);
info = old;
}
else
{
info->next = _XcursorDisplayInfo;
_XcursorDisplayInfo = info;
}
_XUnlockMutex (_Xglobal_lock);
return info;
}
XcursorBool
XcursorSupportsARGB (Display *dpy)
{
XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
return info && info->has_render_cursor;
}
XcursorBool
XcursorSupportsAnim (Display *dpy)
{
XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
return info && info->has_anim_cursor;
}
XcursorBool
XcursorSetDefaultSize (Display *dpy, int size)
{
XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
if (!info)
return XcursorFalse;
info->size = size;
return XcursorTrue;
}
int
XcursorGetDefaultSize (Display *dpy)
{
XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
if (!info)
return 0;
return info->size;
}
XcursorBool
XcursorSetTheme (Display *dpy, const char *theme)
{
XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
char *copy;
if (!info)
return XcursorFalse;
if (theme)
{
copy = malloc (strlen (theme) + 1);
if (!copy)
return XcursorFalse;
strcpy (copy, theme);
}
else
copy = 0;
if (info->theme)
free (info->theme);
info->theme = copy;
return XcursorTrue;
}
char *
XcursorGetTheme (Display *dpy)
{
XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
if (!info)
return 0;
return info->theme;
}
XcursorBool
XcursorGetThemeCore (Display *dpy)
{
XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
if (!info)
return XcursorFalse;
return info->theme_core;
}
XcursorBool
XcursorSetThemeCore (Display *dpy, XcursorBool theme_core)
{
XcursorDisplayInfo *info = _XcursorGetDisplayInfo (dpy);
if (!info)
return XcursorFalse;
info->theme_core = theme_core;
return XcursorTrue;
}
This diff is collapsed.
This diff is collapsed.
/*
* $XFree86: xc/lib/Xcursor/xcursorint.h,v 1.4 2003/01/26 03:22:42 eich Exp $
*
* Copyright © 2002 Keith Packard, member of The XFree86 Project, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, provided that
* the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of Keith Packard not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. Keith Packard makes no
* representations about the suitability of this software for any purpose. It
* is provided "as is" without express or implied warranty.
*
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef _XCURSORINT_H_
#define _XCURSORINT_H_
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <X11/extensions/Xrender.h>
#include "Xcursor.h"
typedef struct _XcursorFontInfo {
struct _XcursorFontInfo *next;
Font font;
XcursorBool is_cursor_font;
} XcursorFontInfo;
/*
* Track a few recently created bitmaps to see
* if they get used to create cursors. This
* is done by hooking into Xlib and watching
* for XCreatePixmap, XPutImage, XCreatePixmapCursor
* with appropriate arguments. When this happens
* Xcursor computes a hash value for the source image
* and tries to load a library cursor of that name.
*/
/* large bitmaps are unlikely to be cursors */
#define MAX_BITMAP_CURSOR_SIZE 64
/* don't need to remember very many; in fact, 2 is likely sufficient */
#define NUM_BITMAPS 8
typedef struct _XcursorBitmapInfo {
Pixmap bitmap;
unsigned long sequence;
unsigned int width, height;
Bool has_image;
unsigned char hash[XCURSOR_BITMAP_HASH_SIZE];
} XcursorBitmapInfo;
typedef enum _XcursorDither {
XcursorDitherThreshold,
XcursorDitherMedian,
XcursorDitherOrdered,
XcursorDitherDiffuse
} XcursorDither;
typedef struct _XcursorDisplayInfo {
struct _XcursorDisplayInfo *next;
Display *display;
XExtCodes *codes;
XcursorBool has_render_cursor;
XcursorBool has_anim_cursor;
XcursorBool theme_core;
int size;
XcursorFontInfo *fonts;
char *theme;
XcursorDither dither;
XcursorBitmapInfo bitmaps[NUM_BITMAPS];
} XcursorDisplayInfo;
XcursorDisplayInfo *
_XcursorGetDisplayInfo (Display *dpy);
Cursor
_XcursorCreateGlyphCursor(Display *dpy,
Font source_font,
Font mask_font,
unsigned int source_char,
unsigned int mask_char,
XColor _Xconst *foreground,
XColor _Xconst *background);
Cursor
_XcursorCreateFontCursor (Display *dpy, unsigned int shape);
#endif /* _XCURSORINT_H_ */
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment