rework histogram_bezier, init wm icon set_icon(gg), update de.po+msg/txt
[goodguy/history.git] / cinelerra-5.1 / guicast / bcwindowbase.C
index 6f45933f714b85bf548054dde862b291c3b96941..1ef0d5939cc8e697ae71ffe3a94b2bbcdc894b3b 100644 (file)
@@ -46,6 +46,7 @@
 #include "mutex.h"
 #include "sizes.h"
 #include "vframe.h"
+#include "workarounds.h"
 
 #ifdef HAVE_GL
 #include <GL/gl.h>
@@ -61,7 +62,6 @@
 #include <X11/XF86keysym.h>
 #include <X11/Sunkeysym.h>
 
-
 BC_ResizeCall::BC_ResizeCall(int w, int h)
 {
        this->w = w;
@@ -181,10 +181,12 @@ BC_WindowBase::~BC_WindowBase()
                for( int i=sizeof(xfont)/sizeof(xfont[0]); --i>=0; )
                        XFreeFont(display, this->*xfont[i]);
 
-// 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)
+#ifdef HAVE_XFT
+// prevents a bug when Xft closes with unrefd fonts
+               FcPattern *defaults = FcPatternCreate();
+               FcPatternAddInteger(defaults, "maxunreffonts", 0);
+               XftDefaultSet(display, defaults);
+
                static void *BC_WindowBase::*xft_font[] = {
                         &BC_WindowBase::smallfont_xft,
                         &BC_WindowBase::mediumfont_xft,
@@ -197,7 +199,7 @@ BC_WindowBase::~BC_WindowBase()
                };
                for( int i=sizeof(xft_font)/sizeof(xft_font[0]); --i>=0; ) {
                        XftFont *xft = (XftFont *)(this->*xft_font[i]);
-                       if( xft ) XftFontClose (display, xft);
+                       if( xft ) xftFontClose (display, xft);
                }
 #endif
                finit_im();
@@ -255,6 +257,7 @@ int BC_WindowBase::initialize()
        keys_return[0] = 0;
        is_deleting = 0;
        window_lock = 0;
+       resend_event_window = 0;
        x = 0;
        y = 0;
        w = 0;
@@ -388,12 +391,8 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, const char *title
 #endif
 
        id = get_resources()->get_id();
-       int need_lock = 0;
        if(parent_window) top_level = parent_window->top_level;
-       if( top_level ) { // need this to avoid deadlock with Xlib's locks
-               need_lock = 1;
-               lock_window("BC_WindowBase::create_window");
-       }
+       if( top_level ) lock_window("BC_WindowBase::create_window");
        get_resources()->create_window_lock->lock("BC_WindowBase::create_window");
 
 #ifdef HAVE_LIBXXF86VM
@@ -443,6 +442,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, const char *title
                if( shm_completion_event < 0 ) shm_completion_event =
                        ShmCompletion + XShmGetEventBase(display);
 #endif
+               lock_window("BC_WindowBase::create_window 1");
 
                screen = DefaultScreen(display);
                rootwin = RootWindow(display, screen);
@@ -546,6 +546,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, const char *title
                                PropModeReplace, (unsigned char *)&XGroupLeader, true);
                }
                init_im();
+               set_icon(get_resources()->default_icon);
        }
 
 #ifdef HAVE_LIBXXF86VM
@@ -636,7 +637,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, const char *title
                if(!hidden) show_window();
        }
        get_resources()->create_window_lock->unlock();
-       if(need_lock) unlock_window();
+       unlock_window();
 
        return 0;
 }
@@ -996,7 +997,7 @@ locking_message = event->xclient.message_type;
                        done = 1;
                        } else
                        { // We currently use X marshalling for xatom events, we can switch to something else later
-                               recieve_custom_xatoms((xatom_event *)ptr);
+                               receive_custom_xatoms((xatom_event *)ptr);
                }
                break;
 
@@ -1254,6 +1255,20 @@ locking_message = event->xclient.message_type;
                case XK_KP_Insert:      key_pressed = KPINS;    break;
                case XK_KP_Decimal:
                case XK_KP_Delete:      key_pressed = KPDEL;    break;
+
+               case XK_F1:             key_pressed = KEY_F1;   break;
+               case XK_F2:             key_pressed = KEY_F2;   break;
+               case XK_F3:             key_pressed = KEY_F3;   break;
+               case XK_F4:             key_pressed = KEY_F4;   break;
+               case XK_F5:             key_pressed = KEY_F5;   break;
+               case XK_F6:             key_pressed = KEY_F6;   break;
+               case XK_F7:             key_pressed = KEY_F7;   break;
+               case XK_F8:             key_pressed = KEY_F8;   break;
+               case XK_F9:             key_pressed = KEY_F9;   break;
+               case XK_F10:            key_pressed = KEY_F10;  break;
+               case XK_F11:            key_pressed = KEY_F11;  break;
+               case XK_F12:            key_pressed = KEY_F12;  break;
+
                case XK_Menu:           key_pressed = KPMENU;   break;  /* menu */
 // remote control
 // above       case XK_KP_Enter:       key_pressed = KPENTER;  break;  /* check */
