Merge branch 'ct' of git.pipapo.org:cinelerra-ct into ct
[cinelerra_cv/ct.git] / guicast / bcclipboard.C
blob416edcd8be0f30eb918ae22b9f832cf949b1a64b
1 #include "bcclipboard.h"
2 #include "bcwindowbase.h"
3 #include <string.h>
5 BC_Clipboard::BC_Clipboard(char *display_name) : Thread()
7         Thread::set_synchronous(1);
9         in_display = BC_WindowBase::init_display(display_name);
10         out_display = BC_WindowBase::init_display(display_name);
11         completion_atom = XInternAtom(out_display, "BC_CLOSE_EVENT", False);
12         primary = XA_PRIMARY;
13         secondary = XInternAtom(out_display, "CLIPBOARD", False);
14         targets_atom = XInternAtom(out_display, "TARGETS", False);
15         in_win = XCreateSimpleWindow(in_display, 
16                                 DefaultRootWindow(in_display), 
17                                 0, 
18                                 0, 
19                                 1, 
20                                 1, 
21                                 0,
22                                 0,
23                                 0);
24         out_win = XCreateSimpleWindow(out_display, 
25                                 DefaultRootWindow(out_display), 
26                                 0, 
27                                 0, 
28                                 1, 
29                                 1, 
30                                 0,
31                                 0,
32                                 0);
33         data[0] = 0;
34         data[1] = 0;
37 BC_Clipboard::~BC_Clipboard()
39         if(data[0]) delete [] data[0];
40         if(data[1]) delete [] data[1];
42         XDestroyWindow(in_display, in_win);
43         XCloseDisplay(in_display);
44         XDestroyWindow(out_display, out_win);
45         XCloseDisplay(out_display);
48 int BC_Clipboard::start_clipboard()
50         Thread::start();
51         return 0;
54 int BC_Clipboard::stop_clipboard()
56         XEvent event;
57         XClientMessageEvent *ptr = (XClientMessageEvent*)&event;
59         event.type = ClientMessage;
60         ptr->message_type = completion_atom;
61         ptr->format = 32;
62         XSendEvent(out_display, out_win, 0, 0, &event);
63         XFlush(out_display);
64         Thread::join();
65         return 0;
68 void BC_Clipboard::run()
70         XEvent event;
71         XClientMessageEvent *ptr;
72         int done = 0;
74         while(!done)
75         {
76 //printf("BC_Clipboard::run 1\n");                                      
77                 XNextEvent(out_display, &event);
78 //printf("BC_Clipboard::run 2 %d\n", event.type);                                       
80                 XLockDisplay(out_display);
81                 switch(event.type)
82                 {
83 // Termination signal
84                         case ClientMessage:
85                                 ptr = (XClientMessageEvent*)&event;
86                                 if(ptr->message_type == completion_atom)
87                                 {
88                                         done = 1;
89                                 }
90 //printf("ClientMessage %x %x %d\n", ptr->message_type, ptr->data.l[0], primary_atom);
91                                 break;
94                         case SelectionRequest:
95                                 handle_selectionrequest((XSelectionRequestEvent*)&event);
96                                 break;
97                         
98                         
99                         
100                         case SelectionClear:
101                                 if(data[0]) data[0][0] = 0;
102                                 if(data[1]) data[1][0] = 0;
103                                 break;
104                 }
105                 XUnlockDisplay(out_display);
106         }
109 void BC_Clipboard::handle_selectionrequest(XSelectionRequestEvent *request)
111         int success = 0;
112         if (request->target == XA_STRING)
113                 success = handle_request_string(request);
114         else if (request->target == targets_atom)
115                 success = handle_request_targets(request);
117         XEvent reply;
118 // 'None' tells the client that the request was denied
119         reply.xselection.property  = success ? request->property : None;
120         reply.xselection.type      = SelectionNotify;
121         reply.xselection.display   = request->display;
122         reply.xselection.requestor = request->requestor;
123         reply.xselection.selection = request->selection;
124         reply.xselection.target    = request->target;
125         reply.xselection.time      = request->time;
126                                         
128         XSendEvent(out_display, request->requestor, 0, 0, &reply);
129         XFlush(out_display);
130 //printf("SelectionRequest\n");
133 int BC_Clipboard::handle_request_string(XSelectionRequestEvent *request)
135         char *data_ptr = (request->selection == primary ? data[0] : data[1]);
137         XChangeProperty(out_display,
138                         request->requestor,
139                         request->property,
140                         XA_STRING,
141                         8,
142                         PropModeReplace,
143                         (unsigned char*)data_ptr,
144                         strlen(data_ptr));
145         return 1;
148 int BC_Clipboard::handle_request_targets(XSelectionRequestEvent *request)
150         Atom targets[] = {
151                 targets_atom,
152                 XA_STRING
153         };
154         XChangeProperty(out_display,
155                         request->requestor,
156                         request->property,
157                         XA_ATOM,
158                         32,
159                         PropModeReplace,
160                         (unsigned char*)targets,
161                         sizeof(targets)/sizeof(targets[0]));
162 //printf("BC_Clipboard::handle_request_targets\n");
163         return 1;
166 int BC_Clipboard::to_clipboard(char *data, long len, int clipboard_num)
169 #if 0
170         XStoreBuffer(display, data, len, clipboard_num);
171 #endif
173         XLockDisplay(out_display);
175 // Store in local buffer
176         if(this->data[clipboard_num] && length[clipboard_num] != len + 1)
177         {
178                 delete [] this->data[clipboard_num];
179                 this->data[clipboard_num] = 0;
180         }
182         if(!this->data[clipboard_num])
183         {
184                 length[clipboard_num] = len;
185                 this->data[clipboard_num] = new char[len + 1];
186                 memcpy(this->data[clipboard_num], data, len);
187                 this->data[clipboard_num][len] = 0;
188         }
190         XSetSelectionOwner(out_display, 
191                 (clipboard_num == PRIMARY_SELECTION) ? primary : secondary, 
192                 out_win, 
193                 CurrentTime);
195         XFlush(out_display);
197         XUnlockDisplay(out_display);
198         return 0;
201 int BC_Clipboard::from_clipboard(char *data, long maxlen, int clipboard_num)
206 #if 0
207         char *data2;
208         int len, i;
209         data2 = XFetchBuffer(display, &len, clipboard_num);
210         for(i = 0; i < len && i < maxlen; i++)
211                 data[i] = data2[i];
213         data[i] = 0;
215         XFree(data2);
217 #endif
220         XLockDisplay(in_display);
222         XEvent event;
223     Atom type_return, pty;
224     int format;
225     unsigned long nitems, size, new_size, total;
226         char *temp_data = 0;
228     pty = (clipboard_num == PRIMARY_SELECTION) ? primary : secondary; 
229                                                 /* a property of our window
230                                                    for apps to put their
231                                                    selection into */
233         XConvertSelection(in_display, 
234                 clipboard_num == PRIMARY_SELECTION ? primary : secondary, 
235                 XA_STRING, 
236                 pty,
237         in_win, 
238                 CurrentTime);
240         data[0] = 0;
241         do
242         {
243                 XNextEvent(in_display, &event);
244         }while(event.type != SelectionNotify && event.type != None);
246         if(event.type != None)
247         {
248 // Get size
249         XGetWindowProperty(in_display,
250                 in_win,
251                 pty,
252                 0,
253                 0,
254                 False,
255                 AnyPropertyType,
256                 &type_return,
257                 &format,
258                 &nitems,
259                 &size,
260                 (unsigned char**)&temp_data);
262         if(temp_data) XFree(temp_data);
263         temp_data = 0;
265 // Get data
266         XGetWindowProperty(in_display,
267                 in_win,
268                 pty,
269                 0,
270                 size,
271                 False,
272                 AnyPropertyType,
273                 &type_return,
274                 &format,
275                 &nitems,
276                 &new_size,
277                 (unsigned char**)&temp_data);
280                 if(type_return && temp_data)
281                 {
282                         strncpy(data, temp_data, maxlen);
283                         data[size] = 0;
284                 }
285                 else
286                         data[0] = 0;
288                 if(temp_data) XFree(temp_data);
289         }
291         XUnlockDisplay(in_display);
293         return 0;
296 long BC_Clipboard::clipboard_len(int clipboard_num)
299 #if 0
300         char *data2;
301         int len;
303         data2 = XFetchBuffer(display, &len, clipboard_num);
304         XFree(data2);
305         return len;
306 #endif
310         XLockDisplay(in_display);
312         XEvent event;
313     Atom type_return, pty;
314     int format;
315     unsigned long nitems, pty_size, total;
316         char *temp_data = 0;
317         int result = 0;
319     pty = (clipboard_num == PRIMARY_SELECTION) ? primary : secondary; 
320                                                 /* a property of our window
321                                                    for apps to put their
322                                                    selection into */
323         XConvertSelection(in_display, 
324                 (clipboard_num == PRIMARY_SELECTION) ? primary : secondary, 
325                 XA_STRING, 
326                 pty,
327         in_win, 
328                 CurrentTime);
330         do
331         {
332                 XNextEvent(in_display, &event);
333         }while(event.type != SelectionNotify && event.type != None);
335         if(event.type != None)
336         {
337 // Get size
338         XGetWindowProperty(in_display,
339                 in_win,
340                 pty,
341                 0,
342                 0,
343                 False,
344                 AnyPropertyType,
345                 &type_return,
346                 &format,
347                 &nitems,
348                 &pty_size,
349                 (unsigned char**)&temp_data);
351                 if(type_return)
352                 {
353                         result = pty_size + 1;
354                 }
355                 else
356                         result = 0;
360                 if(temp_data)
361                         XFree(temp_data);
363         }
365         XUnlockDisplay(in_display);
367         return result;
370 //      Local Variables:
371 //      mode: C++
372 //      c-file-style: "linux"
373 //      End: