1 /*-
2  * Copyright (c) 1996
3  *        Rob Zimmermann.  All rights reserved.
4  * Copyright (c) 1996
5  *        Keith Bostic.  All rights reserved.
6  *
7  * See the LICENSE file for redistribution information.
8  */
9 
10 #include "config.h"
11 
12 #include <sys/cdefs.h>
13 #if 0
14 #ifndef lint
15 static const char sccsid[] = "Id: m_copypaste.c,v 8.10 2003/11/05 17:09:59 skimo Exp  (Berkeley) Date: 2003/11/05 17:09:59 ";
16 #endif /* not lint */
17 #else
18 __RCSID("$NetBSD: m_copypaste.c,v 1.2 2014/01/26 21:43:45 christos Exp $");
19 #endif
20 
21 /* ICCCM Cut and paste Utilities: */
22 
23 #include  <sys/types.h>
24 #include  <sys/queue.h>
25 
26 #include  <X11/X.h>
27 #include  <X11/Intrinsic.h>
28 #include  <X11/Xatom.h>
29 
30 #include  <bitstring.h>
31 #include  <stdio.h>
32 
33 #undef LOCK_SUCCESS
34 #include  "../common/common.h"
35 #include  "../ipc/ip.h"
36 #include  "m_motif.h"
37 
38 typedef   int       (*PFI)();
39 
40 static    PFI       icccm_paste,
41                     icccm_copy,
42                     icccm_clear,
43                     icccm_error;
44 
45 /*
46  * InitCopyPaste --
47  *
48  * PUBLIC: void __vi_InitCopyPaste
49  * PUBLIC:    __P((int (*)(), int (*)(), int (*)(), int (*)()));
50  */
51 void
__vi_InitCopyPaste(PFI f_copy,PFI f_paste,PFI f_clear,PFI f_error)52 __vi_InitCopyPaste(PFI f_copy, PFI f_paste, PFI f_clear, PFI f_error)
53 {
54     icccm_paste     = f_paste;
55     icccm_clear     = f_clear;
56     icccm_copy      = f_copy;
57     icccm_error     = f_error;
58 }
59 
60 
61 #if defined(__STDC__)
peekProc(Widget widget,void * data,Atom * selection,Atom * type,void * value,unsigned long * length,int * format)62 static    void      peekProc( Widget widget,
63                                 void *data,
64                                 Atom *selection,
65                                 Atom *type,
66                                 void *value,
67                                 unsigned long *length,
68                                 int *format
69                                 )
70 #else
71 static    void      peekProc( widget, data, selection, type, value, length, format )
72           Widget    widget;
73           void      *data;
74           Atom      *selection, *type;
75           void      *value;
76           unsigned long *length;
77           int       *format;
78 #endif
79 {
80     if ( *type == 0 )
81           (*icccm_error)( stderr, "Nothing in the primary selection buffer");
82     else if ( *type != XA_STRING )
83           (*icccm_error)( stderr, "Unknown type return from selection");
84     else
85           XtFree( value );
86 }
87 
88 
89 #if 0
90 #if defined(__STDC__)
91 void      _vi_AcquireClipboard( Widget wid )
92 #else
93 void      _vi_AcquireClipboard( wid )
94 Widget    wid;
95 #endif
96 {
97     XtGetSelectionValue( wid,
98                                XA_PRIMARY,
99                                XA_STRING,
100                                (XtSelectionCallbackProc) peekProc,
101                                NULL,
102                                XtLastTimestampProcessed( XtDisplay(wid) )
103                                );
104 }
105 #endif
106 
107 
108 #if defined(__STDC__)
loseProc(Widget widget)109 static    void      loseProc( Widget widget )
110 #else
111 static    void      loseProc( widget )
112           Widget    widget;
113 #endif
114 {
115     /* we have lost ownership of the selection.  clear it */
116     (*icccm_clear)( widget );
117 
118     /* also participate in the protocols */
119     XtDisownSelection(        widget,
120                               XA_PRIMARY,
121                               XtLastTimestampProcessed( XtDisplay(widget) )
122                               );
123 }
124 
125 
126 #if defined(__STDC__)
convertProc(Widget widget,Atom * selection,Atom * target,Atom * type,void ** value,int * length,int * format)127 static    int convertProc( Widget widget,
128                          Atom *selection,
129                          Atom *target,
130                          Atom *type,
131                          void **value,
132                          int *length,
133                          int *format
134                          )
135 #else
136 static    int convertProc( widget, selection, target, type, value, length, format )
137 Widget    widget;
138 Atom      *selection, *target, *type;
139 void      **value;
140 int       *length;
141 int       *format;
142 #endif
143 {
144     String          buffer;
145     int             len;
146 
147     /* someone wants a copy of the selection.  is there one? */
148     (*icccm_copy)( &buffer, &len );
149     if ( len == 0 ) return False;
150 
151     /* do they want the string? */
152     if ( *target == XA_STRING ) {
153           *length = len;
154           *value  = (void *) XtMalloc( len );
155           *type   = XA_STRING;
156           *format = 8;
157           memcpy( (char *) *value, buffer, *length );
158           return True;
159           }
160 
161     /* do they want the length? */
162     if ( *target == XInternAtom( XtDisplay(widget), "LENGTH", FALSE) ) {
163           *length = 1;
164           *value  = (void *) XtMalloc( sizeof(int) );
165           *type   = *target;
166           *format = 32;
167           * ((int *) *value) = len;
168           return True;
169           }
170 
171     /* we lose */
172     return False;
173 }
174 
175 /*
176  * __vi_AcquirePrimary --
177  *
178  * PUBLIC: void     __vi_AcquirePrimary __P((Widget));
179  */
180 void
__vi_AcquirePrimary(Widget widget)181 __vi_AcquirePrimary(Widget widget)
182 {
183     /* assert we own the primary selection */
184     XtOwnSelection( widget,
185                         XA_PRIMARY,
186                         XtLastTimestampProcessed( XtDisplay(widget) ),
187                         (XtConvertSelectionProc) convertProc,
188                         (XtLoseSelectionProc) loseProc,
189                         NULL
190                         );
191 
192 #if defined(OPENLOOK)
193     /* assert we also own the clipboard */
194     XtOwnSelection( widget,
195                         XA_CLIPBOARD( XtDisplay(widget) ),
196                         XtLastTimestampProcessed( XtDisplay(widget) ),
197                         convertProc,
198                         loseProc,
199                         NULL
200                         );
201 #endif
202 }
203 
204 
205 #if defined(__STDC__)
gotProc(Widget widget,void * data,Atom * selection,Atom * type,void * value,unsigned long * length,int * format)206 static    void      gotProc( Widget widget,
207                                void *data,
208                                Atom *selection,
209                                Atom *type,
210                                void *value,
211                                unsigned long *length,
212                                int *format
213                                )
214 #else
215 static    void      gotProc( widget, data, selection, type, value, length, format )
216           Widget    widget;
217           void      *data;
218           Atom      *selection, *type;
219           void      *value;
220           unsigned long *length;
221           int       *format;
222 #endif
223 {
224     if ( *type == 0 )
225           (*icccm_error)( stderr, "Nothing in the primary selection buffer");
226     else if ( *type != XA_STRING )
227           (*icccm_error)( stderr, "Unknown type return from selection");
228     else {
229           (*icccm_paste)( widget, value, *length );
230           XtFree( value );
231     }
232 }
233 
234 /*
235  * __vi_PasteFromClipboard --
236  *
237  * PUBLIC: void     __vi_PasteFromClipboard __P((Widget));
238  */
239 void
__vi_PasteFromClipboard(Widget widget)240 __vi_PasteFromClipboard(Widget widget)
241 {
242     XtGetSelectionValue( widget,
243                                XA_PRIMARY,
244                                XA_STRING,
245                                (XtSelectionCallbackProc) gotProc,
246                                NULL,
247                                XtLastTimestampProcessed( XtDisplay(widget) )
248                                );
249 }
250