X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fbcwindowbase.C;h=1f1d0d30c151581dfbe51cc2ff90ec67ab71e1e0;hp=3db866f89ca63620d166939a9fa064e59250ae39;hb=a2ebbc5e88800bd740652a32285f8145a1acfdc6;hpb=3bf30d220f7855b995b887dc10812ae3780e6805 diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index 3db866f8..1f1d0d30 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -149,7 +149,11 @@ BC_WindowBase::~BC_WindowBase() //printf("delete glx=%08x, win=%08x %s\n", (unsigned)glx_win, (unsigned)win, title); #ifdef HAVE_GL if( get_resources()->get_synchronous() && glx_win != 0 ) { + if( window_type == MAIN_WINDOW ) + unlock_window(); get_resources()->get_synchronous()->delete_window(this); + if( window_type == MAIN_WINDOW ) + lock_window("BC_WindowBase::delete_window"); } #endif XDestroyWindow(top_level->display, win); @@ -456,8 +460,16 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, const char *title vis = get_glx_visual(display); if( !vis ) #endif + { + int mask = VisualDepthMask | VisualClassMask; + static XVisualInfo vinfo = { .depth = 24, .c_class = DirectColor, }; + int nitems = 0; + XVisualInfo *vis_info = XGetVisualInfo(display, mask, &vinfo, &nitems); + vis = vis_info && nitems>0 ? vis_info[0].visual : 0; + if( vis_info ) XFree(vis_info); + } + if( !vis ) vis = DefaultVisual(display, screen); - default_depth = DefaultDepth(display, screen); client_byte_order = (*(const u_int32_t*)"a ") & 0x00000001; @@ -566,9 +578,8 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, const char *title mask = CWEventMask | CWBackPixel | CWColormap | CWOverrideRedirect | CWSaveUnder | CWCursor; - attr.event_mask = DEFAULT_EVENT_MASKS | - KeyPressMask | - KeyReleaseMask; + attr.event_mask = DEFAULT_EVENT_MASKS | ExposureMask | + KeyPressMask | KeyReleaseMask; if(this->bg_color == -1) this->bg_color = resources.get_bg_color(); @@ -648,18 +659,16 @@ Display* BC_WindowBase::init_display(const char *display_name) if(display_name && display_name[0] == 0) display_name = NULL; if((display = XOpenDisplay(display_name)) == NULL) { - printf("BC_WindowBase::init_display: cannot connect to X server %s\n", + printf("BC_WindowBase::init_display: cannot connect to X server %s\n", display_name); - if(getenv("DISPLAY") == NULL) { + if(getenv("DISPLAY") == NULL) { printf(_("'DISPLAY' environment variable not set.\n")); - exit(1); + exit(1); } - else { // Try again with default display. - if((display = XOpenDisplay(0)) == NULL) { - printf("BC_WindowBase::init_display: cannot connect to default X server.\n"); - exit(1); - } + if((display = XOpenDisplay(0)) == NULL) { + printf("BC_WindowBase::init_display: cannot connect to default X server.\n"); + exit(1); } } @@ -731,9 +740,8 @@ int BC_WindowBase::run_window() init_lock->unlock(); // Handle common events - while(!done) - { - dispatch_event(0); + while( !done ) { + dispatch_event(); } unset_all_repeaters(); @@ -873,7 +881,7 @@ int BC_WindowBase::keysym_lookup(XEvent *event) // wkey_string[0], wkey_string[1], wkey_string[2], wkey_string[3]); Status stat; - int ret = Xutf8LookupString(input_context, (XKeyEvent*)event, + int ret = Xutf8LookupString(input_context, (XKeyEvent*)event, keys_return, KEYPRESSLEN, &keysym, &stat); //printf("keysym_lookup 2 %d %d %lx %x %x\n", ret, stat, keysym, keys_return[0], keys_return[1]); if( stat == XLookupBoth ) return ret; @@ -889,13 +897,14 @@ pthread_t locking_task = (pthread_t)-1L; int locking_event = -1; int locking_message = -1; -int BC_WindowBase::dispatch_event(XEvent *event) +int BC_WindowBase::dispatch_event() { Window tempwin; int result; XClientMessageEvent *ptr; int cancel_resize, cancel_translation; - const int debug = 0; + volatile static int debug = 0; + XEvent *event; key_pressed = 0; @@ -932,23 +941,22 @@ locking_message = event->xclient.message_type; -//static const char *event_names[] = { -// "Reply", "Error", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease", "MotionNotify", -// "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut", "KeymapNotify", "Expose", "GraphicsExpose", -// "NoExpose", "VisibilityNotify", "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", -// "MapRequest", "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify", -// "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify", "SelectionClear", -// "SelectionRequest", "SelectionNotify", "ColormapNotify", "ClientMessage", "MappingNotify", -// "GenericEvent", "LASTEvent", -//}; -// -//if(debug) -//if(event->type != ClientMessage) { -// printf("BC_WindowBase::dispatch_event %d %s %p %d (%s)\n", -//__LINE__, title, event, event->type, -// event->type>=0 && event->typetype] : "Unknown"); -//} +if( debug && event->type != ClientMessage ) { + static const char *event_names[] = { + "Reply", "Error", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease", "MotionNotify", + "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut", "KeymapNotify", "Expose", "GraphicsExpose", + "NoExpose", "VisibilityNotify", "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify", + "MapRequest", "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify", + "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify", "SelectionClear", + "SelectionRequest", "SelectionNotify", "ColormapNotify", "ClientMessage", "MappingNotify", + "GenericEvent", "LASTEvent", + }; + const int nevents = sizeof(event_names)/sizeof(event_names[0]); + + printf("BC_WindowBase::dispatch_event %d %s %p %d (%s)\n", __LINE__, + title, event, event->type, event->type>=0 && event->typetype] : "Unknown"); +} if( active_grab ) { unlock_window(); @@ -962,42 +970,25 @@ locking_message = event->xclient.message_type; switch(event->type) { case ClientMessage: // Clear the resize buffer - if(resize_events) dispatch_resize_event(last_resize_w, last_resize_h); + if( resize_events ) + dispatch_resize_event(last_resize_w, last_resize_h); // Clear the motion buffer since this can clear the window - if(motion_events) - { + if( motion_events ) dispatch_motion_event(); - } ptr = (XClientMessageEvent*)event; - - - if(ptr->message_type == ProtoXAtom && - (Atom)ptr->data.l[0] == DelWinXAtom) - { + if( ptr->message_type == ProtoXAtom && + (Atom)ptr->data.l[0] == DelWinXAtom ) { close_event(); } - else - if(ptr->message_type == RepeaterXAtom) - { + else if( ptr->message_type == RepeaterXAtom ) { dispatch_repeat_event(ptr->data.l[0]); -// Make sure the repeater still exists. -// for(int i = 0; i < repeaters.total; i++) -// { -// if(repeaters.values[i]->repeat_id == ptr->data.l[0]) -// { -// dispatch_repeat_event_master(ptr->data.l[0]); -// break; -// } -// } } - else - if(ptr->message_type == SetDoneXAtom) - { + else if( ptr->message_type == SetDoneXAtom ) { done = 1; - } else - { // We currently use X marshalling for xatom events, we can switch to something else later - receive_custom_xatoms((xatom_event *)ptr); + } + else { + receive_custom_xatoms((xatom_event *)ptr); } break; @@ -1031,8 +1022,7 @@ locking_message = event->xclient.message_type; //printf("BC_WindowBase::dispatch_event %d %d\n", __LINE__, button_number); event_win = event->xany.window; - if (button_number < 6) - { + if (button_number < 6) { if(button_number < 4) button_down = 1; button_pressed = event->xbutton.button; @@ -1087,7 +1077,13 @@ locking_message = event->xclient.message_type; case Expose: event_win = event->xany.window; - dispatch_expose_event(); + result = 0; + for( int i=0; !result && iwin == event_win ) + result = popups[i]->dispatch_expose_event(); + } + if( !result ) + result = dispatch_expose_event(); break; case MotionNotify: @@ -2112,13 +2108,11 @@ int BC_WindowBase::init_colors() switch(color_model) { case BC_RGB8: - if(private_color) - { - cmap = XCreateColormap(display, rootwin, vis, AllocNone); + if(private_color) { + cmap = XCreateColormap(display, rootwin, vis, AllocNone); create_private_colors(); } - else - { + else { cmap = DefaultColormap(display, screen); create_shared_colors(); } @@ -3319,13 +3313,10 @@ int BC_WindowBase::unlock_window() if(top_level) { UNSET_LOCK(this); - -// if(!top_level->window_lock) -// { -// printf("BC_WindowBase::unlock_window %d %s already unlocked\n", -// __LINE__, -// title); -// } + if( !top_level->window_lock ) { + printf("BC_WindowBase::unlock_window %s not locked\n", title); + booby(); + } if( top_level->window_lock > 0 ) if( --top_level->window_lock == 0 ) top_level->display_lock_owner = 0; @@ -3342,6 +3333,23 @@ int BC_WindowBase::unlock_window() return 0; } +int BC_WindowBase::break_lock() +{ + if( !top_level ) return 0; + if( top_level != this ) return top_level->break_lock(); + if( top_level->display_lock_owner != pthread_self() ) return 0; + if( top_level->window_lock != 1 ) return 0; + UNSET_LOCK(this); + window_lock = 0; + display_lock_owner = 0; +#ifdef SINGLE_THREAD + BC_Display::unlock_display(); +#else + XUnlockDisplay(display); +#endif + return 1; +} + void BC_WindowBase::set_done(int return_value) { if(done_set) return; @@ -3427,7 +3435,7 @@ void BC_WindowBase::grab_cursor() } void BC_WindowBase::ungrab_cursor() { - XUngrabPointer(top_level->display, CurrentTime); + XUngrabPointer(top_level->display, CurrentTime); } // for get_root_w/h @@ -4060,6 +4068,11 @@ int BC_WindowBase::resize_window(int w, int h) size_hints.max_width = w; size_hints.min_height = h; size_hints.max_height = h; + if( this->x > -BC_INFINITY && this->x < BC_INFINITY ) { + size_hints.flags |= PPosition; + size_hints.x = this->x; + size_hints.y = this->y; + } XSetNormalHints(top_level->display, win, &size_hints); } XResizeWindow(top_level->display, win, w, h); @@ -4412,81 +4425,65 @@ void BC_WindowBase::get_win_coordinates(int abs_x, int abs_y, int *x, int *y) #ifdef HAVE_LIBXXF86VM void BC_WindowBase::closest_vm(int *vm, int *width, int *height) { - int foo,bar; - *vm = 0; - if(XF86VidModeQueryExtension(top_level->display,&foo,&bar)) { - int vm_count,i; - XF86VidModeModeInfo **vm_modelines; - XF86VidModeGetAllModeLines(top_level->display,XDefaultScreen(top_level->display),&vm_count,&vm_modelines); - for (i = 0; i < vm_count; i++) { - if (vm_modelines[i]->hdisplay < vm_modelines[*vm]->hdisplay && vm_modelines[i]->hdisplay >= *width) - *vm = i; - } - display = top_level->display; - if (vm_modelines[*vm]->hdisplay == *width) - *vm = -1; - else - { - *width = vm_modelines[*vm]->hdisplay; - *height = vm_modelines[*vm]->vdisplay; - } - } + int foo,bar; + *vm = 0; + if(XF86VidModeQueryExtension(top_level->display,&foo,&bar)) { + int vm_count,i; + XF86VidModeModeInfo **vm_modelines; + XF86VidModeGetAllModeLines(top_level->display, + XDefaultScreen(top_level->display), &vm_count,&vm_modelines); + for( i = 0; i < vm_count; i++ ) { + if( vm_modelines[i]->hdisplay < vm_modelines[*vm]->hdisplay && + vm_modelines[i]->hdisplay >= *width ) + *vm = i; + } + display = top_level->display; + if( vm_modelines[*vm]->hdisplay == *width ) + *vm = -1; + else { + *width = vm_modelines[*vm]->hdisplay; + *height = vm_modelines[*vm]->vdisplay; + } + } } void BC_WindowBase::scale_vm(int vm) { - int foo,bar,dotclock; - if(XF86VidModeQueryExtension(top_level->display,&foo,&bar)) - { - int vm_count; - XF86VidModeModeInfo **vm_modelines; - XF86VidModeModeLine vml; - XF86VidModeGetAllModeLines(top_level->display,XDefaultScreen(top_level->display),&vm_count,&vm_modelines); - XF86VidModeGetModeLine(top_level->display,XDefaultScreen(top_level->display),&dotclock,&vml); - orig_modeline.dotclock = dotclock; - orig_modeline.hdisplay = vml.hdisplay; - orig_modeline.hsyncstart = vml.hsyncstart; - orig_modeline.hsyncend = vml.hsyncend; - orig_modeline.htotal = vml.htotal; - orig_modeline.vdisplay = vml.vdisplay; - orig_modeline.vsyncstart = vml.vsyncstart; - orig_modeline.vsyncend = vml.vsyncend; - orig_modeline.vtotal = vml.vtotal; - orig_modeline.flags = vml.flags; - orig_modeline.privsize = vml.privsize; - // orig_modeline.private = vml.private; - XF86VidModeSwitchToMode(top_level->display,XDefaultScreen(top_level->display),vm_modelines[vm]); - XF86VidModeSetViewPort(top_level->display,XDefaultScreen(top_level->display),0,0); - XFlush(top_level->display); - } + int foo,bar,dotclock; + if( XF86VidModeQueryExtension(top_level->display,&foo,&bar) ) { + int vm_count; + XF86VidModeModeInfo **vm_modelines; + XF86VidModeModeLine vml; + XF86VidModeGetAllModeLines(top_level->display, + XDefaultScreen(top_level->display), &vm_count,&vm_modelines); + XF86VidModeGetModeLine(top_level->display, + XDefaultScreen(top_level->display), &dotclock,&vml); + orig_modeline.dotclock = dotclock; + orig_modeline.hdisplay = vml.hdisplay; + orig_modeline.hsyncstart = vml.hsyncstart; + orig_modeline.hsyncend = vml.hsyncend; + orig_modeline.htotal = vml.htotal; + orig_modeline.vdisplay = vml.vdisplay; + orig_modeline.vsyncstart = vml.vsyncstart; + orig_modeline.vsyncend = vml.vsyncend; + orig_modeline.vtotal = vml.vtotal; + orig_modeline.flags = vml.flags; + orig_modeline.privsize = vml.privsize; + // orig_modeline.private = vml.private; + XF86VidModeSwitchToMode(top_level->display,XDefaultScreen(top_level->display),vm_modelines[vm]); + XF86VidModeSetViewPort(top_level->display,XDefaultScreen(top_level->display),0,0); + XFlush(top_level->display); + } } void BC_WindowBase::restore_vm() { - XF86VidModeSwitchToMode(top_level->display,XDefaultScreen(top_level->display),&orig_modeline); - XFlush(top_level->display); + XF86VidModeSwitchToMode(top_level->display,XDefaultScreen(top_level->display),&orig_modeline); + XFlush(top_level->display); } - - #endif - - - - - - - - - - - - - - - - #ifndef SINGLE_THREAD int BC_WindowBase::get_event_count() {