interp bilinear fix
[goodguy/history.git] / cinelerra-5.1 / guicast / bcwindowbase.C
index e4a0ef6b785708aacda45b2fe23d2684e17bb2e1..cee19e7adaf812f51cce88886196d7d79a3f94d7 100644 (file)
@@ -181,9 +181,10 @@ BC_WindowBase::~BC_WindowBase()
                for( int i=sizeof(xfont)/sizeof(xfont[0]); --i>=0; )
                        XFreeFont(display, this->*xfont[i]);
 
-// bug in X causes XRenderExtensionInfo to be damaged if this is done here
-//  left to be done in XCloseDisplay by Xlib.
-#if defined(HAVE_XFT) && 0
+// past bug in X caused XRenderExtensionInfo to be damaged
+// if this is done here. left to be done in XCloseDisplay by Xlib.
+// works in more modern systems, and needed for leak testing.
+#if defined(HAVE_XFT) && defined(VALGRIND)
                static void *BC_WindowBase::*xft_font[] = {
                         &BC_WindowBase::smallfont_xft,
                         &BC_WindowBase::mediumfont_xft,
@@ -546,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
 
@@ -683,6 +684,15 @@ Display* BC_WindowBase::init_display(const char *display_name)
                        }
                }
        }
+
+       static int xsynch = -1;
+       if( xsynch < 0 ) {
+               const char *cp = getenv("CIN_XSYNCH");
+               xsynch = !cp ? 0 : atoi(cp);
+       }
+       if( xsynch > 0 )
+               XSynchronize(display, True);
+
        return display;
 }
 
@@ -962,12 +972,15 @@ locking_message = event->xclient.message_type;
 //   event_names[event->type] : "Unknown");
 //}
 
-       if( active_grab && active_grab->grab_event(event) ) {
+       if( active_grab ) {
                unlock_window();
-               return 0;
+               active_grab->lock_window("BC_WindowBase::dispatch_event 3");
+               result = active_grab->grab_event(event);
+               active_grab->unlock_window();
+               if( result ) return result;
+               lock_window("BC_WindowBase::dispatch_event 4");
        }
 
-
        switch(event->type) {
        case ClientMessage:
 // Clear the resize buffer
@@ -1335,6 +1348,7 @@ locking_message = event->xclient.message_type;
                cursor_y = event->xcrossing.y;
                dispatch_cursor_enter();
                break;
+
        default:
                break;
        }
@@ -2009,7 +2023,7 @@ void BC_WindowBase::init_cursors()
        downleft_resize_cursor = XCreateFontCursor(display, XC_bottom_left_corner);
        downright_resize_cursor = XCreateFontCursor(display, XC_bottom_right_corner);
        hourglass_cursor = XCreateFontCursor(display, XC_watch);
-
+       grabbed_cursor = create_grab_cursor();
 
        static char cursor_data[] = { 0,0,0,0, 0,0,0,0 };
        Colormap colormap = DefaultColormap(display, screen);
@@ -2021,49 +2035,6 @@ void BC_WindowBase::init_cursors()
                pixmap_bottom, pixmap_bottom, &black, &black, 0, 0);
 //     XDefineCursor(display, win, transparent_cursor);
        XFreePixmap(display, pixmap_bottom);
-
-       int iw = 23, iw1 = iw-1, iw2 = iw/2;
-       int ih = 23, ih1 = ih-1, ih2 = ih/2;
-       VFrame grab(iw,ih,BC_RGB888);
-       grab.clear_frame();
-       grab.set_pixel_color(RED);   // fg
-       grab.draw_smooth(iw2,0,   iw1,0,   iw1,ih2);
-       grab.draw_smooth(iw1,ih2, iw1,ih1, iw2,ih1);
-       grab.draw_smooth(iw2,ih1, 0,ih1,   0,ih2);
-       grab.draw_smooth(0,ih2,   0,0,     iw2,0);
-       grab.set_pixel_color(WHITE); // bg
-       grab.draw_line(0,ih2,     iw2-2,ih2);
-       grab.draw_line(iw2+2,ih2, iw1,ih2);
-       grab.draw_line(iw2,0,     iw2,ih2-2);
-       grab.draw_line(iw2,ih2+2, iw2,ih1);
-
-       int bpl = (iw+7)/8, isz = bpl * ih;
-       char img[isz];  memset(img, 0, isz);
-       char msk[isz];  memset(msk, 0, isz);
-       unsigned char **rows = grab.get_rows();
-       for( int iy=0; iy<ih; ++iy ) {
-               char *op = img + iy*bpl;
-               char *mp = msk + iy*bpl;
-               unsigned char *ip = rows[iy];
-               for( int ix=0; ix<iw; ++ix,ip+=3 ) {
-                       if( ip[0] ) mp[ix>>3] |= (1<<(ix&7));
-                       if( !ip[1] ) op[ix>>3] |= (1<<(ix&7));
-               }
-       }
-       unsigned long white_pix = WhitePixel(display, screen);
-       unsigned long black_pix = BlackPixel(display, screen);
-       Pixmap img_xpm = XCreatePixmapFromBitmapData(display, rootwin,
-               img, iw,ih, white_pix,black_pix, 1);
-       Pixmap msk_xpm = XCreatePixmapFromBitmapData(display, rootwin,
-               msk, iw,ih, white_pix,black_pix, 1);
-
-       XColor fc, bc;
-       fc.flags = bc.flags = DoRed | DoGreen | DoBlue;
-       fc.red = 0xffff; fc.green = fc.blue = 0;  // fg
-       bc.red = bc.green = bc.blue = 0x0000;     // bg
-       grabbed_cursor = XCreatePixmapCursor(display, img_xpm,msk_xpm, &fc,&bc, iw2,ih2);
-       XFreePixmap(display, img_xpm);
-       XFreePixmap(display, msk_xpm);
 }
 
 int BC_WindowBase::evaluate_color_model(int client_byte_order, int server_byte_order, int depth)
