clipboard rework, C41/titler fixes, displayinfo tweak
authorGood Guy <[email protected]>
Wed, 23 Aug 2017 19:17:47 +0000 (13:17 -0600)
committerGood Guy <[email protected]>
Wed, 23 Aug 2017 19:17:47 +0000 (13:17 -0600)
20 files changed:
cinelerra-5.1/bld_scripts/bld_prepare.sh
cinelerra-5.1/cinelerra/clippopup.C
cinelerra-5.1/cinelerra/keyframepopup.C
cinelerra-5.1/cinelerra/mwindowedit.C
cinelerra-5.1/cinelerra/vwindow.C
cinelerra-5.1/guicast/bcclipboard.C
cinelerra-5.1/guicast/bcclipboard.h
cinelerra-5.1/guicast/bcdisplay.C
cinelerra-5.1/guicast/bcdisplay.h
cinelerra-5.1/guicast/bcdisplayinfo.C
cinelerra-5.1/guicast/bcresources.C
cinelerra-5.1/guicast/bcresources.h
cinelerra-5.1/guicast/bctextbox.C
cinelerra-5.1/guicast/bctextbox.h
cinelerra-5.1/guicast/bcwindowbase.C
cinelerra-5.1/guicast/bcwindowbase.h
cinelerra-5.1/guicast/colors.h
cinelerra-5.1/plugins/C41/c41.C
cinelerra-5.1/plugins/theme_bright/brighttheme.C
cinelerra-5.1/plugins/titler/titler.C

index 8aea5d836af4c04410ffb04888982ed59d5279d4..028a0071746f2c2f1fe13a4d82defcb5cfd97071 100755 (executable)
@@ -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
index cbd7ca04c84d9a7d3d879d621fef86e484a4b43a..4fd6af6975e6139c42d4965f31d16f43b604151a 100644 (file)
@@ -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 = "<EDL VERSION=";
                if( !strncmp(clip_header, string, strlen(clip_header)) ) {
                        FileXML file;
index 41fe8d9c187e9f16292485fa28d2d33691d58e03..9fb15e71b1e5b67d4e953916e6449e4c499bc794 100644 (file)
@@ -438,9 +438,7 @@ int KeyframePopupCopy::handle_event()
                file.terminate_string();
 
                mwindow->gui->lock_window();
-               mwindow->gui->get_clipboard()->to_clipboard(file.string,
-                       strlen(file.string),
-                       SECONDARY_SELECTION);
+               mwindow->gui->to_clipboard(file.string, strlen(file.string), SECONDARY_SELECTION);
                mwindow->gui->unlock_window();
 
        } else
index 9e53bde729a8d62cf0fd56f3e5bf7409c8512541..8fba7bfc95d48b110516db5e6ef81c743d8e59df 100644 (file)
@@ -427,10 +427,8 @@ int MWindow::copy(double start, double end)
        edl->copy(start, end, 0, 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, 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();
index 2f96447c4674981ebbc5d21438b8fd322e9f267e..45dacc0b8496f4425b782f2b560ac67b7d189a94 100644 (file)
@@ -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();
        }
 }
index 7c201af8bc33d94166a534f8653171f10cc2ada1..4ef144bcb8e74455c8abb7300f1f931361584dd9 100644 (file)
 #include <string.h>
 #include <unistd.h>
 
-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; i<CLIP_BUFFERS; ++i ) {
+               data_buffer[i] = 0;
+               data_length[i] = 0;
+       }
 }
 
 BC_Clipboard::~BC_Clipboard()
 {
-       if(data[0]) delete [] data[0];
-       if(data[1]) delete [] data[1];
-
+       for( int i=0; i<CLIP_BUFFERS; ++i ) {
+               delete [] data_buffer[i];
+       }
        XDestroyWindow(in_display, in_win);
        XCloseDisplay(in_display);
        XDestroyWindow(out_display, out_win);
@@ -82,6 +79,12 @@ int BC_Clipboard::start_clipboard()
 
 int BC_Clipboard::stop_clipboard()
 {
+// if closing clipboard with selection, move data to CUT_BUFFER0
+       char *data = 0;  int len = 0;
+       for( int i=0; !data && i<CLIP_BUFFERS; ++i ) {
+               data = data_buffer[i];  len = data_length[i];
+       }
+       if( data ) XStoreBuffer(out_display, data, len, 0);
 #ifdef SINGLE_THREAD
        XFlush(in_display);
 #else
@@ -89,6 +92,7 @@ int BC_Clipboard::stop_clipboard()
        XFlush(out_display);
 #endif
 // Must use a different display handle to send events.
+       const char *display_name = window->display_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);
 }
