Imported Upstream version 1.1.2
[platform/upstream/libXmu.git] / src / CvtStdSel.c
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 #ifdef SYSVNET
40 #include <interlan/il_types.h>
41 #define __TYPES__               /* prevent #include <sys/types.h> in Xlib.h */
42 #include <interlan/netdb.h>
43 #include <interlan/socket.h>
44 #endif /* SYSVNET */
45
46 #include <X11/IntrinsicP.h>
47 #include <X11/Xatom.h>
48 #include <X11/ShellP.h>
49 #ifdef XTHREADS
50 #include <X11/Xthreads.h>
51 #endif
52 #include <stdio.h>
53
54 #ifndef SYSVNET
55 #ifdef WIN32
56 #include <X11/Xwinsock.h>
57 #define XOS_USE_MTSAFE_NETDBAPI
58 #else
59 #ifndef Lynx
60 #include <sys/socket.h>
61 #else
62 #include <sys/types.h>
63 #include <socket.h>
64 #endif
65 #define XOS_USE_XT_LOCKING
66 #endif
67 #define X_INCLUDE_NETDB_H
68 #include <X11/Xos_r.h>
69 #endif
70
71 #include <X11/Xos.h>
72 #include <stdlib.h>
73 #include "Atoms.h"
74 #include "StdSel.h"
75 #include "SysUtil.h"
76 #include <X11/Xfuncs.h>
77
78 #ifndef OS_NAME
79 #ifndef X_OS_FILE
80 #ifdef SYSV                     /* keep separate until makedepend fixed */
81 #define USE_UNAME
82 #endif
83 #ifdef SVR4
84 #define USE_UNAME
85 #endif
86 #ifdef ultrix
87 #define USE_UNAME
88 #endif
89 #ifdef CSRG_BASED
90 #define USE_UNAME
91 #endif
92 #endif /*X_OS_FILE*/
93 #ifdef USE_UNAME
94 #include <sys/utsname.h>
95 #endif
96 #endif
97
98 /*
99  * Prototypes
100  */
101 static char *get_os_name(void);
102 static Bool isApplicationShell(Widget);
103
104 /*
105  * Implementation
106  */
107 static char *
108 get_os_name(void)
109 {
110 #ifdef OS_NAME
111         return XtNewString(OS_NAME);
112 #else
113 #if defined(X_OS_FILE) || defined(MOTD_FILE)
114         FILE *f = NULL;
115 #endif
116
117 #ifdef USE_UNAME
118         struct utsname utss;
119
120         if (uname (&utss) >= 0) {
121             char *os_name;
122             int len = strlen(utss.sysname) + 1;
123 #ifndef hpux                            /* because of hostname length crock */
124             len += 2 + strlen(utss.release);
125 #endif
126             os_name = XtMalloc (len);
127             strcpy (os_name, utss.sysname);
128 #ifndef hpux
129             strcat (os_name, " ");
130             strcat (os_name, utss.release);
131 #endif
132             return os_name;
133         }
134 #endif
135
136 #ifdef X_OS_FILE
137         f = fopen(X_OS_FILE, "r");
138         if (!f)
139 #endif
140 #ifdef MOTD_FILE
141                f = fopen(MOTD_FILE, "r");
142 #endif
143 #if defined(X_OS_FILE) || defined(MOTD_FILE)
144         if (f) {
145             char motd[512];
146             motd[0] = '\0';
147             (void) fgets(motd, 511, f);
148             fclose(f);
149             motd[511] = '\0';
150             if (motd[0] != '\0') {
151                 int len = strlen(motd);
152                 if (motd[len - 1] == '\n')
153                     motd[len - 1] = '\0';
154                 return XtNewString(motd);
155             }
156         }
157 #endif
158
159 #ifdef sun
160         return XtNewString("SunOS");
161 #else
162 # if !defined(SYSV) && (defined(CSRG_BASED) || defined(unix))
163         return XtNewString("BSD");
164 # else
165         return NULL;
166 # endif
167 #endif
168
169 #endif /*OS_NAME*/
170 }
171
172 /* This is a trick/kludge.  To make shared libraries happier (linking
173  * against Xmu but not linking against Xt, and apparently even work
174  * as we desire on SVR4, we need to avoid an explicit data reference
175  * to applicationShellWidgetClass.  XtIsTopLevelShell is known
176  * (implementation dependent assumption!) to use a bit flag.  So we
177  * go that far.  Then, we test whether it is an applicationShellWidget
178  * class by looking for an explicit class name.  Seems pretty safe.
179  */
180 static Bool
181 isApplicationShell(Widget w)
182 {
183     register WidgetClass c;
184
185     if (!XtIsTopLevelShell(w))
186         return False;
187     for (c = XtClass(w); c; c = c->core_class.superclass) {
188         if (!strcmp(c->core_class.class_name, "ApplicationShell"))
189             return True;
190     }
191     return False;
192 }
193
194 Boolean
195 XmuConvertStandardSelection(Widget w, Time time, Atom *selection, Atom *target,
196                             Atom *type, XPointer *value,
197                             unsigned long *length, int *format)
198 {
199     Display *d = XtDisplay(w);
200     if (*target == XA_TIMESTAMP(d)) {
201         *value = XtMalloc(4);
202         if (sizeof(long) == 4)
203             *(long*)*value = time;
204         else {
205             long temp = time;
206             (void) memmove((char*)*value, ((char*)&temp)+sizeof(long)-4, 4);
207         }
208         *type = XA_INTEGER;
209         *length = 1;
210         *format = 32;
211         return True;
212     }
213     if (*target == XA_HOSTNAME(d)) {
214         char hostname[1024];
215         hostname[0] = '\0';
216         *length = XmuGetHostname (hostname, sizeof hostname);
217         *value = XtNewString(hostname);
218         *type = XA_STRING;
219         *format = 8;
220         return True;
221     }
222 #if defined(TCPCONN)
223     if (*target == XA_IP_ADDRESS(d)) {
224         char hostname[1024];
225 #ifdef XTHREADS_NEEDS_BYNAMEPARAMS
226         _Xgethostbynameparams hparams;
227 #endif
228         struct hostent *hostp;
229
230         hostname[0] = '\0';
231         (void) XmuGetHostname (hostname, sizeof hostname);
232
233         if ((hostp = _XGethostbyname (hostname,hparams)) == NULL)
234             return False;
235
236         if (hostp->h_addrtype != AF_INET) return False;
237         *length = hostp->h_length;
238         *value = XtMalloc(*length);
239         (void) memmove (*value, hostp->h_addr, *length);
240         *type = XA_NET_ADDRESS(d);
241         *format = 8;
242         return True;
243     }
244 #endif
245     if (*target == XA_USER(d)) {
246         char *name = (char*)getenv("USER");
247         if (name == NULL) return False;
248         *value = XtNewString(name);
249         *type = XA_STRING;
250         *length = strlen(name);
251         *format = 8;
252         return True;
253     }
254     if (*target == XA_CLASS(d)) {
255         Widget parent = XtParent(w);
256         char *class;
257         int len;
258         while (parent != NULL && !isApplicationShell(w)) {
259             w = parent;
260             parent = XtParent(w);
261         }
262         if (isApplicationShell(w))
263             class = ((ApplicationShellWidget) w)->application.class;
264         else
265             class = XtClass(w)->core_class.class_name;
266         *length = (len=strlen(w->core.name)) + strlen(class) + 2;
267         *value = XtMalloc(*length);
268         strcpy( (char*)*value, w->core.name );
269         strcpy( (char*)*value+len+1, class );
270         *type = XA_STRING;
271         *format = 8;
272         return True;
273     }
274     if (*target == XA_NAME(d)) {
275         Widget parent = XtParent(w);
276
277         while (parent != NULL && !XtIsWMShell(w)) {
278             w = parent;
279             parent = XtParent(w);
280         }
281         if (!XtIsWMShell(w)) return False;
282         *value = XtNewString( ((WMShellWidget) w)->wm.title );
283         *length = strlen(*value);
284         *type = XA_STRING;
285         *format = 8;
286         return True;
287     }
288     if (*target == XA_CLIENT_WINDOW(d)) {
289         Widget parent = XtParent(w);
290         while (parent != NULL) {
291             w = parent;
292             parent = XtParent(w);
293         }
294         *value = XtMalloc(sizeof(Window));
295         *(Window*)*value = w->core.window;
296         *type = XA_WINDOW;
297         *length = 1;
298         *format = 32;
299         return True;
300     }
301     if (*target == XA_OWNER_OS(d)) {
302         *value = get_os_name();
303         if (*value == NULL) return False;
304         *type = XA_STRING;
305         *length = strlen(*value);
306         *format = 8;
307         return True;
308     }
309     if (*target == XA_TARGETS(d)) {
310 #if defined(unix)
311 #  define NUM_TARGETS 8
312 #else
313 #  define NUM_TARGETS 7
314 #endif
315         Atom* std_targets = (Atom*)XtMalloc(NUM_TARGETS*sizeof(Atom));
316         int i = 0;
317         std_targets[i++] = XA_TIMESTAMP(d);
318         std_targets[i++] = XA_HOSTNAME(d);
319         std_targets[i++] = XA_IP_ADDRESS(d);
320         std_targets[i++] = XA_USER(d);
321         std_targets[i++] = XA_CLASS(d);
322         std_targets[i++] = XA_NAME(d);
323         std_targets[i++] = XA_CLIENT_WINDOW(d);
324 #ifdef unix
325         std_targets[i++] = XA_OWNER_OS(d);
326 #endif
327         *value = (XPointer)std_targets;
328         *type = XA_ATOM;
329         *length = NUM_TARGETS;
330         *format = 32;
331         return True;
332     }
333     /* else */
334     return False;
335 }