@@ -2215,6 +2186,53 @@ int BC_WindowBase::create_shared_colors()
        return 0;
 }
 
+Cursor BC_WindowBase::create_grab_cursor()
+{
+       int iw = 23, iw1 = iw-1, iw2 = iw/2;
+       int ih = 23, ih1 = ih-1, ih2 = ih/2;
+       VFrame grab(iw,ih,BC_RGB888);
+       grab.clear_frame();
+       grab.set_pixel_color(RED);   // fg
+       grab.draw_smooth(iw2,0,   iw1,0,   iw1,ih2);
+       grab.draw_smooth(iw1,ih2, iw1,ih1, iw2,ih1);
+       grab.draw_smooth(iw2,ih1, 0,ih1,   0,ih2);
+       grab.draw_smooth(0,ih2,   0,0,     iw2,0);
+       grab.set_pixel_color(WHITE); // bg
+       grab.draw_line(0,ih2,     iw2-2,ih2);
+       grab.draw_line(iw2+2,ih2, iw1,ih2);
+       grab.draw_line(iw2,0,     iw2,ih2-2);
+       grab.draw_line(iw2,ih2+2, iw2,ih1);
+
+       int bpl = (iw+7)/8, isz = bpl * ih;
+       char img[isz];  memset(img, 0, isz);
+       char msk[isz];  memset(msk, 0, isz);
+       unsigned char **rows = grab.get_rows();
+       for( int iy=0; iy<ih; ++iy ) {
+               char *op = img + iy*bpl;
+               char *mp = msk + iy*bpl;
+               unsigned char *ip = rows[iy];
+               for( int ix=0; ix<iw; ++ix,ip+=3 ) {
+                       if( ip[0] ) mp[ix>>3] |= (1<<(ix&7));
+                       if( !ip[1] ) op[ix>>3] |= (1<<(ix&7));
+               }
+       }
+       unsigned long white_pix = WhitePixel(display, screen);
+       unsigned long black_pix = BlackPixel(display, screen);
+       Pixmap img_xpm = XCreatePixmapFromBitmapData(display, rootwin,
+               img, iw,ih, white_pix,black_pix, 1);
+       Pixmap msk_xpm = XCreatePixmapFromBitmapData(display, rootwin,
+               msk, iw,ih, white_pix,black_pix, 1);
+
+       XColor fc, bc;
+       fc.flags = bc.flags = DoRed | DoGreen | DoBlue;
+       fc.red = 0xffff; fc.green = fc.blue = 0;  // fg
+       bc.red = bc.green = bc.blue = 0x0000;     // bg
+       Cursor cursor = XCreatePixmapCursor(display, img_xpm,msk_xpm, &fc,&bc, iw2,ih2);
+       XFreePixmap(display, img_xpm);
+       XFreePixmap(display, msk_xpm);
+       return cursor;
+}
+
 int BC_WindowBase::allocate_color_table()
 {
        int red, green, blue, color;
@@ -2610,21 +2628,22 @@ Cursor BC_WindowBase::get_cursor_struct(int cursor)
 {
        switch(cursor)
        {
-               case ARROW_CURSOR:         return top_level->arrow_cursor;                 break;
+               case ARROW_CURSOR:         return top_level->arrow_cursor;
                case CROSS_CURSOR:         return top_level->cross_cursor;
-               case IBEAM_CURSOR:         return top_level->ibeam_cursor;                 break;
-               case VSEPARATE_CURSOR:     return top_level->vseparate_cursor;             break;
-               case HSEPARATE_CURSOR:     return top_level->hseparate_cursor;             break;
-               case MOVE_CURSOR:              return top_level->move_cursor;                  break;
-               case LEFT_CURSOR:          return top_level->left_cursor;                  break;
-               case RIGHT_CURSOR:         return top_level->right_cursor;                 break;
-               case UPRIGHT_ARROW_CURSOR: return top_level->upright_arrow_cursor;         break;
-               case UPLEFT_RESIZE:        return top_level->upleft_resize_cursor;         break;
-               case UPRIGHT_RESIZE:       return top_level->upright_resize_cursor;        break;
-               case DOWNLEFT_RESIZE:      return top_level->downleft_resize_cursor;       break;
-               case DOWNRIGHT_RESIZE:     return top_level->downright_resize_cursor;      break;
-               case HOURGLASS_CURSOR:     return top_level->hourglass_cursor;                 break;
-               case TRANSPARENT_CURSOR:   return top_level->transparent_cursor;               break;
+               case IBEAM_CURSOR:         return top_level->ibeam_cursor;
+               case VSEPARATE_CURSOR:     return top_level->vseparate_cursor;
+               case HSEPARATE_CURSOR:     return top_level->hseparate_cursor;
+               case MOVE_CURSOR:          return top_level->move_cursor;
+               case LEFT_CURSOR:          return top_level->left_cursor;
+               case RIGHT_CURSOR:         return top_level->right_cursor;
+               case UPRIGHT_ARROW_CURSOR: return top_level->upright_arrow_cursor;
+               case UPLEFT_RESIZE:        return top_level->upleft_resize_cursor;
+               case UPRIGHT_RESIZE:       return top_level->upright_resize_cursor;
+               case DOWNLEFT_RESIZE:      return top_level->downleft_resize_cursor;
+               case DOWNRIGHT_RESIZE:     return top_level->downright_resize_cursor;
+               case HOURGLASS_CURSOR:     return top_level->hourglass_cursor;
+               case TRANSPARENT_CURSOR:   return top_level->transparent_cursor;
+               case GRABBED_CURSOR:       return top_level->grabbed_cursor;
        }
        return 0;
 }
@@ -2872,26 +2891,6 @@ int BC_WindowBase::get_single_text_width(int font, const char *text, int length)
        }
 }
 
