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