X-Git-Url: http://git.cinelerra-gg.org/git/?a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fbcwindowbase.C;h=75e37fb472633a6db03eb7a0d88293d39021a137;hb=21c2e6b36d6a96c2f662a89459d607b5a387f4eb;hp=0c34217adfa474ea83cb4912001c0489e74260b4;hpb=30bdb85eb33a8ee7ba675038a86c6be59c43d7bd;p=goodguy%2Fhistory.git diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index 0c34217a..75e37fb4 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -101,15 +102,21 @@ BC_WindowBase::~BC_WindowBase() #endif #ifdef HAVE_LIBXXF86VM - if(window_type == VIDMODE_SCALED_WINDOW && vm_switched) - { - restore_vm(); - } + if(window_type == VIDMODE_SCALED_WINDOW && vm_switched) { + restore_vm(); + } #endif + is_deleting = 1; hide_tooltip(); if(window_type != MAIN_WINDOW) { +// stop event input + XSelectInput(top_level->display, this->win, 0); + motion_events = resize_events = translation_events = 0; +#ifndef SINGLE_THREAD + top_level->dequeue_events(win); +#endif if(top_level->active_menubar == this) top_level->active_menubar = 0; if(top_level->active_popup_menu == this) top_level->active_popup_menu = 0; if(top_level->active_subwindow == this) top_level->active_subwindow = 0; @@ -118,10 +125,10 @@ BC_WindowBase::~BC_WindowBase() } if(icon_window) delete icon_window; - if(window_type == POPUP_WINDOW) parent_window->remove_popup(this); + if(window_type == POPUP_WINDOW) + parent_window->remove_popup(this); // Delete the subwindows - is_deleting = 1; if(subwindows) { while(subwindows->total) @@ -186,7 +193,6 @@ BC_WindowBase::~BC_WindowBase() } #endif finit_im(); - flush(); sync_display(); @@ -194,6 +200,8 @@ BC_WindowBase::~BC_WindowBase() XFree(xinerama_info); xinerama_screens = 0; xinerama_info = 0; + if( xvideo_port_id >= 0 ) + XvUngrabPort(display, xvideo_port_id, CurrentTime); unlock_window(); // Can't close display if another thread is waiting for events. @@ -242,6 +250,7 @@ int BC_WindowBase::initialize() done = 0; done_set = 0; window_running = 0; + display_lock_owner = 0; test_keypress = 0; keys_return[0] = 0; is_deleting = 0; @@ -339,6 +348,8 @@ int BC_WindowBase::initialize() glx_win = 0; #endif + flash_enabled = 1; + win = 0; return 0; } @@ -625,9 +636,6 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, } - - - draw_background(0, 0, this->w, this->h); flash(-1, -1, -1, -1, 0); @@ -882,7 +890,7 @@ int BC_WindowBase::keysym_lookup(XEvent *event) return ret; } -pthread_t locking_task = -1; +pthread_t locking_task = (pthread_t)-1L; int locking_event = -1; int locking_message = -1; @@ -1352,32 +1360,40 @@ int BC_WindowBase::dispatch_resize_event(int w, int h) // Can't store new w and h until the event is handles // because bcfilebox depends on the old w and h to // reposition widgets. - if(window_type == MAIN_WINDOW) - { + if( window_type == MAIN_WINDOW ) { + flash_enabled = 0; resize_events = 0; + delete pixmap; pixmap = new BC_Pixmap(this, w, h); - clear_box(0, 0, w, h); } // Propagate to subwindows - for(int i = 0; i < subwindows->total; i++) - { + for(int i = 0; i < subwindows->total; i++) { subwindows->values[i]->dispatch_resize_event(w, h); } // Propagate to user resize_event(w, h); - if(window_type == MAIN_WINDOW) - { + if( window_type == MAIN_WINDOW ) { this->w = w; this->h = h; + dispatch_flash(); + flush(); } return 0; } +int BC_WindowBase::dispatch_flash() +{ + flash_enabled = 1; + for(int i = 0; i < subwindows->total; i++) + subwindows->values[i]->dispatch_flash(); + return flash(0); +} + int BC_WindowBase::dispatch_translation_event() { translation_events = 0; @@ -1915,11 +1931,17 @@ int BC_WindowBase::unset_all_repeaters() // return top_level->next_repeat_id++; // } +XEvent *BC_WindowBase::new_xevent() +{ + XEvent *event = new XEvent; + memset(event, 0, sizeof(*event)); + return event; +} #ifndef SINGLE_THREAD int BC_WindowBase::arm_repeat(int64_t duration) { - XEvent *event = new XEvent; + XEvent *event = new_xevent(); XClientMessageEvent *ptr = (XClientMessageEvent*)event; ptr->type = ClientMessage; ptr->message_type = RepeaterXAtom; @@ -1939,7 +1961,8 @@ int BC_WindowBase::recieve_custom_xatoms(xatom_event *event) int BC_WindowBase::send_custom_xatom(xatom_event *event) { - XEvent *myevent = new XEvent; +#ifndef SINGLE_THREAD + XEvent *myevent = new_xevent(); XClientMessageEvent *ptr = (XClientMessageEvent*)myevent; ptr->type = ClientMessage; ptr->message_type = event->message_type; @@ -1951,6 +1974,7 @@ int BC_WindowBase::send_custom_xatom(xatom_event *event) ptr->data.l[4] = event->data.l[4]; put_event(myevent); +#endif return 0; } @@ -1963,12 +1987,9 @@ Atom BC_WindowBase::create_xatom(const char *atom_name) int BC_WindowBase::get_atoms() { - SetDoneXAtom = create_xatom("BC_REPEAT_EVENT"); - RepeaterXAtom = create_xatom("BC_CLOSE_EVENT"); - DelWinXAtom = create_xatom("WM_DELETE_WINDOW"); - ProtoXAtom = create_xatom("WM_PROTOCOLS"); SetDoneXAtom = XInternAtom(display, "BC_REPEAT_EVENT", False); RepeaterXAtom = XInternAtom(display, "BC_CLOSE_EVENT", False); + DestroyAtom = XInternAtom(display, "BC_DESTROY_WINDOW", False); DelWinXAtom = XInternAtom(display, "WM_DELETE_WINDOW", False); if( (ProtoXAtom = XInternAtom(display, "WM_PROTOCOLS", False)) != 0 ) XChangeProperty(display, win, ProtoXAtom, XA_ATOM, 32, @@ -2796,7 +2817,7 @@ int BC_WindowBase::get_single_text_width(int font, const char *text, int length) if(get_resources()->use_fontset && top_level->get_fontset(font)) return XmbTextEscapement(top_level->get_fontset(font), text, length); else - if(get_font_struct(font)) + if(get_font_struct(font)) return XTextWidth(get_font_struct(font), text, length); else { @@ -2979,119 +3000,76 @@ void BC_WindowBase::init_wait() int BC_WindowBase::accel_available(int color_model, int lock_it) { - if(window_type != MAIN_WINDOW) + if( window_type != MAIN_WINDOW ) return top_level->accel_available(color_model, lock_it); + if( lock_it ) + lock_window("BC_WindowBase::accel_available"); - int result = 0; - - if(lock_it) lock_window("BC_WindowBase::accel_available"); - switch(color_model) - { - case BC_YUV420P: - result = grab_port_id(this, color_model); - if(result >= 0) - { - xvideo_port_id = result; - result = 1; - } - else - result = 0; - break; - - case BC_YUV422P: - result = 0; - break; + switch(color_model) { + case BC_YUV420P: + grab_port_id(color_model); + break; - case BC_YUV422: -//printf("BC_WindowBase::accel_available 1\n"); - result = grab_port_id(this, color_model); -//printf("BC_WindowBase::accel_available 2 %d\n", result); - if(result >= 0) - { - xvideo_port_id = result; - result = 1; - } - else - result = 0; -//printf("BC_WindowBase::accel_available 3 %d\n", xvideo_port_id); - break; + case BC_YUV422: + grab_port_id(color_model); + break; - default: - result = 0; - break; + default: + break; } - if(lock_it) unlock_window(); -//printf("BC_WindowBase::accel_available %d %d\n", color_model, result); - return result; + if( lock_it ) + unlock_window(); +//printf("BC_WindowBase::accel_available %d %d\n", color_model, xvideo_port_id); + return xvideo_port_id >= 0 ? 1 : 0; } -int BC_WindowBase::grab_port_id(BC_WindowBase *window, int color_model) +int BC_WindowBase::grab_port_id(int color_model) { - int numFormats, i, j, k; - unsigned int ver, rev, numAdapt, reqBase, eventBase, errorBase; - XvAdaptorInfo *info; - XvImageFormatValues *formats; - int x_color_model; - - if(!get_resources()->use_xvideo) return -1; - -// Translate from color_model to X color model - x_color_model = BC_CModels::bc_to_x(color_model); - -// Only local server is fast enough. - if(!resources.use_shm) return -1; + if( !get_resources()->use_xvideo || // disabled + !get_resources()->use_shm ) // Only local server is fast enough. + return -1; + if( xvideo_port_id >= 0 ) + return xvideo_port_id; -// XV extension is available - if(Success != XvQueryExtension(window->display, &ver, &rev, - &reqBase, &eventBase, &errorBase)) { + unsigned int ver, rev, reqBase, eventBase, errorBase; + if( Success != XvQueryExtension(display, // XV extension is available + &ver, &rev, &reqBase, &eventBase, &errorBase) ) return -1; - } // XV adaptors are available - XvQueryAdaptors(window->display, - DefaultRootWindow(window->display), - &numAdapt, &info); - - if(!numAdapt) { + unsigned int numAdapt = 0; + XvAdaptorInfo *info = 0; + XvQueryAdaptors(display, DefaultRootWindow(display), &numAdapt, &info); + if( !numAdapt ) return -1; - } + +// Translate from color_model to X color model + int x_color_model = BC_CModels::bc_to_x(color_model); // Get adaptor with desired color model - for(i = 0; i < (int)numAdapt && xvideo_port_id == -1; i++) { -/* adaptor supports XvImages */ - if(info[i].type & XvImageMask) - { - formats = XvListImageFormats(window->display, - info[i].base_id, - &numFormats); -// for(j = 0; j < numFormats; j++) -// printf("%08x\n", formats[j].id); - - int numPorts = info[i].num_ports; - for(j = 0; j < (int)numFormats && xvideo_port_id < 0; j++) - { -/* this adaptor supports the desired format */ - if(formats[j].id == x_color_model) - { -/* Try to grab a port */ - for(k = 0; k < numPorts; k++) - { -/* Got a port */ - if(Success == XvGrabPort(top_level->display, - info[i].base_id + k, - CurrentTime)) - { + for( int i = 0; i < (int)numAdapt && xvideo_port_id == -1; i++) { + if( !(info[i].type & XvImageMask) || !info[i].num_ports ) continue; +// adaptor supports XvImages + int numFormats = 0, numPorts = info[i].num_ports; + XvImageFormatValues *formats = + XvListImageFormats(display, info[i].base_id, &numFormats); + if( !formats ) continue; + + for( int j=0; jdisplay, + info[i].base_id+k, CurrentTime) ) { //printf("BC_WindowBase::grab_port_id %llx\n", info[i].base_id); - xvideo_port_id = info[i].base_id + k; - break; - } - } + xvideo_port_id = info[i].base_id + k; + break; } } - if(formats) XFree(formats); } + XFree(formats); } XvFreeAdaptorInfo(info); @@ -3179,6 +3157,7 @@ BC_WindowBase* BC_WindowBase::add_tool(BC_WindowBase *subwindow) int BC_WindowBase::flash(int x, int y, int w, int h, int flush) { + if( !top_level->flash_enabled ) return 0; //printf("BC_WindowBase::flash %d %d %d %d %d\n", __LINE__, w, h, this->w, this->h); set_opaque(); XSetWindowBackgroundPixmap(top_level->display, win, pixmap->opaque_pixmap); @@ -3305,20 +3284,20 @@ void BC_WindowBase::set_done(int return_value) #else // SINGLE_THREAD init_wait(); if( !event_thread ) return; - XEvent *event = new XEvent; + XEvent *event = new_xevent(); XClientMessageEvent *ptr = (XClientMessageEvent*)event; event->type = ClientMessage; ptr->message_type = SetDoneXAtom; ptr->format = 32; this->return_value = return_value; -// May lock up here because XSendEvent doesn't work too well +// May lock up here because XSendEvent doesn't work too well // asynchronous with XNextEvent. -// This causes BC_WindowEvents to forward a copy of the event to run_window where +// This causes BC_WindowEvents to forward a copy of the event to run_window where // it is deleted. // Deletion of event_thread is done at the end of BC_WindowBase::run_window() - by calling the destructor put_event(event); - } #endif + } } void BC_WindowBase::close(int return_value) @@ -3779,13 +3758,15 @@ int BC_WindowBase::get_cursor_y() int BC_WindowBase::dump_windows() { - printf("\tBC_WindowBase::dump_windows window=%p win=%p\n", - this, (void*)this->win); + printf("\tBC_WindowBase::dump_windows window=%p win=%p '%s', %dx%d+%d+%d %s\n", + this, (void*)this->win, title, w,h,x,y, typeid(*this).name()); for(int i = 0; i < subwindows->size(); i++) subwindows->get(i)->dump_windows(); - for(int i = 0; i < popups.size(); i++) - printf("\tBC_WindowBase::dump_windows popup=%p win=%p\n", - popups.get(i), (void*)popups.get(i)->win); + for(int i = 0; i < popups.size(); i++) { + BC_WindowBase *p = popups[i]; + printf("\tBC_WindowBase::dump_windows popup=%p win=%p '%s', %dx%d+%d+%d %s\n", + p, (void*)p->win, p->title, p->w,p->h,p->x,p->y, typeid(*p).name()); + } return 0; } @@ -3970,6 +3951,7 @@ int BC_WindowBase::reposition_window(int x, int y, int w, int h) { delete pixmap; pixmap = new BC_Pixmap(this, this->w, this->h); + clear_box(0,0, this->w, this->h); // Propagate to menubar for(int i = 0; i < subwindows->total; i++) { @@ -4020,26 +4002,17 @@ void BC_WindowBase::set_background(VFrame *bitmap) { if(bg_pixmap && !shared_bg_pixmap) delete bg_pixmap; - bg_pixmap = new BC_Pixmap(this, - bitmap, - PIXMAP_OPAQUE); + bg_pixmap = new BC_Pixmap(this, bitmap, PIXMAP_OPAQUE); shared_bg_pixmap = 0; draw_background(0, 0, w, h); } void BC_WindowBase::put_title(const char *text) { - if( BC_Resources::locale_utf8 ) { - char *bp=this->title, *ep = bp+sizeof(this->title)-1; - for( const char *cp=text; *cp!=0 && bptitle, text); + char *cp = this->title, *ep = cp+sizeof(this->title)-1; + for( const unsigned char *bp = (const unsigned char *)text; *bp && cp= ' ' ? *bp : ' '; + *cp = 0; } void BC_WindowBase::set_title(const char *text) @@ -4096,10 +4069,7 @@ int BC_WindowBase::get_toggle_drag() int BC_WindowBase::set_icon(VFrame *data) { if(icon_pixmap) delete icon_pixmap; - icon_pixmap = new BC_Pixmap(top_level, - data, - PIXMAP_ALPHA, - 1); + icon_pixmap = new BC_Pixmap(top_level, data, PIXMAP_ALPHA, 1); if(icon_window) delete icon_window; icon_window = new BC_Popup(this, @@ -4359,6 +4329,20 @@ void BC_WindowBase::put_event(XEvent *event) event_condition->unlock(); } +void BC_WindowBase::dequeue_events(Window win) +{ + event_lock->lock("BC_WindowBase::dequeue_events"); + + int out = 0, total = common_events.size(); + for( int in=0; inxany.window == win ) continue; + common_events[out++] = common_events[in]; + } + common_events.total = out; + + event_lock->unlock(); +} + #endif // SINGLE_THREAD int BC_WindowBase::get_id() @@ -4376,3 +4360,15 @@ BC_Pixmap *BC_WindowBase::create_pixmap(VFrame *vframe) } +void BC_WindowBase::flicker(int n, int ms) +{ + int color = get_bg_color(); + for( int i=2*n; --i>=0; ) { + set_inverse(); set_bg_color(WHITE); + clear_box(0,0, w,h); flash(1); + sync_display(); Timer::delay(ms); + } + set_bg_color(color); + set_opaque(); +} +