Blame src/CvtStdSel.c

Packit cd2a55
/*
Packit cd2a55
Packit cd2a55
Copyright 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
 * This file contains routines to handle common selection targets.
Packit cd2a55
 *
Packit cd2a55
 * Public entry points:
Packit cd2a55
 *
Packit cd2a55
 *	XmuConvertStandardSelection()	return a known selection
Packit cd2a55
 */
Packit cd2a55
Packit cd2a55
#ifdef HAVE_CONFIG_H
Packit cd2a55
#include <config.h>
Packit cd2a55
#endif
Packit cd2a55
Packit cd2a55
#ifdef SYSVNET
Packit cd2a55
#include <interlan/il_types.h>
Packit cd2a55
#define __TYPES__		/* prevent #include <sys/types.h> in Xlib.h */
Packit cd2a55
#include <interlan/netdb.h>
Packit cd2a55
#include <interlan/socket.h>
Packit cd2a55
#endif /* SYSVNET */
Packit cd2a55
Packit cd2a55
#include <X11/IntrinsicP.h>
Packit cd2a55
#include <X11/Xatom.h>
Packit cd2a55
#include <X11/ShellP.h>
Packit cd2a55
#ifdef XTHREADS
Packit cd2a55
#include <X11/Xthreads.h>
Packit cd2a55
#endif
Packit cd2a55
#include <stdio.h>
Packit cd2a55
Packit cd2a55
#ifndef SYSVNET
Packit cd2a55
#ifdef WIN32
Packit cd2a55
#include <X11/Xwinsock.h>
Packit cd2a55
#define XOS_USE_MTSAFE_NETDBAPI
Packit cd2a55
#else
Packit cd2a55
#ifndef Lynx
Packit cd2a55
#include <sys/socket.h>
Packit cd2a55
#else
Packit cd2a55
#include <sys/types.h>
Packit cd2a55
#include <socket.h>
Packit cd2a55
#endif
Packit cd2a55
#define XOS_USE_XT_LOCKING
Packit cd2a55
#endif
Packit cd2a55
#define X_INCLUDE_NETDB_H
Packit cd2a55
#include <X11/Xos_r.h>
Packit cd2a55
#endif
Packit cd2a55
Packit cd2a55
#include <X11/Xos.h>
Packit cd2a55
#include <stdlib.h>
Packit cd2a55
#include "Atoms.h"
Packit cd2a55
#include "StdSel.h"
Packit cd2a55
#include "SysUtil.h"
Packit cd2a55
#include <X11/Xfuncs.h>
Packit cd2a55
Packit cd2a55
#ifndef OS_NAME
Packit cd2a55
#ifndef X_OS_FILE
Packit cd2a55
#ifdef SYSV			/* keep separate until makedepend fixed */
Packit cd2a55
#define USE_UNAME
Packit cd2a55
#endif
Packit cd2a55
#ifdef SVR4
Packit cd2a55
#define USE_UNAME
Packit cd2a55
#endif
Packit cd2a55
#ifdef ultrix
Packit cd2a55
#define USE_UNAME
Packit cd2a55
#endif
Packit cd2a55
#ifdef CSRG_BASED
Packit cd2a55
#define USE_UNAME
Packit cd2a55
#endif
Packit cd2a55
#endif /*X_OS_FILE*/
Packit cd2a55
#ifdef USE_UNAME
Packit cd2a55
#include <sys/utsname.h>
Packit cd2a55
#endif
Packit cd2a55
#endif
Packit cd2a55
Packit cd2a55
/*
Packit cd2a55
 * Prototypes
Packit cd2a55
 */
Packit cd2a55
static char *get_os_name(void);
Packit cd2a55
static Bool isApplicationShell(Widget);
Packit cd2a55
Packit cd2a55
/*
Packit cd2a55
 * Implementation
Packit cd2a55
 */