+
index a739878f635ab030f5cb7435d22193c975a82204..d53720a2560c29987719c8fecc858f3bcf7ed825 100644 (file)
 #include <X11/Xatom.h>
 #include <X11/Xlib.h>
 
+
+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
index 2e048c85642900a075b62397a7907214acf2e150..39a2b908b084d3023fb4f7dd18e0a19d128ec0b0 100644 (file)
@@ -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);
 }
 
 
index cc2c615601e374ff63401f12c47496be42d7b641..fe071cc7643e93bf40f7fe5aabd6f18173dbcddc 100644 (file)
@@ -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);
index 724d6c442b87733d061af47c6c325f3bcc1e8655..5bbe991ce925492b454fbc2fc58c0d59e9ac34ef 100644 (file)
@@ -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);
        }
index 6aedde55bd099d425061768ce0c0b809c8f9334a..b51843b11232047a2f229fbd2a9c76b0260da955 100644 (file)
@@ -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;
index 8e518e49f94b6d1debf833976c095accc33d5c01..978425aeb86a7635fc07af00392e752284e6ec0e 100644 (file)
@@ -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;
 
index d377a448a0039398ee493a8ce2ced415b8bf05b3..5d1257eb82cb44e949ca24c406b43684d278b1df 100644 (file)
@@ -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);
index a3db2b69189dc4014376b54404fa6215daadef55..89d7743254ec045e225519c5f1c17530d2cccfab 100644 (file)
@@ -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<BC_ListBoxItem*> *suggestions;
        BC_TextBoxSuggestions *suggestions_popup;
        int suggestion_column;
+       int selection_active;
 };
 
 
index fae98cb186b9315572190fa6abd940e3d2f84a0b..cee19e7adaf812f51cce88886196d7d79a3f94d7 100644 (file)
@@ -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; i<subwindows->total && !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;
index 5532ae49a5454803f0061c5527232e76a9460ab8..8272f4ff14bbfb0e844063b2e0a27f17d45e8481 100644 (file)
@@ -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
index 6aefdf8a35133304b22c2f1d070cb856fd921ce8..a0878fd07b024eb914194859c1b528e99c3d88a4 100644 (file)
@@ -61,6 +61,7 @@
 #define DKGREY              0x4B4B4B
 
 #define BLOND               0xb4b487
+#define SLBLUE              0x6040c0
 
 #define MNGREY              0xe6e6e6
 #define FGGREY              0xe3e3e3
index f4d3fcfe894c20cb51d18ace236a1a3974f7f99a..52ae7b0e7c21048329581206bece571d4b1e93dc 100644 (file)
@@ -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];
index f93920353129c622fb5ec057a9f803088dc69727..e7daaf97719a766ee38da6c0c795c6c88133239d 100644 (file)
@@ -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;
index 77132e7b4f890917f7227b2d4dd842763c8820b7..d96803425779e3f648925dffe7947c9d30ed5256 100644 (file)
@@ -1188,7 +1188,7 @@ void TitleMain::build_previews(TitleWindow *gui)
                        for( int i=0; i<font_number; ++i ) {
                                if( !strcasecmp(fonts[i]->displayname, font->displayname) ) {
                                        if( pass == 1 ) {
-                                               font->image = fonts[i]->image;
+                                               font->image = new VFrame(*fonts[i]->image);
                                        }
                                        skip = 1;
                                        break;