From: Good Guy Date: Wed, 23 Aug 2017 19:17:47 +0000 (-0600) Subject: clipboard rework, C41/titler fixes, displayinfo tweak X-Git-Url: https://git.cinelerra-gg.org/git/?a=commitdiff_plain;h=65eb7d06c462c2caaa7fabcb8956add9e6b8abc7;p=goodguy%2Fhistory.git clipboard rework, C41/titler fixes, displayinfo tweak --- diff --git a/cinelerra-5.1/bld_scripts/bld_prepare.sh b/cinelerra-5.1/bld_scripts/bld_prepare.sh index 8aea5d83..028a0071 100755 --- a/cinelerra-5.1/bld_scripts/bld_prepare.sh +++ b/cinelerra-5.1/bld_scripts/bld_prepare.sh @@ -24,9 +24,9 @@ case "$dir" in libavc1394 festival-devel libiec61883-devel flac-devel inkscape \ libsndfile-devel libtheora-devel linux-firmware ivtv-firmware \ libvorbis-devel texinfo xz-devel lzma-devel cmake udftools git \ - autoconf automake rpm-build jbigkit-devel libvdpau-devel - yasm=yasm-1.2.0-7.fc21.x86_64.rpm - release=http://archives.fedoraproject.org/pub/fedora/linux/releases/21 + autoconf automake rpm-build jbigkit-devel libvdpau-devel alsa-lib-devel + yasm=yasm-1.3.0-3.fc24.x86_64.rpm + release=http://archives.fedoraproject.org/pub/fedora/linux/releases/24 url=$release/Everything/x86_64/os/Packages/y/$yasm wget -P /tmp $url yum -y install /tmp/$yasm diff --git a/cinelerra-5.1/cinelerra/clippopup.C b/cinelerra-5.1/cinelerra/clippopup.C index cbd7ca04..4fd6af69 100644 --- a/cinelerra-5.1/cinelerra/clippopup.C +++ b/cinelerra-5.1/cinelerra/clippopup.C @@ -253,10 +253,8 @@ int ClipPopupCopy::handle_event() edl->copy(start, end, 1, 0, 0, &file, "", 1); const char *file_string = file.string(); long file_length = strlen(file_string); - gui->get_clipboard()->to_clipboard(file_string, file_length, - SECONDARY_SELECTION); - gui->get_clipboard()->to_clipboard(file_string, file_length, - BC_PRIMARY_SELECTION); + gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION); + gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION); } gui->unlock_window(); return 1; @@ -354,10 +352,10 @@ int ClipPasteToFolder::handle_event() { MWindowGUI *gui = mwindow->gui; gui->lock_window("ClipPasteToFolder::handle_event 1"); - int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION); + int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION); if( len ) { char *string = new char[len + 1]; - gui->get_clipboard()->from_clipboard(string, len, BC_PRIMARY_SELECTION); + gui->from_clipboard(string, len, BC_PRIMARY_SELECTION); const char *clip_header = "get_clipboard()->to_clipboard(file_string, file_length, - SECONDARY_SELECTION); - gui->get_clipboard()->to_clipboard(file_string, file_length, - BC_PRIMARY_SELECTION); + gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION); + gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION); save_backup(); return 0; } @@ -443,10 +441,8 @@ int MWindow::copy_automation() edl->tracks->copy_automation(start, end, &file, 0, 1); const char *file_string = file.string(); long file_length = strlen(file_string); - gui->get_clipboard()->to_clipboard(file_string, file_length, - BC_PRIMARY_SELECTION); - gui->get_clipboard()->to_clipboard(file_string, file_length, - SECONDARY_SELECTION); + gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION); + gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION); return 0; } @@ -458,10 +454,8 @@ int MWindow::copy_default_keyframe() edl->tracks->copy_automation(start, end, &file, 1, 0); const char *file_string = file.string(); long file_length = strlen(file_string); - gui->get_clipboard()->to_clipboard(file_string, file_length, - BC_PRIMARY_SELECTION); - gui->get_clipboard()->to_clipboard(file_string, file_length, - SECONDARY_SELECTION); + gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION); + gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION); return 0; } @@ -1087,12 +1081,12 @@ void MWindow::paste() { double start = edl->local_session->get_selectionstart(); //double end = edl->local_session->get_selectionend(); - int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION); + int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION); if( len ) { char *string = new char[len + 1]; undo->update_undo_before(); - gui->get_clipboard()->from_clipboard(string, len, BC_PRIMARY_SELECTION); + gui->from_clipboard(string, len, BC_PRIMARY_SELECTION); FileXML file; file.read_from_string(string); clear(0); @@ -1205,14 +1199,12 @@ if( debug ) printf("MWindow::load_assets %d\n", __LINE__); int MWindow::paste_automation() { - int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION); + int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION); if( len ) { undo->update_undo_before(); char *string = new char[len + 1]; - gui->get_clipboard()->from_clipboard(string, - len, - BC_PRIMARY_SELECTION); + gui->from_clipboard(string, len, BC_PRIMARY_SELECTION); FileXML file; file.read_from_string(string); @@ -1238,14 +1230,12 @@ int MWindow::paste_automation() int MWindow::paste_default_keyframe() { - int64_t len = gui->get_clipboard()->clipboard_len(SECONDARY_SELECTION); + int64_t len = gui->clipboard_len(BC_PRIMARY_SELECTION); if( len ) { undo->update_undo_before(); char *string = new char[len + 1]; - gui->get_clipboard()->from_clipboard(string, - len, - BC_PRIMARY_SELECTION); + gui->from_clipboard(string, len, BC_PRIMARY_SELECTION); FileXML file; file.read_from_string(string); double start = edl->local_session->get_selectionstart(); diff --git a/cinelerra-5.1/cinelerra/vwindow.C b/cinelerra-5.1/cinelerra/vwindow.C index 2f96447c..45dacc0b 100644 --- a/cinelerra-5.1/cinelerra/vwindow.C +++ b/cinelerra-5.1/cinelerra/vwindow.C @@ -425,10 +425,8 @@ void VWindow::copy() const char *file_string = file.string(); long file_length = strlen(file_string); mwindow->gui->lock_window(); - mwindow->gui->get_clipboard()->to_clipboard(file_string, file_length, - SECONDARY_SELECTION); - mwindow->gui->get_clipboard()->to_clipboard(file_string, file_length, - BC_PRIMARY_SELECTION); + mwindow->gui->to_clipboard(file_string, file_length, BC_PRIMARY_SELECTION); + mwindow->gui->to_clipboard(file_string, file_length, SECONDARY_SELECTION); mwindow->gui->unlock_window(); } } diff --git a/cinelerra-5.1/guicast/bcclipboard.C b/cinelerra-5.1/guicast/bcclipboard.C index 7c201af8..4ef144bc 100644 --- a/cinelerra-5.1/guicast/bcclipboard.C +++ b/cinelerra-5.1/guicast/bcclipboard.C @@ -28,13 +28,11 @@ #include #include -BC_Clipboard::BC_Clipboard(const char *display_name) +BC_Clipboard::BC_Clipboard(BC_WindowBase *window) : Thread(1, 0, 0) { - if(display_name) - strcpy(this->display_name, display_name); - else - this->display_name[0] = 0; + this->window = window; + const char *display_name = window->display_name; #ifdef SINGLE_THREAD in_display = out_display = BC_Display::get_display(display_name); @@ -44,28 +42,27 @@ BC_Clipboard::BC_Clipboard(const char *display_name) #endif completion_atom = XInternAtom(out_display, "BC_CLOSE_EVENT", False); - primary = XA_PRIMARY; - secondary = XInternAtom(out_display, "CLIPBOARD", False); - targets_atom = XInternAtom(out_display, "TARGETS", False); - if(BC_Resources::locale_utf8) - strtype_atom = XInternAtom(out_display, "UTF8_STRING", False); - else - strtype_atom = XA_STRING; + xa_primary = XA_PRIMARY; + clipboard = XInternAtom(out_display, "CLIPBOARD", False); + targets = XInternAtom(out_display, "TARGETS", False); + string_type = !BC_Resources::locale_utf8 ? XA_STRING : + XInternAtom(out_display, "UTF8_STRING", False); in_win = XCreateSimpleWindow(in_display, - DefaultRootWindow(in_display), - 0, 0, 1, 1, 0, 0, 0); + DefaultRootWindow(in_display), 0, 0, 1, 1, 0, 0, 0); out_win = XCreateSimpleWindow(out_display, - DefaultRootWindow(out_display), - 0, 0, 1, 1, 0, 0, 0); - data[0] = 0; - data[1] = 0; + DefaultRootWindow(out_display), 0, 0, 1, 1, 0, 0, 0); + + for( int i=0; idisplay_name; Display *display = BC_WindowBase::init_display(display_name); XEvent event; memset(&event, 0, sizeof(event)); XClientMessageEvent *ptr = (XClientMessageEvent*)&event; @@ -96,7 +100,6 @@ int BC_Clipboard::stop_clipboard() event.type = ClientMessage; ptr->message_type = completion_atom; ptr->format = 32; -//printf("BC_Clipboard::stop_clipboard %d\n", __LINE__); XSendEvent(display, out_win, 0, 0, &event); XFlush(display); XCloseDisplay(display); @@ -108,14 +111,12 @@ int BC_Clipboard::stop_clipboard() void BC_Clipboard::run() { XEvent event; - XClientMessageEvent *ptr; int done = 0; #ifndef SINGLE_THREAD int x_fd = ConnectionNumber(out_display); #endif - while(!done) - { + while(!done) { #ifndef SINGLE_THREAD // see bcwindowevents.C regarding XNextEvent fd_set x_fds; @@ -126,323 +127,204 @@ void BC_Clipboard::run() select(x_fd + 1, &x_fds, 0, 0, &tv); XLockDisplay(out_display); - while(XPending(out_display)) - { + while( XPending(out_display) ) { #endif -//printf("BC_Clipboard::run 1\n"); XNextEvent(out_display, &event); -//printf("BC_Clipboard::run 2 %d\n", event.type); #ifdef SINGLE_THREAD BC_Display::lock_display("BC_Clipboard::run"); #endif - switch(event.type) - { -// Termination signal + switch( event.type ) { case ClientMessage: - ptr = (XClientMessageEvent*)&event; - if(ptr->message_type == completion_atom) - { + if( event.xclient.message_type == completion_atom ) done = 1; - } -//printf("ClientMessage %x %x %d\n", ptr->message_type, ptr->data.l[0], primary_atom); break; - case SelectionRequest: - handle_selectionrequest((XSelectionRequestEvent*)&event); + handle_selectionrequest(&event.xselectionrequest); break; - case SelectionClear: - if(data[0]) data[0][0] = 0; - if(data[1]) data[1][0] = 0; - break; - } + case SelectionClear: { + Atom selection = event.xselectionclear.selection; + int idx = + selection == xa_primary ? CLIP_PRIMARY : + selection == clipboard ? CLIP_CLIPBOARD : -1 ; + if( idx < 0 ) break; + delete [] data_buffer[idx]; + data_buffer[idx] = 0; + data_length[idx] = 0; + Window win = event.xselectionclear.window; +#ifndef SINGLE_THREAD + XUnlockDisplay(out_display); +#endif + window->lock_window("BC_Clipboard::run"); + window->do_selection_clear(win); + window->unlock_window(); #ifndef SINGLE_THREAD + XLockDisplay(out_display); +#endif + break; } + } +#ifdef SINGLE_THREAD + BC_Display::unlock_display(); +#else } XUnlockDisplay(out_display); -#else - BC_Display::unlock_display(); #endif } } -void BC_Clipboard::handle_selectionrequest(XSelectionRequestEvent *request) -{ - int success = 0; - if (request->target == strtype_atom) - success = handle_request_string(request); - else if (request->target == targets_atom) - success = handle_request_targets(request); - - XEvent reply; memset(&reply, 0, sizeof(reply)); -// 'None' tells the client that the request was denied - reply.xselection.property = success ? request->property : None; - reply.xselection.type = SelectionNotify; - reply.xselection.display = request->display; - reply.xselection.requestor = request->requestor; - reply.xselection.selection = request->selection; - reply.xselection.target = request->target; - reply.xselection.time = request->time; - - - XSendEvent(out_display, request->requestor, 0, 0, &reply); - XFlush(out_display); -//printf("SelectionRequest\n"); -} - -int BC_Clipboard::handle_request_string(XSelectionRequestEvent *request) +long BC_Clipboard::from_clipboard(char *data, long maxlen, int clipboard_num) { - char *data_ptr = (request->selection == primary ? data[0] : data[1]); - - XChangeProperty(out_display, - request->requestor, - request->property, - strtype_atom, - 8, - PropModeReplace, - (unsigned char*)data_ptr, - strlen(data_ptr)); - return 1; + if( !data || maxlen <= 0 ) return -1; + data[0] = 0; + char *bfr; + long len = from_clipboard(clipboard_num, bfr, maxlen); + if( len >= maxlen ) len = maxlen-1; + if( bfr && len >= 0 ) { + strncpy(data, bfr, len); + data[len] = 0; + } + if( bfr ) XFree(bfr); + return len; } -int BC_Clipboard::handle_request_targets(XSelectionRequestEvent *request) +long BC_Clipboard::clipboard_len(int clipboard_num) { - Atom targets[] = { - targets_atom, - strtype_atom - }; - XChangeProperty(out_display, - request->requestor, - request->property, - XA_ATOM, - 32, - PropModeReplace, - (unsigned char*)targets, - sizeof(targets)/sizeof(targets[0])); -//printf("BC_Clipboard::handle_request_targets\n"); - return 1; + char *bfr; + long len = from_clipboard(clipboard_num, bfr, 0); + if( bfr ) XFree(bfr); + return len < 0 ? 0 : len; } -int BC_Clipboard::to_clipboard(const char *data, long len, int clipboard_num) +long BC_Clipboard::from_clipboard(int clipboard_num, char *&bfr, long maxlen) { -//printf("BC_Clipboard::to_clipboard %d: %d '%*.*s'\n",clipboard_num,len,len,len,data); - if(clipboard_num == BC_PRIMARY_SELECTION) - { - XStoreBuffer(out_display, data, len, clipboard_num); - return 0; - } - #ifdef SINGLE_THREAD - BC_Display::lock_display("BC_Clipboard::to_clipboard"); + BC_Display::lock_display("BC_Clipboard::from_clipboard"); #else - XLockDisplay(out_display); + XLockDisplay(in_display); #endif -// Store in local buffer - if(this->data[clipboard_num] && length[clipboard_num] != len) - { - delete [] this->data[clipboard_num]; - this->data[clipboard_num] = 0; - } - - if(!this->data[clipboard_num]) - { - length[clipboard_num] = len; - this->data[clipboard_num] = new char[len + 1]; - } - - memcpy(this->data[clipboard_num], data, len); - this->data[clipboard_num][len] = 0; - - if(clipboard_num == PRIMARY_SELECTION) - { - XSetSelectionOwner(out_display, - primary, - out_win, - CurrentTime); + bfr = 0; + long len = 0; + if( clipboard_num < CLIP_BUFFER0 ) { + Atom selection = clipboard_num == CLIP_PRIMARY ? xa_primary : clipboard; + Atom target = string_type, property = selection; + XConvertSelection(in_display, selection, target, property, in_win, CurrentTime); + + XEvent event; + do { + XNextEvent(in_display, &event); + } while( event.type != SelectionNotify && event.type != None ); + + if( event.type == SelectionNotify && property == event.xselection.property ) { + unsigned long size = 0, items = 0; + Atom prop_type = 0; int bits_per_item = 0; + XGetWindowProperty(in_display, in_win, property, 0, (maxlen+3)/4, + False, AnyPropertyType, &prop_type, &bits_per_item, + &items, &size, (unsigned char**)&bfr); + len = !prop_type ? -1 : + !maxlen ? size : + (items*bits_per_item + 7)/8; + } + else + clipboard_num = CLIP_BUFFER0; } - else - if(clipboard_num == SECONDARY_SELECTION) - { - XSetSelectionOwner(out_display, - secondary, - out_win, - CurrentTime); + if( clipboard_num >= CLIP_BUFFER0 ) { + int idx = clipboard_num - CLIP_BUFFER0, size = 0; + bfr = XFetchBuffer(in_display, &size, idx); + len = size; } - - XFlush(out_display); - - #ifdef SINGLE_THREAD BC_Display::unlock_display(); #else - XUnlockDisplay(out_display); + XUnlockDisplay(in_display); #endif - return 0; + return len; } -int BC_Clipboard::from_clipboard(char *data, long maxlen, int clipboard_num) +int BC_Clipboard::to_clipboard(BC_WindowBase *owner, const char *data, long len, int clipboard_num) { - - - - if(clipboard_num == BC_PRIMARY_SELECTION) - { - char *data2; - int len, i; - data2 = XFetchBuffer(in_display, &len, clipboard_num); - for(i = 0; i < len && i < maxlen; i++) - data[i] = data2[i]; - - data[i] = 0; - - XFree(data2); - - - return 0; - } - - - + if( !data || len < 0 ) return -1; #ifdef SINGLE_THREAD - BC_Display::lock_display("BC_Clipboard::from_clipboard"); + BC_Display::lock_display("BC_Clipboard::to_clipboard"); #else - XLockDisplay(in_display); + XLockDisplay(out_display); #endif - XEvent event; - Atom type_return, pty; - int format; - unsigned long nitems, size, new_size; - char *temp_data = 0; - - pty = (clipboard_num == PRIMARY_SELECTION) ? primary : secondary; - /* a property of our window - for apps to put their - selection into */ - - XConvertSelection(in_display, - clipboard_num == PRIMARY_SELECTION ? primary : secondary, - strtype_atom, - pty, - in_win, - CurrentTime); - - data[0] = 0; - do - { - XNextEvent(in_display, &event); - }while(event.type != SelectionNotify && event.type != None); - - if(event.type != None) - { -// Get size - XGetWindowProperty(in_display, - in_win, pty, 0, 0, False, AnyPropertyType, - &type_return, &format, &nitems, &size, - (unsigned char**)&temp_data); - - if(temp_data) XFree(temp_data); - temp_data = 0; - -// Get data - XGetWindowProperty(in_display, - in_win, pty, 0, size, False, AnyPropertyType, - &type_return, &format, &nitems, &new_size, - (unsigned char**)&temp_data); - - - if(type_return && temp_data) - { - strncpy(data, temp_data, maxlen); - data[maxlen] = 0; + if( clipboard_num < CLIP_BUFFER0 ) { + char *bfr = data_buffer[clipboard_num]; + if( data_length[clipboard_num] != len+1 ) { + delete [] bfr; bfr = new char[len+1]; + data_buffer[clipboard_num] = bfr; + data_length[clipboard_num] = len+1; } - else - data[0] = 0; - - if(temp_data) XFree(temp_data); + memcpy(bfr, data, len); + bfr[len] = 0; + Atom selection = clipboard_num == CLIP_PRIMARY ? xa_primary : clipboard; +// this is not supposed to be necessary according to the man page + Window cur = XGetSelectionOwner(out_display, selection); + if( cur != owner->win && cur != None ) + XSetSelectionOwner(out_display, selection, None, CurrentTime); + XSetSelectionOwner(out_display, selection, owner->win, CurrentTime); + XFlush(out_display); + } + else { + int idx = clipboard_num - CLIP_BUFFER0; + XStoreBuffer(out_display, data, len, idx); } - #ifdef SINGLE_THREAD BC_Display::unlock_display(); #else - XUnlockDisplay(in_display); + XUnlockDisplay(out_display); #endif -//int len = strlen(data); -//printf("BC_Clipboard::from_clipboard %d: %d '%*.*s'\n",clipboard_num,len,len,len,data); return 0; } -long BC_Clipboard::clipboard_len(int clipboard_num) +int BC_Clipboard::handle_request_string(XSelectionRequestEvent *xev) { + int idx = + xev->selection == xa_primary ? CLIP_PRIMARY : + xev->selection == clipboard ? CLIP_CLIPBOARD : -1 ; + if( idx < 0 ) return 0; + char *data = data_buffer[idx]; + if( !data ) return 0; + int len = data_length[idx]; + + XChangeProperty(out_display, xev->requestor, + xev->property, string_type, 8, PropModeReplace, + (unsigned char*)data, len); + return 1; +} - if(clipboard_num == BC_PRIMARY_SELECTION) - { - char *data2; - int len; - - data2 = XFetchBuffer(in_display, &len, clipboard_num); - XFree(data2); - return len; - } - - - - -#ifdef SINGLE_THREAD - BC_Display::lock_display("BC_Clipboard::clipboard_len"); -#else - XLockDisplay(in_display); -#endif - - XEvent event; - Atom type_return, pty; - int format; - unsigned long nitems, pty_size; - char *temp_data = 0; - int result = 0; - - pty = (clipboard_num == PRIMARY_SELECTION) ? primary : secondary; - /* a property of our window - for apps to put their - selection into */ - XConvertSelection(in_display, - (clipboard_num == PRIMARY_SELECTION) ? primary : secondary, - strtype_atom, pty, in_win, CurrentTime); - - do - { - XNextEvent(in_display, &event); - }while(event.type != SelectionNotify && event.type != None); - - if(event.type != None) - { -// Get size - XGetWindowProperty(in_display, - in_win, pty, 0, 0, False, AnyPropertyType, - &type_return, &format, &nitems, &pty_size, - (unsigned char**)&temp_data); - - if(type_return) - { - result = pty_size + 1; - } - else - result = 0; - - if(temp_data) - XFree(temp_data); - } - +int BC_Clipboard::handle_request_targets(XSelectionRequestEvent *xev) +{ + Atom target_atoms[] = { targets, string_type }; + int ntarget_atoms = sizeof(target_atoms)/sizeof(target_atoms[0]); + XChangeProperty(out_display, xev->requestor, + xev->property, XA_ATOM, 32, PropModeReplace, + (unsigned char*)target_atoms, ntarget_atoms); + return 1; +} -#ifdef SINGLE_THREAD - BC_Display::unlock_display(); -#else - XUnlockDisplay(in_display); -#endif +void BC_Clipboard::handle_selectionrequest(XSelectionRequestEvent *xev) +{ + XEvent reply; memset(&reply, 0, sizeof(reply)); +// 'None' tells the client that the request was denied + reply.xselection.property = + (xev->target == string_type && handle_request_string(xev)) || + (xev->target == targets && handle_request_targets(xev)) ? + xev->property : None; + reply.xselection.type = SelectionNotify; + reply.xselection.display = xev->display; + reply.xselection.requestor = xev->requestor; + reply.xselection.selection = xev->selection; + reply.xselection.target = xev->target; + reply.xselection.time = xev->time; - return result; + XSendEvent(out_display, xev->requestor, 0, 0, &reply); + XFlush(out_display); } + diff --git a/cinelerra-5.1/guicast/bcclipboard.h b/cinelerra-5.1/guicast/bcclipboard.h index a739878f..d53720a2 100644 --- a/cinelerra-5.1/guicast/bcclipboard.h +++ b/cinelerra-5.1/guicast/bcclipboard.h @@ -30,46 +30,55 @@ #include #include + +enum { + CLIP_PRIMARY, // XA_PRIMARY + CLIP_CLIPBOARD, // Atom(CLIPBOARD) + CLIP_BUFFER0, // XA_CUT_BUFFER0 + CLIP_BUFFERS = CLIP_BUFFER0, // CUT_BUFFER api does not need storage +}; +// loads CUT_BUFFER0 if window is closed while selection set + // The primary selection is filled by highlighting a region -#define PRIMARY_SELECTION 0 -// The secondary selection is filled by copying -#define SECONDARY_SELECTION 1 +#define PRIMARY_SELECTION CLIP_PRIMARY +// The secondary selection is filled by copying (textbox Ctrl-C) +#define SECONDARY_SELECTION CLIP_CLIPBOARD // Storage for guicast only -// The secondary selection has never been reliable either in Cinelerra -// or anything else. We just use the guaranteed solution for any data not -// intended for use outside Cinelerra. -#define BC_PRIMARY_SELECTION 2 - +#define BC_PRIMARY_SELECTION (CLIP_BUFFER0+2) +// The secondary selection has never been reliable either in Cinelerra +// or anything else. We just use the CUT_BUFFER2 solution for any data +// not intended for use outside Cinelerra. class BC_Clipboard : public Thread { public: - BC_Clipboard(const char *display_name); + BC_Clipboard(BC_WindowBase *window); ~BC_Clipboard(); int start_clipboard(); void run(); int stop_clipboard(); + int to_clipboard(BC_WindowBase *owner, const char *data, long len, int clipboard_num); + long from_clipboard(char *data, long maxlen, int clipboard_num); long clipboard_len(int clipboard_num); - int to_clipboard(const char *data, long len, int clipboard_num); - int from_clipboard(char *data, long maxlen, int clipboard_num); private: + long from_clipboard(int clipboard_num, char *&bfr, long maxlen); void handle_selectionrequest(XSelectionRequestEvent *request); int handle_request_string(XSelectionRequestEvent *request); int handle_request_targets(XSelectionRequestEvent *request); + BC_WindowBase *window; Display *in_display, *out_display; - Atom completion_atom, primary, secondary; - Atom targets_atom; - Atom strtype_atom; Window in_win, out_win; - char *data[2]; - long length[2]; - char display_name[BCTEXTLEN]; + Atom xa_primary, clipboard, targets; + Atom completion_atom, string_type; + + char *data_buffer[CLIP_BUFFERS]; + int data_length[CLIP_BUFFERS]; }; #endif diff --git a/cinelerra-5.1/guicast/bcdisplay.C b/cinelerra-5.1/guicast/bcdisplay.C index 2e048c85..39a2b908 100644 --- a/cinelerra-5.1/guicast/bcdisplay.C +++ b/cinelerra-5.1/guicast/bcdisplay.C @@ -114,12 +114,9 @@ int BC_Display::is_first(BC_WindowBase *window) void BC_Display::dump_windows() { - for(int i = 0; i < windows.size(); i++) - { - printf("BC_Display::dump_windows %d window=%p window->win=%p\n", - i, - windows.get(i), - windows.get(i)->win); + for(int i = 0; i < windows.size(); i++) { + printf("BC_Display::dump_windows %d window=%p window->win=0x%08jx\n", + i, windows.get(i), windows.get(i)->win); } } @@ -128,7 +125,7 @@ void BC_Display::new_window(BC_WindowBase *window) //printf("BC_Display::new_window %d\n", __LINE__); if(!clipboard) { - clipboard = new BC_Clipboard(""); + clipboard = new BC_Clipboard(window); clipboard->start_clipboard(); } @@ -335,7 +332,7 @@ void BC_Display::unset_repeat(BC_WindowBase *window, int64_t duration) } } -int BC_Display::unset_all_repeaters(BC_WindowBase *window) +void BC_Display::unset_all_repeaters(BC_WindowBase *window) { for(int i = 0; i < repeaters.total; i++) { @@ -384,7 +381,7 @@ void BC_Display::unlock_repeaters(int64_t duration) void BC_Display::lock_display(const char *location) { pthread_mutex_lock(&BC_Display::display_lock); - int result = ++BC_Display::display_global->window_locked; + ++BC_Display::display_global->window_locked; pthread_mutex_unlock(&BC_Display::display_lock); //printf("BC_Display::lock_display %d %s result=%d\n", __LINE__, location, result); @@ -394,13 +391,13 @@ void BC_Display::lock_display(const char *location) void BC_Display::unlock_display() { pthread_mutex_lock(&BC_Display::display_lock); - int result = --BC_Display::display_global->window_locked; + --BC_Display::display_global->window_locked; // if(BC_Display::display_global->window_locked < 0) // BC_Display::display_global->window_locked = 0; pthread_mutex_unlock(&BC_Display::display_lock); //printf("BC_Display::unlock_display %d result=%d\n", __LINE__, result); - /* if(result == 1) */ XUnlockDisplay(BC_Display::display_global->display); + XUnlockDisplay(BC_Display::display_global->display); } diff --git a/cinelerra-5.1/guicast/bcdisplay.h b/cinelerra-5.1/guicast/bcdisplay.h index cc2c6156..fe071cc7 100644 --- a/cinelerra-5.1/guicast/bcdisplay.h +++ b/cinelerra-5.1/guicast/bcdisplay.h @@ -64,7 +64,7 @@ public: XEvent* get_event(); void set_repeat(BC_WindowBase *window, int64_t duration); void unset_repeat(BC_WindowBase *window, int64_t duration); - int unset_all_repeaters(BC_WindowBase *window); + void unset_all_repeaters(BC_WindowBase *window); void unlock_repeaters(int64_t duration); void arm_repeat(int64_t duration); void arm_completion(BC_WindowBase *window); diff --git a/cinelerra-5.1/guicast/bcdisplayinfo.C b/cinelerra-5.1/guicast/bcdisplayinfo.C index 724d6c44..5bbe991c 100644 --- a/cinelerra-5.1/guicast/bcdisplayinfo.C +++ b/cinelerra-5.1/guicast/bcdisplayinfo.C @@ -73,10 +73,12 @@ static void get_top_coords(Display *display, Window win, int &px,int &py, int &t int nx = px, ny = py; pwin = win; for( int i=5; --i>=0; ) { - win = pwin; root = 0; pwin = 0; pcwin = 0; ncwin = 0; - XQueryTree(display, win, &root, &pwin, &pcwin, &ncwin); + win = pwin; pwin = 0; pcwin = 0; ncwin = 0; + Window rwin = 0; +// XQuerytTree has been known to fail here + XQueryTree(display, win, &rwin, &pwin, &pcwin, &ncwin); if( pcwin ) XFree(pcwin); - if( pwin == root ) break; + if( !rwin || rwin != root || pwin == root ) break; XTranslateCoordinates(display, pwin, root, 0,0, &nx,&ny, &cwin); //printf(" win=%lx, nx/ny=%d/%d\n", win, nx,ny); } diff --git a/cinelerra-5.1/guicast/bcresources.C b/cinelerra-5.1/guicast/bcresources.C index 6aedde55..b51843b1 100644 --- a/cinelerra-5.1/guicast/bcresources.C +++ b/cinelerra-5.1/guicast/bcresources.C @@ -658,6 +658,7 @@ new_vframes(20,default_medium_7segment, text_border3_hi = LTPINK; text_border4 = WHITE; text_highlight = BLUE; + text_selected_highlight = SLBLUE; text_inactive_highlight = MEGREY; toggle_highlight_bg = 0; diff --git a/cinelerra-5.1/guicast/bcresources.h b/cinelerra-5.1/guicast/bcresources.h index 8e518e49..978425ae 100644 --- a/cinelerra-5.1/guicast/bcresources.h +++ b/cinelerra-5.1/guicast/bcresources.h @@ -171,6 +171,7 @@ public: int text_border4; int text_highlight; int text_inactive_highlight; + int text_selected_highlight; // Not used int text_background_noborder; diff --git a/cinelerra-5.1/guicast/bctextbox.C b/cinelerra-5.1/guicast/bctextbox.C index d377a448..5d1257eb 100644 --- a/cinelerra-5.1/guicast/bctextbox.C +++ b/cinelerra-5.1/guicast/bctextbox.C @@ -176,6 +176,7 @@ int BC_TextBox::reset_parameters(int rows, int has_border, int font, int size) xscroll = 0; yscroll = 0; dirty = 1; + selection_active = 0; return 0; } @@ -673,6 +674,8 @@ void BC_TextBox::draw(int flush) highlight_letter1 <= row_end ) { int color = active && enabled && get_has_focus() ? resources->text_highlight : + selection_active ? + resources->text_selected_highlight : resources->text_inactive_highlight; if( unicode_active >= 0 ) color ^= LTBLUE; @@ -2007,17 +2010,25 @@ void BC_TextBox::copy_selection(int clipboard_num) //printf(" BC_TextBox::copy_selection %d %d %d\n",highlight_letter1, highlight_letter2, clip_len); char ctext[4*clip_len+4]; clip_len = text_update(&wtext[highlight_letter1],clip_len, ctext,4*clip_len+4); - get_clipboard()->to_clipboard(ctext, clip_len, clipboard_num); + to_clipboard(ctext, clip_len, clipboard_num); + selection_active = 1; } +int BC_TextBox::selection_clear_event() +{ + if( !is_event_win() ) return 0; + selection_active = 0; + draw(1); + return 1; +} void BC_TextBox::paste_selection(int clipboard_num) { - int len = get_clipboard()->clipboard_len(clipboard_num); + int len = clipboard_len(clipboard_num); if( len > 0 ) { char cstring[len]; wchar_t wstring[len]; - get_clipboard()->from_clipboard(cstring, len, clipboard_num); --len; + from_clipboard(cstring, len, clipboard_num); --len; //printf("BC_TextBox::paste_selection %d '%*.*s'\n",len,len,len,cstring); len = BC_Resources::encode(BC_Resources::encoding, BC_Resources::wide_encoding, cstring,len, (char *)wstring,(len+1)*sizeof(wchar_t)) / sizeof(wchar_t); diff --git a/cinelerra-5.1/guicast/bctextbox.h b/cinelerra-5.1/guicast/bctextbox.h index a3db2b69..89d77432 100644 --- a/cinelerra-5.1/guicast/bctextbox.h +++ b/cinelerra-5.1/guicast/bctextbox.h @@ -101,6 +101,7 @@ public: int button_release_event(); int repeat_event(int64_t repeat_id); int keypress_event(); + int selection_clear_event(); int activate(); int deactivate(); const char* get_text(); @@ -218,6 +219,7 @@ private: ArrayList *suggestions; BC_TextBoxSuggestions *suggestions_popup; int suggestion_column; + int selection_active; }; diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index fae98cb1..cee19e7a 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -547,7 +547,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, get_atoms(); #ifndef SINGLE_THREAD - clipboard = new BC_Clipboard(display_name); + clipboard = new BC_Clipboard(this); clipboard->start_clipboard(); #endif @@ -1348,6 +1348,7 @@ locking_message = event->xclient.message_type; cursor_y = event->xcrossing.y; dispatch_cursor_enter(); break; + default: break; } @@ -3696,6 +3697,38 @@ BC_Clipboard* BC_WindowBase::get_clipboard() #endif } +Atom BC_WindowBase::to_clipboard(const char *data, long len, int clipboard_num) +{ + return get_clipboard()->to_clipboard(this, data, len, clipboard_num); +} + +long BC_WindowBase::from_clipboard(char *data, long maxlen, int clipboard_num) +{ + return get_clipboard()->from_clipboard(data, maxlen, clipboard_num); +} + +long BC_WindowBase::clipboard_len(int clipboard_num) +{ + return get_clipboard()->clipboard_len(clipboard_num); +} + +int BC_WindowBase::do_selection_clear(Window win) +{ + top_level->event_win = win; + return dispatch_selection_clear(); +} + +int BC_WindowBase::dispatch_selection_clear() +{ + int result = 0; + for( int i=0; itotal && !result; ++i ) + result = subwindows->values[i]->dispatch_selection_clear(); + if( !result ) + result = selection_clear_event(); + return result; +} + + void BC_WindowBase::get_relative_cursor_xy(int &x, int &y, int lock_window) { int abs_x, abs_y, win_x, win_y; diff --git a/cinelerra-5.1/guicast/bcwindowbase.h b/cinelerra-5.1/guicast/bcwindowbase.h index 5532ae49..8272f4ff 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.h +++ b/cinelerra-5.1/guicast/bcwindowbase.h @@ -194,6 +194,7 @@ public: virtual int drag_motion_event() { return 0; }; virtual int drag_stop_event() { return 0; }; virtual int uses_text() { return 0; }; + virtual int selection_clear_event() { return 0; } // Only if opengl is enabled virtual int expose_event() { return 0; }; virtual int grab_event(XEvent *event) { return 0; }; @@ -528,6 +529,9 @@ public: void restore_vm(); #endif + Atom to_clipboard(const char *data, long len, int clipboard_num); + long from_clipboard(char *data, long maxlen, int clipboard_num); + long clipboard_len(int clipboard_num); int test_keypress; char keys_return[KEYPRESSLEN]; @@ -596,6 +600,8 @@ private: void put_event(XEvent *event); // remove events queued for win void dequeue_events(Window win); +// clear selection + int do_selection_clear(Atom selection); // Recursive event dispatchers int dispatch_resize_event(int w, int h); @@ -616,6 +622,7 @@ private: int dispatch_drag_motion(); int dispatch_drag_stop(); int dispatch_expose_event(); + int dispatch_selection_clear(); // Get the port ID for a color model or return -1 for failure int grab_port_id(int color_model); @@ -764,6 +771,8 @@ private: Window rootwin; // windows previous events happened in Window event_win, drag_win; +// selection clear + Atom event_selection; Visual *vis; Colormap cmap; // Name of display diff --git a/cinelerra-5.1/guicast/colors.h b/cinelerra-5.1/guicast/colors.h index 6aefdf8a..a0878fd0 100644 --- a/cinelerra-5.1/guicast/colors.h +++ b/cinelerra-5.1/guicast/colors.h @@ -61,6 +61,7 @@ #define DKGREY 0x4B4B4B #define BLOND 0xb4b487 +#define SLBLUE 0x6040c0 #define MNGREY 0xe6e6e6 #define FGGREY 0xe3e3e3 diff --git a/cinelerra-5.1/plugins/C41/c41.C b/cinelerra-5.1/plugins/C41/c41.C index f4d3fcfe..52ae7b0e 100644 --- a/cinelerra-5.1/plugins/C41/c41.C +++ b/cinelerra-5.1/plugins/C41/c41.C @@ -430,6 +430,11 @@ C41Effect::C41Effect(PluginServer *server) tmp_frame = 0; blurry_frame = 0; memset(&values, 0, sizeof(values)); + shave_min_row = shave_max_row = 0; + shave_min_col = shave_max_col = 0; + min_col = max_col = 0; + min_row = max_row = 0; + pix_max = 0; pix_len = 0; } C41Effect::~C41Effect() @@ -752,7 +757,7 @@ int C41Effect::process_realtime(VFrame *input, VFrame *output) for( int i = min_row; i < max_row; i++ ) { float *row = (float*)frame->get_rows()[i]; - row += 3 * shave_min_col; + row += 3 * min_col; for( int j = min_col; j < max_col; j++, row += 3 ) { if( row[0] < minima_r ) minima_r = row[0]; if( row[0] > maxima_r ) maxima_r = row[0]; diff --git a/cinelerra-5.1/plugins/theme_bright/brighttheme.C b/cinelerra-5.1/plugins/theme_bright/brighttheme.C index f9392035..e7daaf97 100644 --- a/cinelerra-5.1/plugins/theme_bright/brighttheme.C +++ b/cinelerra-5.1/plugins/theme_bright/brighttheme.C @@ -116,8 +116,9 @@ void BrightTheme::initialize() resources->text_border2_hi = 0x000000; resources->text_border3_hi = 0x000000; resources->text_border4 = 0x000000; - resources->text_inactive_highlight = 0xe0e0e0; + resources->text_inactive_highlight = 0xd0d0d0; resources->text_highlight = 0xe0e0e0; + resources->text_selected_highlight = 0xf0e0e0; resources->bg_color = 0xffffff; resources->default_text_color = 0x000000; diff --git a/cinelerra-5.1/plugins/titler/titler.C b/cinelerra-5.1/plugins/titler/titler.C index 77132e7b..d9680342 100644 --- a/cinelerra-5.1/plugins/titler/titler.C +++ b/cinelerra-5.1/plugins/titler/titler.C @@ -1188,7 +1188,7 @@ void TitleMain::build_previews(TitleWindow *gui) for( int i=0; idisplayname, font->displayname) ) { if( pass == 1 ) { - font->image = fonts[i]->image; + font->image = new VFrame(*fonts[i]->image); } skip = 1; break;