Packit cd2a55
static char *
Packit cd2a55
get_os_name(void)
Packit cd2a55
{
Packit cd2a55
#ifdef OS_NAME
Packit cd2a55
	return XtNewString(OS_NAME);
Packit cd2a55
#else
Packit cd2a55
#if defined(X_OS_FILE) || defined(MOTD_FILE)
Packit cd2a55
	FILE *f = NULL;
Packit cd2a55
#endif
Packit cd2a55
Packit cd2a55
#ifdef USE_UNAME
Packit cd2a55
	struct utsname utss;
Packit cd2a55
Packit cd2a55
	if (uname (&utss) >= 0) {
Packit cd2a55
	    char *os_name;
Packit cd2a55
	    int len = strlen(utss.sysname) + 1;
Packit cd2a55
#ifndef hpux				/* because of hostname length crock */
Packit cd2a55
	    len += 2 + strlen(utss.release);
Packit cd2a55
#endif
Packit cd2a55
	    os_name = XtMalloc (len);
Packit cd2a55
	    strcpy (os_name, utss.sysname);
Packit cd2a55
#ifndef hpux
Packit cd2a55
	    strcat (os_name, " ");
Packit cd2a55
	    strcat (os_name, utss.release);
Packit cd2a55
#endif
Packit cd2a55
	    return os_name;
Packit cd2a55
	}
Packit cd2a55
#endif
Packit cd2a55
Packit cd2a55
#ifdef X_OS_FILE
Packit cd2a55
	f = fopen(X_OS_FILE, "r");
Packit cd2a55
	if (!f)
Packit cd2a55
#endif
Packit cd2a55
#ifdef MOTD_FILE
Packit cd2a55
	       f = fopen(MOTD_FILE, "r");
Packit cd2a55
#endif
Packit cd2a55
#if defined(X_OS_FILE) || defined(MOTD_FILE)
Packit cd2a55
	if (f) {
Packit cd2a55
	    char motd[512];
Packit cd2a55
	    motd[0] = '\0';
Packit cd2a55
	    (void) fgets(motd, 511, f);
Packit cd2a55
	    fclose(f);
Packit cd2a55
	    motd[511] = '\0';
Packit cd2a55
	    if (motd[0] != '\0') {
Packit cd2a55
		int len = strlen(motd);
Packit cd2a55
		if (motd[len - 1] == '\n')
Packit cd2a55
		    motd[len - 1] = '\0';
Packit cd2a55
		return XtNewString(motd);
Packit cd2a55
	    }
Packit cd2a55
	}
Packit cd2a55
#endif
Packit cd2a55
Packit cd2a55
#ifdef sun
Packit cd2a55
	return XtNewString("SunOS");
Packit cd2a55
#else
Packit cd2a55
# if !defined(SYSV) && (defined(CSRG_BASED) || defined(unix))
Packit cd2a55
	return XtNewString("BSD");
Packit cd2a55
# else
Packit cd2a55
	return NULL;
Packit cd2a55
# endif
Packit cd2a55
#endif
Packit cd2a55
Packit cd2a55
#endif /*OS_NAME*/
Packit cd2a55
}
Packit cd2a55
Packit cd2a55
/* This is a trick/kludge.  To make shared libraries happier (linking
Packit cd2a55
 * against Xmu but not linking against Xt, and apparently even work
Packit cd2a55
 * as we desire on SVR4, we need to avoid an explicit data reference
Packit cd2a55
 * to applicationShellWidgetClass.  XtIsTopLevelShell is known
Packit cd2a55
 * (implementation dependent assumption!) to use a bit flag.  So we
Packit cd2a55
 * go that far.  Then, we test whether it is an applicationShellWidget
Packit cd2a55
 * class by looking for an explicit class name.  Seems pretty safe.
Packit cd2a55
 */
