r885: Don't delete a borrowed frame.
[cinelerra_cv/ct.git] / guicast / bcclipboard.C
blob190eaae9efcadff6ba23919850caa91aedfe073a
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         in_win = XCreateSimpleWindow(in_display, 
15                                 DefaultRootWindow(in_display), 
16                                 0, 
17                                 0, 
18                                 1, 
19                                 1, 
20                                 0,
21                                 0,
22                                 0);
23         out_win = XCreateSimpleWindow(out_display, 
24                                 DefaultRootWindow(out_display), 
25                                 0, 
26                                 0, 
27                                 1, 
28                                 1, 
29                                 0,
30                                 0,
31                                 0);
32         data[0] = 0;
33         data[1] = 0;
36 BC_Clipboard::~BC_Clipboard()
38         if(data[0]) delete [] data[0];
39         if(data[1]) delete [] data[1];
41         XDestroyWindow(in_display, in_win);
42         XCloseDisplay(in_display);
43         XDestroyWindow(out_display, out_win);
44         XCloseDisplay(out_display);
47 int BC_Clipboard::start_clipboard()
49         Thread::start();
50         return 0;
53 int BC_Clipboard::stop_clipboard()
55         XEvent event;
56         XClientMessageEvent *ptr = (XClientMessageEvent*)&event;
58         event.type = ClientMessage;
59         ptr->message_type = completion_atom;
60         ptr->format = 32;
61         XSendEvent(out_display, out_win, 0, 0, &event);
62         XFlush(out_display);
63         Thread::join();
64         return 0;
67 void BC_Clipboard::run()
69         XEvent event;
70         XClientMessageEvent *ptr;
71         int done = 0;
73         while(!done)
74         {
75 //printf("BC_Clipboard::run 1\n");                                      
76                 XNextEvent(out_display, &event);
77 //printf("BC_Clipboard::run 2 %d\n", event.type);                                       
79                 XLockDisplay(out_display);
80                 switch(event.type)
81                 {
82 // Termination signal
83                         case ClientMessage:
84                                 ptr = (XClientMessageEvent*)&event;
85                                 if(ptr->message_type == completion_atom)
86                                 {
87                                         done = 1;
88                                 }
89 //printf("ClientMessage %x %x %d\n", ptr->message_type, ptr->data.l[0], primary_atom);
90                                 break;
93                         case SelectionRequest:
94                                 {
95                                         XEvent reply;
96                                         XSelectionRequestEvent *request = (XSelectionRequestEvent*)&event;
97                                         char *data_ptr = (request->selection == primary ? data[0] : data[1]);
99 //printf("BC_Clipboard::run 2\n");                                      
100                                 XChangeProperty(out_display,
101                                         request->requestor,
102                                         request->property,
103                                         XA_STRING,
104                                         8,
105                                         PropModeReplace,
106                                         (unsigned char*)data_ptr,
107                                         strlen(data_ptr));
108                                         
109                                 reply.xselection.property  = request->property;
110                                 reply.xselection.type      = SelectionNotify;
111                                 reply.xselection.display   = request->display;
112                                 reply.xselection.requestor = request->requestor;
113                                 reply.xselection.selection = request->selection;
114                                 reply.xselection.target    = request->target;
115                                 reply.xselection.time      = request->time;
116                                         
118                                         XSendEvent(out_display, request->requestor, 0, 0, &reply);
119                                         XFlush(out_display);
120                                 }
121 //printf("SelectionRequest\n");
122                                 break;
123                         
124                         
125                         
126                         case SelectionClear:
127                                 if(data[0]) data[0][0] = 0;
128                                 if(data[1]) data[1][0] = 0;
129                                 break;
130                 }
131                 XUnlockDisplay(out_display);
132         }
135 int BC_Clipboard::to_clipboard(char *data, long len, int clipboard_num)
138 #if 0
139         XStoreBuffer(display, data, len, clipboard_num);
140 #endif
142         XLockDisplay(out_display);
144 // Store in local buffer
145         if(this->data[clipboard_num] && length[clipboard_num] != len + 1)
146         {
147                 delete [] this->data[clipboard_num];
148                 this->data[clipboard_num] = 0;
149         }
151         if(!this->data[clipboard_num])
152         {
153                 length[clipboard_num] = len;
154                 this->data[clipboard_num] = new char[len + 1];
155                 memcpy(this->data[clipboard_num], data, len);
156                 this->data[clipboard_num][len] = 0;
157         }
159         XSetSelectionOwner(out_display, 
160                 (clipboard_num == PRIMARY_SELECTION) ? primary : secondary, 
161                 out_win, 
162                 CurrentTime);
164         XFlush(out_display);
166         XUnlockDisplay(out_display);
167         return 0;
170 int BC_Clipboard::from_clipboard(char *data, long maxlen, int clipboard_num)
175 #if 0
176         char *data2;
177         int len, i;
178         data2 = XFetchBuffer(display, &len, clipboard_num);
179         for(i = 0; i < len && i < maxlen; i++)
180                 data[i] = data2[i];
182         data[i] = 0;
184         XFree(data2);
186 #endif
189         XLockDisplay(in_display);
191         XEvent event;
192     Atom type_return, pty;
193     int format;
194     unsigned long nitems, size, new_size, total;
195         char *temp_data = 0;
197     pty = (clipboard_num == PRIMARY_SELECTION) ? primary : secondary; 
198                                                 /* a property of our window
199                                                    for apps to put their
200                                                    selection into */
202         XConvertSelection(in_display, 
203                 clipboard_num == PRIMARY_SELECTION ? primary : secondary, 
204                 XA_STRING, 
205                 pty,
206         in_win, 
207                 CurrentTime);
209         data[0] = 0;
210         do
211         {
212                 XNextEvent(in_display, &event);
213         }while(event.type != SelectionNotify && event.type != None);
215         if(event.type != None)
216         {
217 // Get size
218         XGetWindowProperty(in_display,
219                 in_win,
220                 pty,
221                 0,
222                 0,
223                 False,
224                 AnyPropertyType,
225                 &type_return,
226                 &format,
227                 &nitems,
228                 &size,
229                 (unsigned char**)&temp_data);
231         if(temp_data) XFree(temp_data);
232         temp_data = 0;
234 // Get data
235         XGetWindowProperty(in_display,
236                 in_win,
237                 pty,
238                 0,
239                 size,
240                 False,
241                 AnyPropertyType,
242                 &type_return,
243                 &format,
244                 &nitems,
245                 &new_size,
246                 (unsigned char**)&temp_data);
249                 if(type_return && temp_data)
250                 {
251                         strncpy(data, temp_data, maxlen);
252                         data[size] = 0;
253                 }
254                 else
255                         data[0] = 0;
257                 if(temp_data) XFree(temp_data);
258         }
260         XUnlockDisplay(in_display);
262         return 0;
265 long BC_Clipboard::clipboard_len(int clipboard_num)
268 #if 0
269         char *data2;
270         int len;
272         data2 = XFetchBuffer(display, &len, clipboard_num);
273         XFree(data2);
274         return len;
275 #endif
279         XLockDisplay(in_display);
281         XEvent event;
282     Atom type_return, pty;
283     int format;
284     unsigned long nitems, pty_size, total;
285         char *temp_data = 0;
286         int result = 0;
288     pty = (clipboard_num == PRIMARY_SELECTION) ? primary : secondary; 
289                                                 /* a property of our window
290                                                    for apps to put their
291                                                    selection into */
292         XConvertSelection(in_display, 
293                 (clipboard_num == PRIMARY_SELECTION) ? primary : secondary, 
294                 XA_STRING, 
295                 pty,
296         in_win, 
297                 CurrentTime);
299         do
300         {
301                 XNextEvent(in_display, &event);
302         }while(event.type != SelectionNotify && event.type != None);
304         if(event.type != None)
305         {
306 // Get size
307         XGetWindowProperty(in_display,
308                 in_win,
309                 pty,
310                 0,
311                 0,
312                 False,
313                 AnyPropertyType,
314                 &type_return,
315                 &format,
316                 &nitems,
317                 &pty_size,
318                 (unsigned char**)&temp_data);
320                 if(type_return)
321                 {
322                         result = pty_size + 1;
323                 }
324                 else
325                         result = 0;
329                 if(temp_data)
330                         XFree(temp_data);
332         }
334         XUnlockDisplay(in_display);
336         return result;