1 #include "bcclipboard.h"
2 #include "bcwindowbase.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);
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),
24 out_win = XCreateSimpleWindow(out_display,
25 DefaultRootWindow(out_display),
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()
54 int BC_Clipboard::stop_clipboard()
57 XClientMessageEvent *ptr = (XClientMessageEvent*)&event;
59 event.type = ClientMessage;
60 ptr->message_type = completion_atom;
62 XSendEvent(out_display, out_win, 0, 0, &event);
68 void BC_Clipboard::run()
71 XClientMessageEvent *ptr;
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);
85 ptr = (XClientMessageEvent*)&event;
86 if(ptr->message_type == completion_atom)
90 //printf("ClientMessage %x %x %d\n", ptr->message_type, ptr->data.l[0], primary_atom);
94 case SelectionRequest:
95 handle_selectionrequest((XSelectionRequestEvent*)&event);
101 if(data[0]) data[0][0] = 0;
102 if(data[1]) data[1][0] = 0;
105 XUnlockDisplay(out_display);
109 void BC_Clipboard::handle_selectionrequest(XSelectionRequestEvent *request)
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);
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;
128 XSendEvent(out_display, request->requestor, 0, 0, &reply);
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,
143 (unsigned char*)data_ptr,
148 int BC_Clipboard::handle_request_targets(XSelectionRequestEvent *request)
154 XChangeProperty(out_display,
160 (unsigned char*)targets,
161 sizeof(targets)/sizeof(targets[0]));
162 //printf("BC_Clipboard::handle_request_targets\n");
166 int BC_Clipboard::to_clipboard(char *data, long len, int clipboard_num)
170 XStoreBuffer(display, data, len, clipboard_num);
173 XLockDisplay(out_display);
175 // Store in local buffer
176 if(this->data[clipboard_num] && length[clipboard_num] != len + 1)
178 delete [] this->data[clipboard_num];
179 this->data[clipboard_num] = 0;
182 if(!this->data[clipboard_num])
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;
190 XSetSelectionOwner(out_display,
191 (clipboard_num == PRIMARY_SELECTION) ? primary : secondary,
197 XUnlockDisplay(out_display);
201 int BC_Clipboard::from_clipboard(char *data, long maxlen, int clipboard_num)
209 data2 = XFetchBuffer(display, &len, clipboard_num);
210 for(i = 0; i < len && i < maxlen; i++)
220 XLockDisplay(in_display);
223 Atom type_return, pty;
225 unsigned long nitems, size, new_size, total;
228 pty = (clipboard_num == PRIMARY_SELECTION) ? primary : secondary;
229 /* a property of our window
230 for apps to put their
233 XConvertSelection(in_display,
234 clipboard_num == PRIMARY_SELECTION ? primary : secondary,
243 XNextEvent(in_display, &event);
244 }while(event.type != SelectionNotify && event.type != None);
246 if(event.type != None)
249 XGetWindowProperty(in_display,
260 (unsigned char**)&temp_data);
262 if(temp_data) XFree(temp_data);
266 XGetWindowProperty(in_display,
277 (unsigned char**)&temp_data);
280 if(type_return && temp_data)
282 strncpy(data, temp_data, maxlen);
288 if(temp_data) XFree(temp_data);
291 XUnlockDisplay(in_display);
296 long BC_Clipboard::clipboard_len(int clipboard_num)
303 data2 = XFetchBuffer(display, &len, clipboard_num);
310 XLockDisplay(in_display);
313 Atom type_return, pty;
315 unsigned long nitems, pty_size, total;
319 pty = (clipboard_num == PRIMARY_SELECTION) ? primary : secondary;
320 /* a property of our window
321 for apps to put their
323 XConvertSelection(in_display,
324 (clipboard_num == PRIMARY_SELECTION) ? primary : secondary,
332 XNextEvent(in_display, &event);
333 }while(event.type != SelectionNotify && event.type != None);
335 if(event.type != None)
338 XGetWindowProperty(in_display,
349 (unsigned char**)&temp_data);
353 result = pty_size + 1;
365 XUnlockDisplay(in_display);