-int BC_WindowBase::get_single_text_width(int font, const wchar_t *text, int length)
-{
-#ifdef HAVE_XFT
-       if(get_resources()->use_xft && get_xft_struct(font)) {
-               XGlyphInfo extents;
-
-               XftTextExtents32(top_level->display, get_xft_struct(font),
-                       (const FcChar32*)text, length, &extents);
-               return extents.xOff;
-       }
-#endif
-       if(!get_font_struct(font)) return 0;
-       XChar2b xtext[length], *xp = xtext;
-       for( int i=0; i<length; ++i,++xp ) {
-               xp->byte1 = (unsigned char) (text[i] >> 8);
-               xp->byte2 = (unsigned char) (text[i] & 0xff);
-       }
-       return XTextWidth16(get_font_struct(font), xtext, length);
-}
-
 int BC_WindowBase::get_text_width(int font, const char *text, int length)
 {
        int i, j, w = 0, line_w = 0;
@@ -3356,7 +3355,7 @@ int BC_WindowBase::grab_buttons()
        XSync(top_level->display, False);
        if( XGrabButton(top_level->display, AnyButton, AnyModifier,
                        top_level->rootwin, True, ButtonPressMask | ButtonReleaseMask,
-                       GrabModeAsync, GrabModeSync, None, grabbed_cursor) == GrabSuccess ) {
+                       GrabModeAsync, GrabModeSync, None, None) == GrabSuccess ) {
                set_active_subwindow(this);
                return 0;
        }
@@ -3370,11 +3369,14 @@ void BC_WindowBase::ungrab_buttons()
 }
 void BC_WindowBase::grab_cursor()
 {
-       XDefineCursor(top_level->display, top_level->rootwin, grabbed_cursor);
+       Cursor cursor_grab = get_cursor_struct(GRABBED_CURSOR);
+       XGrabPointer(top_level->display, top_level->rootwin, True,
+               PointerMotionMask | ButtonPressMask | ButtonReleaseMask,
+               GrabModeAsync, GrabModeAsync, None, cursor_grab, CurrentTime);
 }
 void BC_WindowBase::ungrab_cursor()
 {
-       XUndefineCursor(top_level->display, top_level->rootwin);
+       XUngrabPointer(top_level->display, CurrentTime);
 }
 
 // for get_root_w/h
@@ -3695,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;