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 #include <sys/socket.h>
     51 #define XOS_USE_XT_LOCKING
     52 #endif
     53 #include <X11/Xos_r.h>
     54 
     55 #include <X11/Xos.h>
     56 #include <stdlib.h>
     57 #include "Atoms.h"
     58 #include "StdSel.h"
     59 #include "SysUtil.h"
     60 #include <X11/Xfuncs.h>
     61 
     62 #ifndef OS_NAME
     63 # ifndef X_OS_FILE
     64 #  ifdef HAVE_UNAME
     65 #   define USE_UNAME
     66 #  endif
     67 # endif /*X_OS_FILE*/
     68 # ifdef USE_UNAME
     69 #  include <sys/utsname.h>
     70 # endif
     71 #endif
     72 
     73 /*
     74  * Prototypes
     75  */
     76 static char *get_os_name(void);
     77 static Bool isApplicationShell(Widget);
     78 
     79 /*
     80  * Implementation
     81  */
     82 static char *
     83 get_os_name(void)
     84 {
     85 #ifdef OS_NAME
     86 	return XtNewString(OS_NAME);
     87 #else
     88 #if defined(X_OS_FILE) || defined(MOTD_FILE)
     89 	FILE *f = NULL;
     90 #endif
     91 
     92 #ifdef USE_UNAME
     93 	struct utsname utss;
     94 
     95 	if (uname (&utss) >= 0) {
     96 	    char *os_name;
     97 
     98 	    XtAsprintf(&os_name, "%s %s", utss.sysname, utss.release);
     99 	    return os_name;
    100 	}
    101 #endif
    102 
    103 #ifdef X_OS_FILE
    104 	f = fopen(X_OS_FILE, "r");
    105 	if (!f)
    106 #endif
    107 #ifdef MOTD_FILE
    108 	       f = fopen(MOTD_FILE, "r");
    109 #endif
    110 #if defined(X_OS_FILE) || defined(MOTD_FILE)
    111 	if (f) {
    112 	    char motd[512];
    113 	    motd[0] = '\0';
    114 	    (void) fgets(motd, 511, f);
    115 	    fclose(f);
    116 	    motd[511] = '\0';
    117 	    if (motd[0] != '\0') {
    118 		int len = strlen(motd);
    119 		if (motd[len - 1] == '\n')
    120 		    motd[len - 1] = '\0';
    121 		return XtNewString(motd);
    122 	    }
    123 	}
    124 #endif
    125 
    126 #ifdef CSRG_BASED
    127 	return XtNewString("BSD");
    128 #else
    129 	return NULL;
    130 #endif
    131 
    132 #endif /*OS_NAME*/
    133 }
    134 
    135 /* This is a trick/kludge.  To make shared libraries happier (linking
    136  * against Xmu but not linking against Xt, and apparently even work
    137  * as we desire on SVR4, we need to avoid an explicit data reference
    138  * to applicationShellWidgetClass.  XtIsTopLevelShell is known
    139  * (implementation dependent assumption!) to use a bit flag.  So we
    140  * go that far.  Then, we test whether it is an applicationShellWidget
    141  * class by looking for an explicit class name.  Seems pretty safe.
    142  */
    143 static Bool
    144 isApplicationShell(Widget w)
    145 {
    146     register WidgetClass c;
    147 
    148     if (!XtIsTopLevelShell(w))
    149 	return False;
    150     for (c = XtClass(w); c; c = c->core_class.superclass) {
    151 	if (!strcmp(c->core_class.class_name, "ApplicationShell"))
    152 	    return True;
    153     }
    154     return False;
    155 }
    156 
    157 Boolean
    158 XmuConvertStandardSelection(Widget w, Time time, Atom *selection, Atom *target,
    159 			    Atom *type, XPointer *value,
    160 			    unsigned long *length, int *format)
    161 {
    162     Display *d = XtDisplay(w);
    163     if (*target == XA_TIMESTAMP(d)) {
    164 	*value = XtMalloc(4);
    165 	if (sizeof(long) == 4)
    166 	    *(long*)*value = time;
    167 	else {
    168 	    long temp = time;
    169 	    memcpy((char*)*value, ((char*)&temp)+sizeof(long)-4, 4);
    170 	}
    171 	*type = XA_INTEGER;
    172 	*length = 1;
    173 	*format = 32;
    174 	return True;
    175     }
    176     if (*target == XA_HOSTNAME(d)) {
    177 	char hostname[1024];
    178 	hostname[0] = '\0';
    179 	*length = XmuGetHostname (hostname, sizeof hostname);
    180 	*value = XtNewString(hostname);
    181 	*type = XA_STRING;
    182 	*format = 8;
    183 	return True;
    184     }
    185     if (*target == XA_USER(d)) {
    186 	char *name = (char*)getenv("USER");
    187 	if (name == NULL) return False;
    188 	*value = XtNewString(name);
    189 	*type = XA_STRING;
    190 	*length = strlen(name);
    191 	*format = 8;
    192 	return True;
    193     }
    194     if (*target == XA_CLASS(d)) {
    195 	Widget parent = XtParent(w);
    196 	String class;
    197 	int len;
    198 	while (parent != NULL && !isApplicationShell(w)) {
    199 	    w = parent;
    200 	    parent = XtParent(w);
    201 	}
    202 	if (isApplicationShell(w))
    203 	    class = ((ApplicationShellWidget) w)->application.class;
    204 	else
    205 	    class = XtClass(w)->core_class.class_name;
    206 	*length = (len=strlen(w->core.name)) + strlen(class) + 2;
    207 	*value = XtMalloc(*length);
    208 	strcpy( (char*)*value, w->core.name );
    209 	strcpy( (char*)*value+len+1, class );
    210 	*type = XA_STRING;
    211 	*format = 8;
    212 	return True;
    213     }
    214     if (*target == XA_NAME(d)) {
    215 	Widget parent = XtParent(w);
    216 
    217 	while (parent != NULL && !XtIsWMShell(w)) {
    218 	    w = parent;
    219 	    parent = XtParent(w);
    220 	}
    221 	if (!XtIsWMShell(w)) return False;
    222 	*value = XtNewString( ((WMShellWidget) w)->wm.title );
    223 	*length = strlen(*value);
    224 	*type = XA_STRING;
    225 	*format = 8;
    226 	return True;
    227     }
    228     if (*target == XA_CLIENT_WINDOW(d)) {
    229 	Widget parent = XtParent(w);
    230 	while (parent != NULL) {
    231 	    w = parent;
    232 	    parent = XtParent(w);
    233 	}
    234 	*value = XtMalloc(sizeof(Window));
    235 	*(Window*)*value = w->core.window;
    236 	*type = XA_WINDOW;
    237 	*length = 1;
    238 	*format = 32;
    239 	return True;
    240     }
    241     if (*target == XA_OWNER_OS(d)) {
    242 	*value = get_os_name();
    243 	if (*value == NULL) return False;
    244 	*type = XA_STRING;
    245 	*length = strlen(*value);
    246 	*format = 8;
    247 	return True;
    248     }
    249     if (*target == XA_TARGETS(d)) {
    250 #if defined(unix)
    251 #  define NUM_TARGETS 7
    252 #else
    253 #  define NUM_TARGETS 6
    254 #endif
    255 	Atom* std_targets = (Atom*)XtMalloc(NUM_TARGETS*sizeof(Atom));
    256 	int i = 0;
    257 	std_targets[i++] = XA_TIMESTAMP(d);
    258 	std_targets[i++] = XA_HOSTNAME(d);
    259 	std_targets[i++] = XA_USER(d);
    260 	std_targets[i++] = XA_CLASS(d);
    261 	std_targets[i++] = XA_NAME(d);
    262 	std_targets[i++] = XA_CLIENT_WINDOW(d);
    263 #ifdef unix
    264 	std_targets[i++] = XA_OWNER_OS(d);
    265 #endif
    266 	*value = (XPointer)std_targets;
    267 	*type = XA_ATOM;
    268 	*length = NUM_TARGETS;
    269 	*format = 32;
    270 	return True;
    271     }
    272     /* else */
    273     return False;
    274 }
    275