00001 #include "bcclipboard.h"
00002 #include "bcwindowbase.h"
00003 #include <string.h>
00004
00005 BC_Clipboard::BC_Clipboard(char *display_name) : Thread()
00006 {
00007 Thread::set_synchronous(1);
00008
00009 in_display = BC_WindowBase::init_display(display_name);
00010 out_display = BC_WindowBase::init_display(display_name);
00011 completion_atom = XInternAtom(out_display, "BC_CLOSE_EVENT", False);
00012 primary = XA_PRIMARY;
00013 secondary = XInternAtom(out_display, "CLIPBOARD", False);
00014 in_win = XCreateSimpleWindow(in_display,
00015 DefaultRootWindow(in_display),
00016 0,
00017 0,
00018 1,
00019 1,
00020 0,
00021 0,
00022 0);
00023 out_win = XCreateSimpleWindow(out_display,
00024 DefaultRootWindow(out_display),
00025 0,
00026 0,
00027 1,
00028 1,
00029 0,
00030 0,
00031 0);
00032 data[0] = 0;
00033 data[1] = 0;
00034 }
00035
00036 BC_Clipboard::~BC_Clipboard()
00037 {
00038 if(data[0]) delete [] data[0];
00039 if(data[1]) delete [] data[1];
00040
00041 XDestroyWindow(in_display, in_win);
00042 XCloseDisplay(in_display);
00043 XDestroyWindow(out_display, out_win);
00044 XCloseDisplay(out_display);
00045 }
00046
00047 int BC_Clipboard::start_clipboard()
00048 {
00049 Thread::start();
00050 return 0;
00051 }
00052
00053 int BC_Clipboard::stop_clipboard()
00054 {
00055 XEvent event;
00056 XClientMessageEvent *ptr = (XClientMessageEvent*)&event;
00057
00058 event.type = ClientMessage;
00059 ptr->message_type = completion_atom;
00060 ptr->format = 32;
00061 XSendEvent(out_display, out_win, 0, 0, &event);
00062 XFlush(out_display);
00063 Thread::join();
00064 return 0;
00065 }
00066
00067 void BC_Clipboard::run()
00068 {
00069 XEvent event;
00070 XClientMessageEvent *ptr;
00071 int done = 0;
00072
00073 while(!done)
00074 {
00075
00076 XNextEvent(out_display, &event);
00077
00078
00079 XLockDisplay(out_display);
00080 switch(event.type)
00081 {
00082
00083 case ClientMessage:
00084 ptr = (XClientMessageEvent*)&event;
00085 if(ptr->message_type == completion_atom)
00086 {
00087 done = 1;
00088 }
00089
00090 break;
00091
00092
00093 case SelectionRequest:
00094 {
00095 XEvent reply;
00096 XSelectionRequestEvent *request = (XSelectionRequestEvent*)&event;
00097 char *data_ptr = (request->selection == primary ? data[0] : data[1]);
00098
00099
00100 XChangeProperty(out_display,
00101 request->requestor,
00102 request->property,
00103 XA_STRING,
00104 8,
00105 PropModeReplace,
00106 (unsigned char*)data_ptr,
00107 strlen(data_ptr));
00108
00109 reply.xselection.property = request->property;
00110 reply.xselection.type = SelectionNotify;
00111 reply.xselection.display = request->display;
00112 reply.xselection.requestor = request->requestor;
00113 reply.xselection.selection = request->selection;
00114 reply.xselection.target = request->target;
00115 reply.xselection.time = request->time;
00116
00117
00118 XSendEvent(out_display, request->requestor, 0, 0, &reply);
00119 XFlush(out_display);
00120 }
00121
00122 break;
00123
00124
00125
00126 case SelectionClear:
00127 if(data[0]) data[0][0] = 0;
00128 if(data[1]) data[1][0] = 0;
00129 break;
00130 }
00131 XUnlockDisplay(out_display);
00132 }
00133 }
00134
00135 int BC_Clipboard::to_clipboard(char *data, long len, int clipboard_num)
00136 {
00137
00138 #if 0
00139 XStoreBuffer(display, data, len, clipboard_num);
00140 #endif
00141
00142 XLockDisplay(out_display);
00143
00144
00145 if(this->data[clipboard_num] && length[clipboard_num] != len + 1)
00146 {
00147 delete [] this->data[clipboard_num];
00148 this->data[clipboard_num] = 0;
00149 }
00150
00151 if(!this->data[clipboard_num])
00152 {
00153 length[clipboard_num] = len;
00154 this->data[clipboard_num] = new char[len + 1];
00155 memcpy(this->data[clipboard_num], data, len);
00156 this->data[clipboard_num][len] = 0;
00157 }
00158
00159 XSetSelectionOwner(out_display,
00160 (clipboard_num == PRIMARY_SELECTION) ? primary : secondary,
00161 out_win,
00162 CurrentTime);
00163
00164 XFlush(out_display);
00165
00166 XUnlockDisplay(out_display);
00167 return 0;
00168 }
00169
00170 int BC_Clipboard::from_clipboard(char *data, long maxlen, int clipboard_num)
00171 {
00172
00173
00174
00175 #if 0
00176 char *data2;
00177 int len, i;
00178 data2 = XFetchBuffer(display, &len, clipboard_num);
00179 for(i = 0; i < len && i < maxlen; i++)
00180 data[i] = data2[i];
00181
00182 data[i] = 0;
00183
00184 XFree(data2);
00185
00186 #endif
00187
00188
00189 XLockDisplay(in_display);
00190
00191 XEvent event;
00192 Atom type_return, pty;
00193 int format;
00194 unsigned long nitems, size, new_size, total;
00195 char *temp_data = 0;
00196
00197 pty = (clipboard_num == PRIMARY_SELECTION) ? primary : secondary;
00198
00199
00200
00201
00202 XConvertSelection(in_display,
00203 clipboard_num == PRIMARY_SELECTION ? primary : secondary,
00204 XA_STRING,
00205 pty,
00206 in_win,
00207 CurrentTime);
00208
00209 data[0] = 0;
00210 do
00211 {
00212 XNextEvent(in_display, &event);
00213 }while(event.type != SelectionNotify && event.type != None);
00214
00215 if(event.type != None)
00216 {
00217
00218 XGetWindowProperty(in_display,
00219 in_win,
00220 pty,
00221 0,
00222 0,
00223 False,
00224 AnyPropertyType,
00225 &type_return,
00226 &format,
00227 &nitems,
00228 &size,
00229 (unsigned char**)&temp_data);
00230
00231 if(temp_data) XFree(temp_data);
00232 temp_data = 0;
00233
00234
00235 XGetWindowProperty(in_display,
00236 in_win,
00237 pty,
00238 0,
00239 size,
00240 False,
00241 AnyPropertyType,
00242 &type_return,
00243 &format,
00244 &nitems,
00245 &new_size,
00246 (unsigned char**)&temp_data);
00247
00248
00249 if(type_return && temp_data)
00250 {
00251 strncpy(data, temp_data, maxlen);
00252 data[size] = 0;
00253 }
00254 else
00255 data[0] = 0;
00256
00257 if(temp_data) XFree(temp_data);
00258 }
00259
00260 XUnlockDisplay(in_display);
00261
00262 return 0;
00263 }
00264
00265 long BC_Clipboard::clipboard_len(int clipboard_num)
00266 {
00267
00268 #if 0
00269 char *data2;
00270 int len;
00271
00272 data2 = XFetchBuffer(display, &len, clipboard_num);
00273 XFree(data2);
00274 return len;
00275 #endif
00276
00277
00278
00279 XLockDisplay(in_display);
00280
00281 XEvent event;
00282 Atom type_return, pty;
00283 int format;
00284 unsigned long nitems, pty_size, total;
00285 char *temp_data = 0;
00286 int result = 0;
00287
00288 pty = (clipboard_num == PRIMARY_SELECTION) ? primary : secondary;
00289
00290
00291
00292 XConvertSelection(in_display,
00293 (clipboard_num == PRIMARY_SELECTION) ? primary : secondary,
00294 XA_STRING,
00295 pty,
00296 in_win,
00297 CurrentTime);
00298
00299 do
00300 {
00301 XNextEvent(in_display, &event);
00302 }while(event.type != SelectionNotify && event.type != None);
00303
00304 if(event.type != None)
00305 {
00306
00307 XGetWindowProperty(in_display,
00308 in_win,
00309 pty,
00310 0,
00311 0,
00312 False,
00313 AnyPropertyType,
00314 &type_return,
00315 &format,
00316 &nitems,
00317 &pty_size,
00318 (unsigned char**)&temp_data);
00319
00320 if(type_return)
00321 {
00322 result = pty_size + 1;
00323 }
00324 else
00325 result = 0;
00326
00327
00328
00329 if(temp_data)
00330 XFree(temp_data);
00331
00332 }
00333
00334 XUnlockDisplay(in_display);
00335
00336 return result;
00337 }