X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fbcwindowbase.C;h=1ef0d5939cc8e697ae71ffe3a94b2bbcdc894b3b;hp=8654bbe7238bb6ed66d66e201c3e3a10bb05d238;hb=04031cc2a664d2a6d9d2a37954c55cc68742d78c;hpb=faf9f1da60357505e88f5be80c0256a64bf2d650 diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index 8654bbe7..1ef0d593 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -36,7 +36,7 @@ #include "bcwindowbase.h" #include "bcwindowevents.h" #include "bccmodels.h" -#include "colors.h" +#include "bccolors.h" #include "condition.h" #include "cursors.h" #include "bchash.h" @@ -46,6 +46,7 @@ #include "mutex.h" #include "sizes.h" #include "vframe.h" +#include "workarounds.h" #ifdef HAVE_GL #include @@ -61,7 +62,6 @@ #include #include - BC_ResizeCall::BC_ResizeCall(int w, int h) { this->w = w; @@ -85,9 +85,8 @@ Window XGroupLeader = 0; Mutex BC_KeyboardHandlerLock::keyboard_listener_mutex("keyboard_listener",0); ArrayList BC_KeyboardHandler::listeners; -BC_WindowBase::BC_WindowBase(int opts) +BC_WindowBase::BC_WindowBase() { - this->options = opts; //printf("BC_WindowBase::BC_WindowBase 1\n"); BC_WindowBase::initialize(); } @@ -147,13 +146,13 @@ BC_WindowBase::~BC_WindowBase() delete pixmap; +//printf("delete glx=%08x, win=%08x %s\n", (unsigned)glx_win, (unsigned)win, title); #ifdef HAVE_GL - if( get_resources()->get_synchronous() && - (top_level->options & GLX_WINDOW) && glx_win != 0 ) + if( get_resources()->get_synchronous() && glx_win != 0 ) { get_resources()->get_synchronous()->delete_window(this); - else + } #endif - XDestroyWindow(top_level->display, win); + XDestroyWindow(top_level->display, win); if(bg_pixmap && !shared_bg_pixmap) delete bg_pixmap; if(icon_pixmap) delete icon_pixmap; @@ -177,13 +176,17 @@ BC_WindowBase::~BC_WindowBase() &BC_WindowBase::mediumfont, &BC_WindowBase::largefont, &BC_WindowBase::bigfont, + &BC_WindowBase::clockfont, }; 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 +#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, @@ -192,10 +195,11 @@ BC_WindowBase::~BC_WindowBase() &BC_WindowBase::bold_smallfont_xft, &BC_WindowBase::bold_mediumfont_xft, &BC_WindowBase::bold_largefont_xft, + &BC_WindowBase::clockfont_xft, }; 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(); @@ -210,23 +214,15 @@ BC_WindowBase::~BC_WindowBase() XvUngrabPort(display, xvideo_port_id, CurrentTime); unlock_window(); -// Can't close display if another thread is waiting for events. -// Synchronous thread must delete display it owns a GLX_WINDOW // Must be last reference to display. -#ifndef SINGLE_THREAD -#ifdef HAVE_GL - if( (options & GLX_DISPLAY) != 0 && get_resources()->get_synchronous() ) { - printf(_("BC_WindowBase::~BC_WindowBase window deleted but opengl deletion is not\n" - "implemented for BC_Pixmap.\n")); - get_resources()->get_synchronous()->delete_display(this); - } - else -#endif - XCloseDisplay(display); +// _XftDisplayInfo needs a lock. + get_resources()->create_window_lock->lock("BC_WindowBase::~BC_WindowBase"); + XCloseDisplay(display); + get_resources()->create_window_lock->unlock(); + // clipboard uses a different display connection clipboard->stop_clipboard(); delete clipboard; -#endif // SINGLE_THREAD } resize_history.remove_all_objects(); @@ -261,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; @@ -295,6 +292,7 @@ int BC_WindowBase::initialize() active_menubar = 0; active_popup_menu = 0; active_subwindow = 0; + cursor_entered = 0; pixmap = 0; bg_pixmap = 0; _7segment_pixmaps = 0; @@ -324,16 +322,24 @@ int BC_WindowBase::initialize() #ifdef HAVE_LIBXXF86VM vm_switched = 0; #endif - smallfont_xft = 0; - bold_largefont_xft = 0; - bold_mediumfont_xft = 0; - bold_smallfont_xft = 0; input_method = 0; input_context = 0; + smallfont = 0; + mediumfont = 0; + largefont = 0; + bigfont = 0; + clockfont = 0; + + smallfont_xft = 0; mediumfont_xft = 0; largefont_xft = 0; bigfont_xft = 0; + clockfont_xft = 0; + + bold_smallfont_xft = 0; + bold_mediumfont_xft = 0; + bold_largefont_xft = 0; #ifdef SINGLE_THREAD completion_lock = new Condition(0, "BC_WindowBase::completion_lock"); #else @@ -370,22 +376,10 @@ int BC_WindowBase::initialize() FocusChangeMask -int BC_WindowBase::create_window(BC_WindowBase *parent_window, - const char *title, - int x, - int y, - int w, - int h, - int minw, - int minh, - int allow_resize, - int private_color, - int hide, - int bg_color, - const char *display_name, - int window_type, - BC_Pixmap *bg_pixmap, - int group_it) +int BC_WindowBase::create_window(BC_WindowBase *parent_window, const char *title, + int x, int y, int w, int h, int minw, int minh, int allow_resize, + int private_color, int hide, int bg_color, const char *display_name, + int window_type, BC_Pixmap *bg_pixmap, int group_it) { XSetWindowAttributes attr; unsigned long mask; @@ -397,12 +391,8 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, #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 @@ -426,7 +416,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, else this->display_name[0] = 0; - put_title(_(title)); + put_title(title); if(bg_pixmap) shared_bg_pixmap = 1; subwindows = new BC_SubWindowList; @@ -452,6 +442,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, 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); @@ -529,24 +520,11 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, size_hints.x = this->x; size_hints.y = this->y; } - - char *txlist[2]; - txlist[0] = this->title; - txlist[1] = 0; - XTextProperty titleprop; - if(options & WINDOW_UTF8) - Xutf8TextListToTextProperty(display, txlist, 1, - XUTF8StringStyle, &titleprop); - else - XmbTextListToTextProperty(display, txlist, 1, - XStdICCTextStyle, &titleprop); - XSetWMProperties(display, win, &titleprop, &titleprop, - 0, 0, &size_hints, 0, 0); - XFree(titleprop.value); + XSetWMProperties(display, win, 0, 0, 0, 0, &size_hints, 0, 0); get_atoms(); - + set_title(title); #ifndef SINGLE_THREAD - clipboard = new BC_Clipboard(display_name); + clipboard = new BC_Clipboard(this); clipboard->start_clipboard(); #endif @@ -568,6 +546,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, PropModeReplace, (unsigned char *)&XGroupLeader, true); } init_im(); + set_icon(get_resources()->default_icon); } #ifdef HAVE_LIBXXF86VM @@ -658,7 +637,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, if(!hidden) show_window(); } get_resources()->create_window_lock->unlock(); - if(need_lock) unlock_window(); + unlock_window(); return 0; } @@ -683,6 +662,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 +950,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 @@ -1006,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; @@ -1029,6 +1020,10 @@ locking_message = event->xclient.message_type; break; case ButtonPress: + if(motion_events) + { + dispatch_motion_event(); + } get_key_masks(event->xbutton.state); cursor_x = event->xbutton.x; cursor_y = event->xbutton.y; @@ -1073,6 +1068,10 @@ locking_message = event->xclient.message_type; break; case ButtonRelease: + if(motion_events) + { + dispatch_motion_event(); + } get_key_masks(event->xbutton.state); button_number = event->xbutton.button; event_win = event->xany.window; @@ -1256,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 */ @@ -1325,16 +1338,33 @@ locking_message = event->xclient.message_type; break; case LeaveNotify: + if( event->xcrossing.mode != NotifyNormal ) break; + cursor_entered = 0; event_win = event->xany.window; dispatch_cursor_leave(); break; case EnterNotify: + if( event->xcrossing.mode != NotifyNormal ) break; + + if( !cursor_entered ) { + for( int i=0; iwin == event->xcrossing.window ) + 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; cursor_y = event->xcrossing.y; dispatch_cursor_enter(); break; + default: break; } @@ -1343,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 @@ -1800,7 +1837,7 @@ int BC_WindowBase::show_tooltip(const char *text, int x, int y, int w, int h) if( wy >= (y1-=h) ) wy = y1; // avoid tip under cursor (flickers) int abs_x, abs_y; - get_abs_cursor_xy(abs_x,abs_y, 0); + get_abs_cursor(abs_x,abs_y, 0); if( wx < abs_x && abs_x < wx+w && wy < abs_y && abs_y < wy+h ) { if( wx-abs_x < wy-abs_y ) wx = abs_x+1; @@ -1948,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; } @@ -2287,6 +2324,10 @@ int BC_WindowBase::init_fonts() if( !(bigfont = XLoadQueryFont(display, _(resources.big_font2))) ) bigfont = XLoadQueryFont(display, "fixed"); + if((clockfont = XLoadQueryFont(display, _(resources.clock_font))) == NULL) + if((clockfont = XLoadQueryFont(display, _(resources.clock_font2))) == NULL) + clockfont = XLoadQueryFont(display, "fixed"); + init_xft(); if(get_resources()->use_fontset) { @@ -2305,8 +2346,11 @@ int BC_WindowBase::init_fonts() largefontset = XCreateFontSet(display, "fixed,*", &m, &n, &d); bigfontset = XCreateFontSet(display, resources.big_fontset, &m, &n, &d); if( !bigfontset ) - largefontset = XCreateFontSet(display, "fixed,*", &m, &n, &d); - if(bigfontset && largefontset && mediumfontset && smallfontset) { + bigfontset = XCreateFontSet(display, "fixed,*", &m, &n, &d); + clockfontset = XCreateFontSet(display, resources.clock_fontset, &m, &n, &d); + if( !clockfontset ) + clockfontset = XCreateFontSet(display, "fixed,*", &m, &n, &d); + if(clockfontset && bigfontset && largefontset && mediumfontset && smallfontset) { curr_fontset = mediumfontset; get_resources()->use_fontset = 1; } @@ -2323,66 +2367,79 @@ void BC_WindowBase::init_xft() { #ifdef HAVE_XFT if( !get_resources()->use_xft ) return; +// apparently, xft is not reentrant, more than this is needed +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"); + 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"); -// Extension failed to locate fonts if( !smallfont_xft || !mediumfont_xft || !largefont_xft || !bigfont_xft || - !bold_largefont_xft || !bold_mediumfont_xft || !bold_largefont_xft ) { + !bold_largefont_xft || !bold_mediumfont_xft || !bold_largefont_xft || + !clockfont_xft ) { printf("BC_WindowBase::init_fonts: no xft fonts found:" - " %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n", + " %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n", resources.small_font_xft, smallfont_xft, resources.medium_font_xft, mediumfont_xft, resources.large_font_xft, largefont_xft, resources.big_font_xft, bigfont_xft, + resources.clock_font_xft, clockfont_xft, resources.small_b_font_xft, bold_smallfont_xft, resources.medium_b_font_xft, bold_mediumfont_xft, resources.large_b_font_xft, bold_largefont_xft); get_resources()->use_xft = 0; exit(1); } +// _XftDisplayInfo needs a lock. + xftDefaultHasRender(display); +xft_init_lock.unlock(); #endif // HAVE_XFT } @@ -2733,6 +2790,7 @@ XFontStruct* BC_WindowBase::get_font_struct(int font) case MEDIUMFONT: return top_level->mediumfont; break; case LARGEFONT: return top_level->largefont; break; case BIGFONT: return top_level->bigfont; break; + case CLOCKFONT: return top_level->clockfont; break; } return 0; } @@ -2748,6 +2806,7 @@ XFontSet BC_WindowBase::get_fontset(int font) case MEDIUMFONT: fs = top_level->mediumfontset; break; case LARGEFONT: fs = top_level->largefontset; break; case BIGFONT: fs = top_level->bigfontset; break; + case CLOCKFONT: fs = top_level->clockfontset; break; } } @@ -2762,6 +2821,7 @@ XftFont* BC_WindowBase::get_xft_struct(int font) case MEDIUMFONT: return (XftFont*)top_level->mediumfont_xft; case LARGEFONT: return (XftFont*)top_level->largefont_xft; case BIGFONT: return (XftFont*)top_level->bigfont_xft; + case CLOCKFONT: return (XftFont*)top_level->clockfont_xft; case MEDIUMFONT_3D: return (XftFont*)top_level->bold_mediumfont_xft; case SMALLFONT_3D: return (XftFont*)top_level->bold_smallfont_xft; case LARGEFONT_3D: return (XftFont*)top_level->bold_largefont_xft; @@ -2772,13 +2832,6 @@ XftFont* BC_WindowBase::get_xft_struct(int font) #endif - - - - - - - int BC_WindowBase::get_current_font() { return top_level->current_font; @@ -2814,6 +2867,7 @@ void BC_WindowBase::set_fontset(int font) case MEDIUMFONT: fs = top_level->mediumfontset; break; case LARGEFONT: fs = top_level->largefontset; break; case BIGFONT: fs = top_level->bigfontset; break; + case CLOCKFONT: fs = top_level->clockfontset; break; } } @@ -2837,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, @@ -2846,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, @@ -3336,6 +3390,14 @@ int BC_WindowBase::ungrab(BC_WindowBase *window) this->grab_active = 0; return 1; } +int BC_WindowBase::grab_event_count() +{ + int result = 0; +#ifndef SINGLE_THREAD + result = grab_active->get_event_count(); +#endif + return result; +} int BC_WindowBase::grab_buttons() { XSync(top_level->display, False); @@ -3398,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_info[i].height ) continue; @@ -3408,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; @@ -3683,13 +3779,45 @@ BC_Clipboard* BC_WindowBase::get_clipboard() #endif } -void BC_WindowBase::get_relative_cursor_xy(int &x, int &y, int lock_window) +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(int &x, int &y, int lock_window) { int abs_x, abs_y, win_x, win_y; unsigned int temp_mask; Window temp_win; - if(lock_window) this->lock_window("BC_WindowBase::get_relative_cursor_xy"); + if(lock_window) this->lock_window("BC_WindowBase::get_relative_cursor"); XQueryPointer(top_level->display, top_level->win, &temp_win, &temp_win, &abs_x, &abs_y, &win_x, &win_y, &temp_mask); @@ -3701,23 +3829,23 @@ void BC_WindowBase::get_relative_cursor_xy(int &x, int &y, int lock_window) int BC_WindowBase::get_relative_cursor_x(int lock_window) { int x, y; - get_relative_cursor_xy(x, y, lock_window); + get_relative_cursor(x, y, lock_window); return x; } int BC_WindowBase::get_relative_cursor_y(int lock_window) { int x, y; - get_relative_cursor_xy(x, y, lock_window); + get_relative_cursor(x, y, lock_window); return y; } -void BC_WindowBase::get_abs_cursor_xy(int &abs_x, int &abs_y, int lock_window) +void BC_WindowBase::get_abs_cursor(int &abs_x, int &abs_y, int lock_window) { int win_x, win_y; unsigned int temp_mask; Window temp_win; - if(lock_window) this->lock_window("BC_WindowBase::get_abs_cursor_xy"); + if(lock_window) this->lock_window("BC_WindowBase::get_abs_cursor"); XQueryPointer(top_level->display, top_level->win, &temp_win, &temp_win, &abs_x, &abs_y, &win_x, &win_y, &temp_mask); @@ -3726,20 +3854,20 @@ void BC_WindowBase::get_abs_cursor_xy(int &abs_x, int &abs_y, int lock_window) int BC_WindowBase::get_abs_cursor_x(int lock_window) { int abs_x, abs_y; - get_abs_cursor_xy(abs_x, abs_y, lock_window); + get_abs_cursor(abs_x, abs_y, lock_window); return abs_x; } int BC_WindowBase::get_abs_cursor_y(int lock_window) { int abs_x, abs_y; - get_abs_cursor_xy(abs_x, abs_y, lock_window); + get_abs_cursor(abs_x, abs_y, lock_window); return abs_y; } -void BC_WindowBase::get_pop_cursor_xy(int &px, int &py, int lock_window) +void BC_WindowBase::get_pop_cursor(int &px, int &py, int lock_window) { int margin = 100; - get_abs_cursor_xy(px, py, lock_window); + get_abs_cursor(px, py, lock_window); if( px < margin ) px = margin; if( py < margin ) py = margin; int wd = get_screen_w(lock_window,-1) - margin; @@ -3750,13 +3878,13 @@ void BC_WindowBase::get_pop_cursor_xy(int &px, int &py, int lock_window) int BC_WindowBase::get_pop_cursor_x(int lock_window) { int px, py; - get_pop_cursor_xy(px, py, lock_window); + get_pop_cursor(px, py, lock_window); return px; } int BC_WindowBase::get_pop_cursor_y(int lock_window) { int px, py; - get_pop_cursor_xy(px, py, lock_window); + get_pop_cursor(px, py, lock_window); return py; } @@ -3774,27 +3902,34 @@ 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); -//printf("BC_WindowBase::get_cursor_over_window %d %s 0x%x %d 0x%x\n", -// __LINE__, title, win, ret, child_return); - - int result = !ret || child_return == None ? 0 : - match_window(child_return); - return result; + &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; } int BC_WindowBase::cursor_above() { int rx, ry; - get_relative_cursor_xy(rx, ry); + get_relative_cursor(rx, ry); return rx < 0 || rx >= get_w() || ry < 0 || ry >= get_h() ? 0 : 1; } @@ -4078,39 +4213,30 @@ void BC_WindowBase::put_title(const char *text) *cp = 0; } -void BC_WindowBase::set_title(const char *text) -{ - put_title(_(text)); - - char *txlist[2]; - txlist[0] = this->title; - txlist[1] = 0; - - XTextProperty titleprop; - XmbTextListToTextProperty(top_level->display, txlist, 1, - XStdICCTextStyle, &titleprop); - XSetWMName(top_level->display, top_level->win, &titleprop); - XSetWMIconName(top_level->display, top_level->win, &titleprop); - XFree(titleprop.value); - - flush(); -} - -void BC_WindowBase::set_utf8title(const char *text) -{ - XTextProperty titleprop; - char *txlist[2]; - - strcpy(this->title, text); - txlist[0] = this->title; - txlist[1] = 0; - - Xutf8TextListToTextProperty(top_level->display, txlist, 1, - XUTF8StringStyle, &titleprop); - XSetWMName(top_level->display, top_level->win, &titleprop); - XSetWMIconName(top_level->display, top_level->win, &titleprop); - XFree(titleprop.value); - +void BC_WindowBase::set_title(const char *text, int utf8) +{ +// utf8>0: wm + net_wm, utf8=0: wm only, utf<0: net_wm only + put_title(text); + const unsigned char *wm_title = (const unsigned char *)title; + int title_len = strlen((const char *)title); + if( utf8 >= 0 ) { + Atom xa_wm_name = XA_WM_NAME; + Atom xa_icon_name = XA_WM_ICON_NAME; + Atom xa_string = XA_STRING; + XChangeProperty(display, win, xa_wm_name, xa_string, 8, + PropModeReplace, wm_title, title_len); + XChangeProperty(display, win, xa_icon_name, xa_string, 8, + PropModeReplace, wm_title, title_len); + } + if( utf8 != 0 ) { + Atom xa_net_wm_name = XInternAtom(display, "_NET_WM_NAME", True); + Atom xa_net_icon_name = XInternAtom(display, "_NET_WM_ICON_NAME", True); + Atom xa_utf8_string = XInternAtom(display, "UTF8_STRING", True); + XChangeProperty(display, win, xa_net_wm_name, xa_utf8_string, 8, + PropModeReplace, wm_title, title_len); + XChangeProperty(display, win, xa_net_icon_name, xa_utf8_string, 8, + PropModeReplace, wm_title, title_len); + } flush(); } @@ -4200,6 +4326,7 @@ int BC_WindowBase::load_defaults(BC_Hash *defaults) resources->filebox_columnwidth[1] = defaults->get("FILEBOX_WIDTH1", resources->filebox_columnwidth[1]); resources->filebox_columnwidth[2] = defaults->get("FILEBOX_WIDTH2", resources->filebox_columnwidth[2]); resources->filebox_columnwidth[3] = defaults->get("FILEBOX_WIDTH3", resources->filebox_columnwidth[3]); + resources->filebox_size_format = defaults->get("FILEBOX_SIZE_FORMAT", get_resources()->filebox_size_format); defaults->get("FILEBOX_FILTER", resources->filebox_filter); return 0; } @@ -4227,6 +4354,7 @@ int BC_WindowBase::save_defaults(BC_Hash *defaults) defaults->update("FILEBOX_WIDTH2", resources->filebox_columnwidth[2]); defaults->update("FILEBOX_WIDTH3", resources->filebox_columnwidth[3]); defaults->update("FILEBOX_FILTER", resources->filebox_filter); + defaults->update("FILEBOX_SIZE_FORMAT", get_resources()->filebox_size_format); return 0; } @@ -4406,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() @@ -4435,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); +} +