/**
 *
 * $Id: misc.c,v 1.12 1999/04/28 21:47:37 jon Exp $
 *
 * Copyright (C) 1995 Free Software Foundation, Inc.
 *
 * This file is part of the GNU LessTif Library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 **/

/*
 * This file contains routines that just don't belong anywhere else
 */

#include <LTconfig.h>
#include <XmI/XmI.h>

#ifdef	HAVE_CTYPE_H
#include <ctype.h>
#endif

#include <Xm/XmP.h>
#if XtSpecificationRelease < 6
#include <X11/IntrinsicP.h>
#endif

const char _XmVersionString[] = XmVERSION_STRING;

#ifndef HAVE_STRCASECMP
int
strcasecmp(s1, s2)
     char *s1, *s2;
{
    int c1, c2;

    while (*s1 && *s2)
    {
	c1 = tolower(*s1);
	c2 = tolower(*s2);
	if (c1 != c2)
	{
	    return (c1 - c2);
	}
	s1++;
	s2++;
    }
    return (int)(*s1 - *s2);
}
#endif

#ifndef HAVE_STRNCASECMP
int
strncasecmp(s1, s2, count)
     char *s1, *s2;
     int count;
{
    int c1, c2;
    int i = 0;

    while (*s1 && *s2 && i < count)
    {
	c1 = tolower(*s1);
	c2 = tolower(*s2);
	if (c1 != c2)
	{
	    return (c1 - c2);
	}
	s1++;
	s2++;
	i++;
    }
    return (int)(*s1 - *s2);
}
#endif

#ifndef HAVE_STRSTR
char *
strstr(s1, s2)
     char *s1;
     char *s2;
{
    int i;
    char *p1;
    char *p2;
    char *s = s1;

    for (p2 = s2, i = 0; *s; p2 = s2, i++, s++)
    {
	for (p1 = s; *p1 && *p2 && *p1 == *p2; p1++, p2++)
	{
	}
	if (!*p2)
	{
	    break;
	}
    }
    if (!*p2)
    {
	return s1 + i;
    }

    return 0;
}
#endif

#ifndef HAVE_MEMMOVE
void *
memmove(void *s1, XmConst void *s2, size_t size)
{
    XmConst unsigned char *from = (XmConst unsigned char *)s2;
    unsigned char *to = (unsigned char *)s1;
    register int i;

    /* equal */
    if (from == to)
    {
	return (void *)to;
    }
    /* copy forwards */
    else if ((to - from) >= size)
    {
	for (i = 0; i < size; i++)
	{
	    to[i] = from[i];
	}
    }
    /* copy backwards */
    else
    {
	for (i = size - 1; i >= 0; i--)
	{
	    to[i] = from[i];
	}
    }

    return (void *)to;
}
#endif

void
XmUpdateDisplay(Widget w)
{
    XEvent ev;
    Display *dsp;

    dsp = XtDisplay(w);

    /* First process all available events ... */
    while (XCheckMaskEvent(dsp, ExposureMask, &ev))
    {
	XtDispatchEvent(&ev);
    }

    /* Flush all buffers */
    XSync(dsp, False);

    /* Process remaining events ... */
    while (XCheckMaskEvent(dsp, ExposureMask, &ev))
    {
	XtDispatchEvent(&ev);
    }
}

#define even_stipple_width 8
#define even_stipple_height 8
static unsigned char even_stipple_bits[] =
{
    0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55};
#define odd_stipple_width 8
#define odd_stipple_height 8
static unsigned char odd_stipple_bits[] =
{
    0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa};

void
_XmInstallStippleImages(Widget w)
{
    XImage *even_stipple_image;
    XImage *odd_stipple_image;

    _XmCreateImage(even_stipple_image, XtDisplay(w), (char *)even_stipple_bits,
		   even_stipple_width, even_stipple_height, LSBFirst);
    XmInstallImage(even_stipple_image, XmEVEN_STIPPLE_IMAGE);

    _XmCreateImage(odd_stipple_image, XtDisplay(w), (char *)odd_stipple_bits,
		   odd_stipple_width, odd_stipple_height, LSBFirst);
    XmInstallImage(odd_stipple_image, XmODD_STIPPLE_IMAGE);
}

/*
 * Below are some functions to deal with a multi-threaded environment.
 * Use these instead of the Xt stuff, to ensure that we can still cope
 * with X11r5 where this stuff didn't exist.
 */
#ifdef	XtSpecificationRelease
#if	XtSpecificationRelease > 5
#define	R6plus
#endif
#endif

void
_XmAppLock(XtAppContext appc)
{
#ifdef	R6plus
	XtAppLock(appc);
#endif
}

void
_XmAppUnlock(XtAppContext appc)
{
#ifdef	R6plus
	XtAppUnlock(appc);
#endif
}

void
_XmProcessLock(void)
{
#ifdef	R6plus
	XtProcessLock();
#endif
}

void
_XmProcessUnlock(void)
{
#ifdef	R6plus
	XtProcessUnlock();
#endif
}

/*
 * These are utility functions so you don't need to type so much.
 * Just pass a widget or gadget.
 */
void
_XmObjectLock(Widget w)
{
#ifdef	R6plus
	if (XmIsGadget(w))
		XtAppLock(XtWidgetToApplicationContext(
			XtParent(w)));
	else
		XtAppLock(XtWidgetToApplicationContext(w));
#endif
}

void
_XmObjectUnlock(Widget w)
{
#ifdef	R6plus
	if (XmIsGadget(w))
		XtAppUnlock(XtWidgetToApplicationContext(
			XtParent(w)));
	else
		XtAppUnlock(XtWidgetToApplicationContext(w));
#endif
}