@@ -1323,19 +1338,26 @@ locking_message = event->xclient.message_type;
                break;
 
        case LeaveNotify:
-               if( cursor_entered && event->xcrossing.window == win ) {
-                       cursor_entered = 0;
-               }
+               if( event->xcrossing.mode != NotifyNormal ) break;
+               cursor_entered = 0;
                event_win = event->xany.window;
                dispatch_cursor_leave();
                break;
 
        case EnterNotify:
-               if( !cursor_entered && event->xcrossing.window == win ) {
-                       if( !event->xcrossing.focus && get_resources()->grab_input_focus ) {
-                               XSetInputFocus(display, win, RevertToParent, CurrentTime);
+               if( event->xcrossing.mode != NotifyNormal ) break;
+
+               if( !cursor_entered ) {
+                       for( int i=0; i<popups.size(); ++i ) {  // popups always take focus
+                               if( popups[i]->win == event->xcrossing.window )
+                               cursor_entered = 1;
                        }
-                       cursor_entered = 1;
+                       if( !cursor_entered && get_resources()->grab_input_focus &&
+                           !event->xcrossing.focus && event->xcrossing.window == win ) {
+                               cursor_entered = 1;
+                       }
+                       if( cursor_entered )
+                               focus();
                }
                event_win = event->xany.window;
                cursor_x = event->xcrossing.x;
@@ -1351,7 +1373,14 @@ locking_message = event->xclient.message_type;
 
 #ifndef SINGLE_THREAD
        unlock_window();
-       if(event) delete event;
+       if(event) {
+               if( resend_event_window ) {
+                       resend_event_window->put_event(event);
+                       resend_event_window = 0;
+               }
+               else
+                       delete event;
+       }
 #else
 //     if(done) completion_lock->unlock();
 #endif
@@ -1956,7 +1985,7 @@ int BC_WindowBase::arm_repeat(int64_t duration)
 }
 #endif
 
-int BC_WindowBase::recieve_custom_xatoms(xatom_event *event)
+int BC_WindowBase::receive_custom_xatoms(xatom_event *event)
 {
        return 0;
 }
@@ -2343,54 +2372,54 @@ static Mutex xft_init_lock("BC_WindowBase::xft_init_lock", 0);
 xft_init_lock.lock("BC_WindowBase::init_xft");
        if(!(smallfont_xft =
                (resources.small_font_xft[0] == '-' ?
-                       XftFontOpenXlfd(display, screen, resources.small_font_xft) :
-                       XftFontOpenName(display, screen, resources.small_font_xft))) )
+                       xftFontOpenXlfd(display, screen, resources.small_font_xft) :
+                       xftFontOpenName(display, screen, resources.small_font_xft))) )
                if(!(smallfont_xft =
-                       XftFontOpenXlfd(display, screen, resources.small_font_xft2)))
-                       smallfont_xft = XftFontOpenXlfd(display, screen, "fixed");
+                       xftFontOpenXlfd(display, screen, resources.small_font_xft2)))
+                       smallfont_xft = xftFontOpenXlfd(display, screen, "fixed");
        if(!(mediumfont_xft =
                (resources.medium_font_xft[0] == '-' ?
-                       XftFontOpenXlfd(display, screen, resources.medium_font_xft) :
-                       XftFontOpenName(display, screen, resources.medium_font_xft))) )
+                       xftFontOpenXlfd(display, screen, resources.medium_font_xft) :
+                       xftFontOpenName(display, screen, resources.medium_font_xft))) )
                if(!(mediumfont_xft =
-                       XftFontOpenXlfd(display, screen, resources.medium_font_xft2)))
-                       mediumfont_xft = XftFontOpenXlfd(display, screen, "fixed");
+                       xftFontOpenXlfd(display, screen, resources.medium_font_xft2)))
+                       mediumfont_xft = xftFontOpenXlfd(display, screen, "fixed");
        if(!(largefont_xft =
                (resources.large_font_xft[0] == '-' ?
-                       XftFontOpenXlfd(display, screen, resources.large_font_xft) :
-                       XftFontOpenName(display, screen, resources.large_font_xft))) )
+                       xftFontOpenXlfd(display, screen, resources.large_font_xft) :
+                       xftFontOpenName(display, screen, resources.large_font_xft))) )
                if(!(largefont_xft =
-                       XftFontOpenXlfd(display, screen, resources.large_font_xft2)))
-                       largefont_xft = XftFontOpenXlfd(display, screen, "fixed");
+                       xftFontOpenXlfd(display, screen, resources.large_font_xft2)))
+                       largefont_xft = xftFontOpenXlfd(display, screen, "fixed");
        if(!(bigfont_xft =
                (resources.big_font_xft[0] == '-' ?
-                       XftFontOpenXlfd(display, screen, resources.big_font_xft) :
-                       XftFontOpenName(display, screen, resources.big_font_xft))) )
+                       xftFontOpenXlfd(display, screen, resources.big_font_xft) :
+                       xftFontOpenName(display, screen, resources.big_font_xft))) )
                if(!(bigfont_xft =
-                       XftFontOpenXlfd(display, screen, resources.big_font_xft2)))
-                       bigfont_xft = XftFontOpenXlfd(display, screen, "fixed");
+                       xftFontOpenXlfd(display, screen, resources.big_font_xft2)))
+                       bigfont_xft = xftFontOpenXlfd(display, screen, "fixed");
        if(!(clockfont_xft =
                (resources.clock_font_xft[0] == '-' ?
-                       XftFontOpenXlfd(display, screen, resources.clock_font_xft) :
-                       XftFontOpenName(display, screen, resources.clock_font_xft))) )
-               clockfont_xft = XftFontOpenXlfd(display, screen, "fixed");
+                       xftFontOpenXlfd(display, screen, resources.clock_font_xft) :
+                       xftFontOpenName(display, screen, resources.clock_font_xft))) )
+               clockfont_xft = xftFontOpenXlfd(display, screen, "fixed");
 
 
        if(!(bold_smallfont_xft =
                (resources.small_b_font_xft[0] == '-' ?
-                       XftFontOpenXlfd(display, screen, resources.small_b_font_xft) :
-                       XftFontOpenName(display, screen, resources.small_b_font_xft))) )
-               bold_smallfont_xft = XftFontOpenXlfd(display, screen, "fixed");
+                       xftFontOpenXlfd(display, screen, resources.small_b_font_xft) :
+                       xftFontOpenName(display, screen, resources.small_b_font_xft))) )
+               bold_smallfont_xft = xftFontOpenXlfd(display, screen, "fixed");
        if(!(bold_mediumfont_xft =
                (resources.medium_b_font_xft[0] == '-' ?
-                       XftFontOpenXlfd(display, screen, resources.medium_b_font_xft) :
-                       XftFontOpenName(display, screen, resources.medium_b_font_xft))) )
-               bold_mediumfont_xft = XftFontOpenXlfd(display, screen, "fixed");
+                       xftFontOpenXlfd(display, screen, resources.medium_b_font_xft) :
+                       xftFontOpenName(display, screen, resources.medium_b_font_xft))) )
+               bold_mediumfont_xft = xftFontOpenXlfd(display, screen, "fixed");
        if(!(bold_largefont_xft =
                (resources.large_b_font_xft[0] == '-' ?
-                       XftFontOpenXlfd(display, screen, resources.large_b_font_xft) :
-                       XftFontOpenName(display, screen, resources.large_b_font_xft))) )
-               bold_largefont_xft = XftFontOpenXlfd(display, screen, "fixed");
+                       xftFontOpenXlfd(display, screen, resources.large_b_font_xft) :
+                       xftFontOpenName(display, screen, resources.large_b_font_xft))) )
+               bold_largefont_xft = xftFontOpenXlfd(display, screen, "fixed");
 
        if( !smallfont_xft || !mediumfont_xft || !largefont_xft || !bigfont_xft ||
            !bold_largefont_xft || !bold_mediumfont_xft || !bold_largefont_xft ||
@@ -2409,7 +2438,7 @@ xft_init_lock.lock("BC_WindowBase::init_xft");
                exit(1);
        }
 // _XftDisplayInfo needs a lock.