Packit cd2a55
static Bool
Packit cd2a55
isApplicationShell(Widget w)
Packit cd2a55
{
Packit cd2a55
    register WidgetClass c;
Packit cd2a55
Packit cd2a55
    if (!XtIsTopLevelShell(w))
Packit cd2a55
	return False;
Packit cd2a55
    for (c = XtClass(w); c; c = c->core_class.superclass) {
Packit cd2a55
	if (!strcmp(c->core_class.class_name, "ApplicationShell"))
Packit cd2a55
	    return True;
Packit cd2a55
    }
Packit cd2a55
    return False;
Packit cd2a55
}
Packit cd2a55
Packit cd2a55
Boolean
Packit cd2a55
XmuConvertStandardSelection(Widget w, Time time, Atom *selection, Atom *target,
Packit cd2a55
			    Atom *type, XPointer *value,
Packit cd2a55
			    unsigned long *length, int *format)
Packit cd2a55
{
Packit cd2a55
    Display *d = XtDisplay(w);
Packit cd2a55
    if (*target == XA_TIMESTAMP(d)) {
Packit cd2a55
	*value = XtMalloc(4);
Packit cd2a55
	if (sizeof(long) == 4)
Packit cd2a55
	    *(long*)*value = time;
Packit cd2a55
	else {
Packit cd2a55
	    long temp = time;
Packit cd2a55
	    (void) memmove((char*)*value, ((char*)&temp)+sizeof(long)-4, 4);
Packit cd2a55
	}
Packit cd2a55
	*type = XA_INTEGER;
Packit cd2a55
	*length = 1;
Packit cd2a55
	*format = 32;
Packit cd2a55
	return True;
Packit cd2a55
    }
Packit cd2a55
    if (*target == XA_HOSTNAME(d)) {
Packit cd2a55
	char hostname[1024];
Packit cd2a55
	hostname[0] = '\0';
Packit cd2a55
	*length = XmuGetHostname (hostname, sizeof hostname);
Packit cd2a55
	*value = XtNewString(hostname);
Packit cd2a55
	*type = XA_STRING;
Packit cd2a55
	*format = 8;
Packit cd2a55
	return True;
Packit cd2a55
    }
Packit cd2a55
#if defined(TCPCONN)
Packit cd2a55
    if (*target == XA_IP_ADDRESS(d)) {
Packit cd2a55
	char hostname[1024];
Packit cd2a55
#ifdef XTHREADS_NEEDS_BYNAMEPARAMS
Packit cd2a55
	_Xgethostbynameparams hparams;
Packit cd2a55
#endif
Packit cd2a55
	struct hostent *hostp;
Packit cd2a55
Packit cd2a55
	hostname[0] = '\0';
Packit cd2a55
	(void) XmuGetHostname (hostname, sizeof hostname);
Packit cd2a55
Packit cd2a55
	if ((hostp = _XGethostbyname (hostname,hparams)) == NULL)
Packit cd2a55
	    return False;
Packit cd2a55
Packit cd2a55
	if (hostp->h_addrtype != AF_INET) return False;
Packit cd2a55
	*length = hostp->h_length;
Packit cd2a55
	*value = XtMalloc(*length);
Packit cd2a55
	(void) memmove (*value, hostp->h_addr, *length);
Packit cd2a55
	*type = XA_NET_ADDRESS(d);
Packit cd2a55
	*format = 8;
Packit cd2a55
	return True;
Packit cd2a55
    }
Packit cd2a55
#endif
Packit cd2a55
    if (*target == XA_USER(d)) {
Packit cd2a55
	char *name = (char*)getenv("USER");
Packit cd2a55
	if (name == NULL) return False;
Packit cd2a55
	*value = XtNewString(name);
Packit cd2a55
	*type = XA_STRING;
Packit cd2a55
	*length = strlen(name);
Packit cd2a55
	*format = 8;
Packit cd2a55
	return True;
Packit cd2a55
    }
Packit cd2a55
    if (*target == XA_CLASS(d)) {
Packit cd2a55
	Widget parent = XtParent(w);
Packit cd2a55
	char *class;
Packit cd2a55
	int len;
Packit cd2a55
	while (parent != NULL && !isApplicationShell(w)) {
Packit cd2a55
	    w = parent;
Packit cd2a55
	    parent = XtParent(w);
Packit cd2a55
	}
Packit cd2a55
	if (isApplicationShell(w))
Packit cd2a55
	    class = ((ApplicationShellWidget) w)->application.class;
Packit cd2a55
	else
Packit cd2a55
	    class = XtClass(w)->core_class.class_name;
Packit cd2a55
	*length = (len=strlen(w->core.name)) + strlen(class) + 2;
Packit cd2a55
	*value = XtMalloc(*length);
Packit cd2a55
	strcpy( (char*)*value, w->core.name );
Packit cd2a55
	strcpy( (char*)*value+len+1, class );
Packit cd2a55
	*type = XA_STRING;
Packit cd2a55
	*format = 8;
Packit cd2a55
	return True;
Packit cd2a55
    }
Packit cd2a55
    if (*target == XA_NAME(d)) {
Packit cd2a55
	Widget parent = XtParent(w);
Packit cd2a55
Packit cd2a55
	while (parent != NULL && !XtIsWMShell(w)) {
Packit cd2a55
	    w = parent;
Packit cd2a55
	    parent = XtParent(w);
Packit cd2a55
	}
Packit cd2a55
	if (!XtIsWMShell(w)) return False;
Packit cd2a55
	*value = XtNewString( ((WMShellWidget) w)->wm.title );
Packit cd2a55
	*length = strlen(*value);
Packit cd2a55
	*type = XA_STRING;
Packit cd2a55
	*format = 8;
Packit cd2a55
	return True;
Packit cd2a55
    }
Packit cd2a55
    if (*target == XA_CLIENT_WINDOW(d)) {
Packit cd2a55
	Widget parent = XtParent(w);
Packit cd2a55
	while (parent != NULL) {
Packit cd2a55
	    w = parent;
Packit cd2a55
	    parent = XtParent(w);
Packit cd2a55
	}
Packit cd2a55
	*value = XtMalloc(sizeof(Window));
Packit cd2a55
	*(Window*)*value = w->core.window;
Packit cd2a55
	*type = XA_WINDOW;
Packit cd2a55
	*length = 1;
Packit cd2a55
	*format = 32;
Packit cd2a55
	return True;
Packit cd2a55
    }
Packit cd2a55
    if (*target == XA_OWNER_OS(d)) {
Packit cd2a55
	*value = get_os_name();
Packit cd2a55
	if (*value == NULL) return False;
Packit cd2a55
	*type = XA_STRING;
Packit cd2a55
	*length = strlen(*value);
Packit cd2a55
	*format = 8;
Packit cd2a55
	return True;
Packit cd2a55
    }
Packit cd2a55
    if (*target == XA_TARGETS(d)) {
Packit cd2a55
#if defined(unix)
Packit cd2a55
#  define NUM_TARGETS 8
Packit cd2a55
#else
Packit cd2a55
#  define NUM_TARGETS 7
Packit cd2a55
#endif
Packit cd2a55
	Atom* std_targets = (Atom*)XtMalloc(NUM_TARGETS*sizeof(Atom));
Packit cd2a55
	int i = 0;
Packit cd2a55
	std_targets[i++] = XA_TIMESTAMP(d);
Packit cd2a55
	std_targets[i++] = XA_HOSTNAME(d);
Packit cd2a55
	std_targets[i++] = XA_IP_ADDRESS(d);
Packit cd2a55
	std_targets[i++] = XA_USER(d);
Packit cd2a55
	std_targets[i++] = XA_CLASS(d);
Packit cd2a55
	std_targets[i++] = XA_NAME(d);
Packit cd2a55
	std_targets[i++] = XA_CLIENT_WINDOW(d);
Packit cd2a55
#ifdef unix
Packit cd2a55
	std_targets[i++] = XA_OWNER_OS(d);
Packit cd2a55
#endif
Packit cd2a55
	*value = (XPointer)std_targets;
Packit cd2a55
	*type = XA_ATOM;
Packit cd2a55
	*length = NUM_TARGETS;
Packit cd2a55
	*format = 32;
Packit cd2a55
	return True;
Packit cd2a55
    }
Packit cd2a55
    /* else */
Packit cd2a55
    return False;
Packit cd2a55
}