Home | History | Annotate | Line # | Download | only in src
      1 /*
      2 
      3 Copyright 1988, 1998  The Open Group
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included in
     12 all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     20 
     21 Except as contained in this notice, the name of The Open Group shall not be
     22 used in advertising or otherwise to promote the sale, use or other dealings
     23 in this Software without prior written authorization from The Open Group.
     24 
     25 */
     26 
     27 /*
     28  * This file contains routines to handle common selection targets.
     29  *
     30  * Public entry points:
     31  *
     32  *	XmuConvertStandardSelection()	return a known selection
     33  */
     34 
     35 #ifdef HAVE_CONFIG_H
     36 #include <config.h>
     37 #endif
     38 
     39 #include <X11/IntrinsicP.h>
     40 #include <X11/Xatom.h>
     41 #include <X11/ShellP.h>
     42 #ifdef XTHREADS
     43 #include <X11/Xthreads.h>
     44 #endif
     45 #include <stdio.h>
     46 
     47 #ifdef WIN32
     48 #include <X11/Xwinsock.h>
     49 #else
     50 #ifndef Lynx
     51 #include <sys/socket.h>
     52 #else
     53 #include <sys/types.h>
     54 #include <socket.h>
     55 #endif
     56 #define XOS_USE_XT_LOCKING
     57 #endif
     58 #include <X11/Xos_r.h>
     59 
     60 #include <X11/Xos.h>
     61 #include <stdlib.h>
     62 #include "Atoms.h"
     63 #include "StdSel.h"
     64 #include "SysUtil.h"
     65 #include <X11/Xfuncs.h>
     66 
     67 #ifndef OS_NAME
     68 # ifndef X_OS_FILE
     69 #  ifdef HAVE_UNAME
     70 #   define USE_UNAME
     71 #  endif
     72 # endif /*X_OS_FILE*/
     73 # ifdef USE_UNAME
     74 #  include <sys/utsname.h>
     75 # endif
     76 #endif
     77 
     78 /*
     79  * Prototypes
     80  */
     81 static char *get_os_name(void);
     82 static Bool isApplicationShell(Widget);
     83 
     84 /*
     85  * Implementation
     86  */
     87 static char *
     88 get_os_name(void)
     89 {
     90 #ifdef OS_NAME
     91 	return XtNewString(OS_NAME);
     92 #else
     93 #if defined(X_OS_FILE) || defined(MOTD_FILE)
     94 	FILE *f = NULL;
     95 #endif
     96 
     97 #ifdef USE_UNAME
     98 	struct utsname utss;
     99 
    100 	if (uname (&utss) >= 0) {
    101 	    char *os_name;
    102 	    int len = strlen(utss.sysname) + 1;
    103 #ifndef hpux				/* because of hostname length crock */
    104 	    len += 2 + strlen(utss.release);
    105 #endif
    106 	    os_name = XtMalloc (len);
    107 	    strcpy (os_name, utss.sysname);
    108 #ifndef hpux
    109 	    strcat (os_name, " ");
    110 	    strcat (os_name, utss.release);
    111 #endif
    112 	    return os_name;
    113 	}
    114 #endif
    115 
    116 #ifdef X_OS_FILE
    117 	f = fopen(X_OS_FILE, "r");
    118 	if (!f)
    119 #endif
    120 #ifdef MOTD_FILE
    121 	       f = fopen(MOTD_FILE, "r");
    122 #endif
    123 #if defined(X_OS_FILE) || defined(MOTD_FILE)
    124 	if (f) {
    125 	    char motd[512];
    126 	    motd[0] = '\0';
    127 	    (void) fgets(motd, 511, f);
    128 	    fclose(f);
    129 	    motd[511] = '\0';
    130 	    if (motd[0] != '\0') {
    131 		int len = strlen(motd);
    132 		if (motd[len - 1] == '\n')
    133 		    motd[len - 1] = '\0';
    134 		return XtNewString(motd);
    135 	    }
    136 	}
    137 #endif
    138 
    139 #if !defined(SYSV) && (defined(CSRG_BASED) || defined(unix))
    140 	return XtNewString("BSD");
    141 #else
    142 	return NULL;
    143 #endif
    144 
    145 #endif /*OS_NAME*/
    146 }
    147 
    148 /* This is a trick/kludge.  To make shared libraries happier (linking
    149  * against Xmu but not linking against Xt, and apparently even work
    150  * as we desire on SVR4, we need to avoid an explicit data reference
    151  * to applicationShellWidgetClass.  XtIsTopLevelShell is known
    152  * (implementation dependent assumption!) to use a bit flag.  So we
    153  * go that far.  Then, we test whether it is an applicationShellWidget
    154  * class by looking for an explicit class name.  Seems pretty safe.
    155  */
    156 static Bool
    157 isApplicationShell(Widget w)
    158 {
    159     register WidgetClass c;
    160 
    161     if (!XtIsTopLevelShell(w))
    162 	return False;
    163     for (c = XtClass(w); c; c = c->core_class.superclass) {
    164 	if (!strcmp(c->core_class.class_name, "ApplicationShell"))
    165 	    return True;
    166     }
    167     return False;
    168 }
    169 
    170 Boolean
    171 XmuConvertStandardSelection(Widget w, Time time, Atom *selection, Atom *target,
    172 			    Atom *type, XPointer *value,
    173 			    unsigned long *length, int *format)
    174 {
    175     Display *d = XtDisplay(w);
    176     if (*target == XA_TIMESTAMP(d)) {
    177 	*value = XtMalloc(4);
    178 	if (sizeof(long) == 4)
    179 	    *(long*)*value = time;
    180 	else {
    181 	    long temp = time;
    182 	    memcpy((char*)*value, ((char*)&temp)+sizeof(long)-4, 4);
    183 	}
    184 	*type = XA_INTEGER;
    185 	*length = 1;
    186 	*format = 32;
    187 	return True;
    188     }
    189     if (*target == XA_HOSTNAME(d)) {
    190 	char hostname[1024];
    191 	hostname[0] = '\0';
    192 	*length = XmuGetHostname (hostname, sizeof hostname);
    193 	*value = XtNewString(hostname);
    194 	*type = XA_STRING;
    195 	*format = 8;
    196 	return True;
    197     }
    198     if (*target == XA_USER(d)) {
    199 	char *name = (char*)getenv("USER");
    200 	if (name == NULL) return False;
    201 	*value = XtNewString(name);
    202 	*type = XA_STRING;
    203 	*length = strlen(name);
    204 	*format = 8;
    205 	return True;
    206     }
    207     if (*target == XA_CLASS(d)) {
    208 	Widget parent = XtParent(w);
    209 	String class;
    210 	int len;
    211 	while (parent != NULL && !isApplicationShell(w)) {
    212 	    w = parent;
    213 	    parent = XtParent(w);
    214 	}
    215 	if (isApplicationShell(w))
    216 	    class = ((ApplicationShellWidget) w)->application.class;
    217 	else
    218 	    class = XtClass(w)->core_class.class_name;
    219 	*length = (len=strlen(w->core.name)) + strlen(class) + 2;
    220 	*value = XtMalloc(*length);
    221 	strcpy( (char*)*value, w->core.name );
    222 	strcpy( (char*)*value+len+1, class );
    223 	*type = XA_STRING;
    224 	*format = 8;
    225 	return True;
    226     }
    227     if (*target == XA_NAME(d)) {
    228 	Widget parent = XtParent(w);
    229 
    230 	while (parent != NULL && !XtIsWMShell(w)) {
    231 	    w = parent;
    232 	    parent = XtParent(w);
    233 	}
    234 	if (!XtIsWMShell(w)) return False;
    235 	*value = XtNewString( ((WMShellWidget) w)->wm.title );
    236 	*length = strlen(*value);
    237 	*type = XA_STRING;
    238 	*format = 8;
    239 	return True;
    240     }
    241     if (*target == XA_CLIENT_WINDOW(d)) {
    242 	Widget parent = XtParent(w);
    243 	while (parent != NULL) {
    244 	    w = parent;
    245 	    parent = XtParent(w);
    246 	}
    247 	*value = XtMalloc(sizeof(Window));
    248 	*(Window*)*value = w->core.window;
    249 	*type = XA_WINDOW;
    250 	*length = 1;
    251 	*format = 32;
    252 	return True;
    253     }
    254     if (*target == XA_OWNER_OS(d)) {
    255 	*value = get_os_name();
    256 	if (*value == NULL) return False;
    257 	*type = XA_STRING;
    258 	*length = strlen(*value);
    259 	*format = 8;
    260 	return True;
    261     }
    262     if (*target == XA_TARGETS(d)) {
    263 #if defined(unix)
    264 #  define NUM_TARGETS 7
    265 #else
    266 #  define NUM_TARGETS 6
    267 #endif
    268 	Atom* std_targets = (Atom*)XtMalloc(NUM_TARGETS*sizeof(Atom));
    269 	int i = 0;
    270 	std_targets[i++] = XA_TIMESTAMP(d);
    271 	std_targets[i++] = XA_HOSTNAME(d);
    272 	std_targets[i++] = XA_USER(d);
    273 	std_targets[i++] = XA_CLASS(d);
    274 	std_targets[i++] = XA_NAME(d);
    275 	std_targets[i++] = XA_CLIENT_WINDOW(d);
    276 #ifdef unix
    277 	std_targets[i++] = XA_OWNER_OS(d);
    278 #endif
    279 	*value = (XPointer)std_targets;
    280 	*type = XA_ATOM;
    281 	*length = NUM_TARGETS;
    282 	*format = 32;
    283 	return True;
    284     }
    285     /* else */
    286     return False;
    287 }
    288