-       XftDefaultHasRender(display);
+       xftDefaultHasRender(display);
 xft_init_lock.unlock();
 #endif // HAVE_XFT
 }
@@ -2862,7 +2891,7 @@ int BC_WindowBase::get_single_text_width(int font, const char *text, int length)
 #ifdef X_HAVE_UTF8_STRING
                if(get_resources()->locale_utf8)
                {
-                       XftTextExtentsUtf8(top_level->display,
+                       xftTextExtentsUtf8(top_level->display,
                                get_xft_struct(font),
                                (const XftChar8 *)text,
                                length,
@@ -2871,7 +2900,7 @@ int BC_WindowBase::get_single_text_width(int font, const char *text, int length)
                else
 #endif
                {
-                       XftTextExtents8(top_level->display,
+                       xftTextExtents8(top_level->display,
                                get_xft_struct(font),
                                (const XftChar8 *)text,
                                length,
@@ -3431,6 +3460,8 @@ BC_WindowBase::get_xinerama_info(int screen)
                return 0;
        }
        int top_x = get_x(), top_y = get_y();
+       if(  BC_DisplayInfo::left_border >= 0 ) top_x +=  BC_DisplayInfo::left_border;
+       if(  BC_DisplayInfo::top_border >= 0 ) top_y +=  BC_DisplayInfo::top_border;
        for( int i=0; i<xinerama_screens; ++i ) {
                int scr_y = top_y - xinerama_info[i].y_org;
                if( scr_y < 0 || scr_y >= xinerama_info[i].height ) continue;
@@ -3441,6 +3472,38 @@ BC_WindowBase::get_xinerama_info(int screen)
        return 0;
 }
 
+void BC_WindowBase::get_fullscreen_geometry(int &wx, int &wy, int &ww, int &wh)
+{
+       XineramaScreenInfo *info = top_level->get_xinerama_info(-1);
+       if( info ) {
+               wx = info->x_org;  wy = info->y_org;
+               ww = info->width;  wh = info->height;
+       }
+       else {
+               wx = get_screen_x(0, -1);
+               wy = get_screen_y(0, -1);
+               int scr_w0 = get_screen_w(0, 0);
+               int root_w = get_root_w(0);
+               int root_h = get_root_h(0);
+               if( root_w > scr_w0 ) { // multi-headed
+                       if( wx >= scr_w0 ) {
+                               // assumes right side is the big one
+                               ww = root_w - scr_w0;
+                               wh = root_h;
+                       }
+                       else {
+                               // use same aspect ratio to compute left height
+                               ww = scr_w0;
+                               wh = (w*root_h) / (root_w-scr_w0);
+                       }
+               }
+               else {
+                       ww = root_w;
+                       wh = root_h;
+               }
+       }
+}
+
 int BC_WindowBase::get_screen_x(int lock_display, int screen)
 {
        int result = -1;
@@ -3839,17 +3902,27 @@ int BC_WindowBase::match_window(Window win)
 
 int BC_WindowBase::get_cursor_over_window()
 {
-       if(top_level != this) return top_level->get_cursor_over_window();
-
        int abs_x, abs_y, win_x, win_y;
-       unsigned int temp_mask;
+       unsigned int mask_return;
        Window root_return, child_return;
 
-       int ret = XQueryPointer(display, win,
+       int ret = XQueryPointer(top_level->display, top_level->rootwin,
                &root_return, &child_return, &abs_x, &abs_y,
-               &win_x, &win_y, &temp_mask);
-       if( ret && win != root_return && child_return != None )
-               ret = match_window(child_return);
+               &win_x, &win_y, &mask_return);
+       if( ret && child_return == None ) ret = 0;
+       if( ret && win != child_return )
+               ret = top_level->match_window(child_return);
+// query pointer can return a window manager window with this top_level as a child
+//  for kde this can be two levels deep
+       unsigned int nchildren_return = 0;
+       Window parent_return, *children_return = 0;
+       Window top_win = top_level->win;
+       while( !ret && top_win != top_level->rootwin && top_win != root_return &&
+               XQueryTree(top_level->display, top_win, &root_return,
+                       &parent_return, &children_return, &nchildren_return) ) {
+               if( children_return ) XFree(children_return);
+               if( (top_win=parent_return) == child_return ) ret = 1;
+       }
        return ret;
 }
 
@@ -4461,6 +4534,20 @@ void BC_WindowBase::dequeue_events(Window win)
        event_lock->unlock();
 }
 
+int BC_WindowBase::resend_event(BC_WindowBase *window)
+{
+       if( resend_event_window ) return 1;
+       resend_event_window = window;
+       return 0;
+}
+
+#else
+
+int BC_WindowBase::resend_event(BC_WindowBase *window)
+{
+       return 1;
+}
+
 #endif // SINGLE_THREAD
 
 int BC_WindowBase::get_id()
@@ -4490,3 +4577,11 @@ void BC_WindowBase::flicker(int n, int ms)
        set_opaque();
 }
 
+void BC_WindowBase::focus()
+{
+       XWindowAttributes xwa;
+       XGetWindowAttributes(top_level->display, top_level->win, &xwa);
+       if( xwa.map_state == IsViewable )
+               XSetInputFocus(top_level->display, top_level->win, RevertToParent, CurrentTime);
+}
+