From f03f546b88125310c184ec2d7db488d93b2fb454 Mon Sep 17 00:00:00 2001 From: Andraz Tori Date: Fri, 13 Oct 2006 10:06:42 +0000 Subject: [PATCH] r917: Implement Asynchronous updates for awinodw, thus removing the reason for the most frequent cinelerra freezes i enjoyed --- cinelerra/assetedit.C | 4 +--- cinelerra/awindow.C | 2 +- cinelerra/awindowgui.C | 32 +++++++++++++++++++++++++++++++- cinelerra/awindowgui.h | 13 ++++++++++++- cinelerra/clipedit.C | 5 +---- cinelerra/labeledit.C | 2 +- cinelerra/mwindow.C | 10 ++-------- cinelerra/mwindowedit.C | 11 +++-------- guicast/bcwindowbase.C | 48 ++++++++++++++++++++++++++++++++++++++++++++---- guicast/bcwindowbase.h | 29 +++++++++++++++++++++++++++++ 10 files changed, 125 insertions(+), 31 deletions(-) diff --git a/cinelerra/assetedit.C b/cinelerra/assetedit.C index 4a1f1c70..25d5baf3 100644 --- a/cinelerra/assetedit.C +++ b/cinelerra/assetedit.C @@ -108,9 +108,7 @@ void AssetEdit::run() mwindow->gui->unlock_window(); - mwindow->awindow->gui->lock_window(); - mwindow->awindow->gui->update_assets(); - mwindow->awindow->gui->unlock_window(); + mwindow->awindow->gui->async_update_assets(); mwindow->restart_brender(); mwindow->sync_parameters(CHANGE_ALL); diff --git a/cinelerra/awindow.C b/cinelerra/awindow.C index 393e20b4..4f9b5723 100644 --- a/cinelerra/awindow.C +++ b/cinelerra/awindow.C @@ -23,7 +23,7 @@ int AWindow::create_objects() { gui = new AWindowGUI(mwindow, this); gui->create_objects(); - gui->update_assets(); + gui->async_update_assets(); asset_remove = new AssetRemoveThread(mwindow); asset_edit = new AssetEdit(mwindow); clip_edit = new ClipEdit(mwindow, this, 0); diff --git a/cinelerra/awindowgui.C b/cinelerra/awindowgui.C index 2c6a3c81..db1ca4ba 100644 --- a/cinelerra/awindowgui.C +++ b/cinelerra/awindowgui.C @@ -584,6 +584,36 @@ int AWindowGUI::keypress_event() return 0; } + + +int AWindowGUI::create_custom_xatoms() +{ + UpdateAssetsXAtom = create_xatom("CWINDOWGUI_UPDATE_ASSETS"); + return 0; +} +int AWindowGUI::recieve_custom_xatoms(xatom_event *event) +{ + if (event->message_type == UpdateAssetsXAtom) + { + update_assets(); + return 1; + } else + return 0; +} + +void AWindowGUI::async_update_assets() +{ + xatom_event event; + event.message_type = UpdateAssetsXAtom; + send_custom_xatom(&event); +} + + + + + + + void AWindowGUI::update_folder_list() { //printf("AWindowGUI::update_folder_list 1\n"); @@ -1139,7 +1169,7 @@ int AWindowFolders::selection_changed() strcpy(mwindow->edl->session->current_folder, picon->get_text()); //printf("AWindowFolders::selection_changed 1\n"); gui->asset_list->draw_background(); - gui->update_assets(); + gui->async_update_assets(); } return 1; } diff --git a/cinelerra/awindowgui.h b/cinelerra/awindowgui.h index 1527c400..bb9d2568 100644 --- a/cinelerra/awindowgui.h +++ b/cinelerra/awindowgui.h @@ -79,7 +79,7 @@ public: int translation_event(); int close_event(); int keypress_event(); - void update_assets(); + void async_update_assets(); // Sends update asset event void sort_assets(); void reposition_objects(); int current_folder_number(); @@ -145,10 +145,21 @@ public: VFrame *temp_picon; int allow_iconlisting; + +// Create custom atoms to be used for async messages between windows + virtual int create_custom_xatoms(); +// Function to overload to recieve customly defined atoms + virtual int recieve_custom_xatoms(xatom_event *event); + + + private: void update_folder_list(); void update_asset_list(); void filter_displayed_assets(); + Atom UpdateAssetsXAtom; + void update_assets(); + }; class AWindowAssets : public BC_ListBox diff --git a/cinelerra/clipedit.C b/cinelerra/clipedit.C index 7731382e..807a7a02 100644 --- a/cinelerra/clipedit.C +++ b/cinelerra/clipedit.C @@ -88,10 +88,7 @@ void ClipEdit::run() // mwindow->vwindow->gui->update_sources(mwindow->vwindow->gui->source->get_text()); - mwindow->awindow->gui->lock_window(); - mwindow->awindow->gui->update_assets(); - mwindow->awindow->gui->flush(); - mwindow->awindow->gui->unlock_window(); + mwindow->awindow->gui->async_update_assets(); // Change VWindow to it if vwindow was called // But this doesn't let you easily create a lot of clips. diff --git a/cinelerra/labeledit.C b/cinelerra/labeledit.C index ed4d4688..43474537 100644 --- a/cinelerra/labeledit.C +++ b/cinelerra/labeledit.C @@ -46,7 +46,7 @@ void LabelEdit::run() window->create_objects(); int result = window->run_window(); delete window; - if (awindow) awindow->gui->update_assets(); + if (awindow) awindow->gui->async_update_assets(); } } diff --git a/cinelerra/mwindow.C b/cinelerra/mwindow.C index 6a6a8f74..50d4f3e2 100644 --- a/cinelerra/mwindow.C +++ b/cinelerra/mwindow.C @@ -1855,10 +1855,7 @@ void MWindow::update_project(int load_mode) edl, 1); - awindow->gui->lock_window("MWindow::update_project"); - awindow->gui->update_assets(); - awindow->gui->flush(); - awindow->gui->unlock_window(); + awindow->gui->async_update_assets(); gui->flush(); } @@ -2004,10 +2001,7 @@ void MWindow::remove_assets_from_project(int push_undo) 0); gui->unlock_window(); - awindow->gui->lock_window("MWindow::remove_assets_from_project 4"); - awindow->gui->update_assets(); - awindow->gui->flush(); - awindow->gui->unlock_window(); + awindow->gui->async_update_assets(); // Removes from playback here sync_parameters(CHANGE_ALL); diff --git a/cinelerra/mwindowedit.C b/cinelerra/mwindowedit.C index 41255627..e81c63ab 100644 --- a/cinelerra/mwindowedit.C +++ b/cinelerra/mwindowedit.C @@ -1087,7 +1087,7 @@ void MWindow::paste() restart_brender(); update_plugin_guis(); gui->update(1, 2, 1, 1, 0, 1, 0); - awindow->gui->update_assets(); + awindow->gui->async_update_assets(); sync_parameters(CHANGE_EDL); } @@ -2137,10 +2137,7 @@ void MWindow::undo_entry(BC_WindowBase *calling_window_gui) vwindow->gui->unlock_window(); - awindow->gui->lock_window("MWindow::undo_entry 3"); - awindow->gui->update_assets(); - awindow->gui->flush(); - awindow->gui->unlock_window(); + awindow->gui->async_update_assets(); cwindow->playback_engine->que->send_command(CURRENT_FRAME, CHANGE_ALL, edl, @@ -2153,9 +2150,7 @@ void MWindow::new_folder(char *new_folder) { edl->new_folder(new_folder); undo->update_undo(_("new folder"), LOAD_ALL); - awindow->gui->lock_window("MWindow::new_folder"); - awindow->gui->update_assets(); - awindow->gui->unlock_window(); + awindow->gui->async_update_assets(); } void MWindow::delete_folder(char *folder) diff --git a/guicast/bcwindowbase.C b/guicast/bcwindowbase.C index ee7a1522..af987f6a 100644 --- a/guicast/bcwindowbase.C +++ b/guicast/bcwindowbase.C @@ -723,6 +723,9 @@ int BC_WindowBase::dispatch_event() if(ptr->message_type == SetDoneXAtom) { done = 1; + } else + { // We currently use X marshalling for xatom events, we can switch to something else later + recieve_custom_xatoms((xatom_event *)ptr); } break; @@ -1470,6 +1473,7 @@ int BC_WindowBase::unset_all_repeaters() // return top_level->next_repeat_id++; // } + int BC_WindowBase::arm_repeat(int64_t duration) { XEvent *event = new XEvent; @@ -1490,16 +1494,52 @@ int BC_WindowBase::arm_repeat(int64_t duration) return 0; } +int BC_WindowBase::create_custom_xatoms() +{ + return 0; +} +int BC_WindowBase::recieve_custom_xatoms(xatom_event *event) +{ + return 0; +} + +int BC_WindowBase::send_custom_xatom(xatom_event *event) +{ + XEvent *myevent = new XEvent; + XClientMessageEvent *ptr = (XClientMessageEvent*)myevent; + ptr->type = ClientMessage; + ptr->message_type = event->message_type; + ptr->format = event->format; + ptr->data.l[0] = event->data.l[0]; + ptr->data.l[1] = event->data.l[1]; + ptr->data.l[2] = event->data.l[2]; + ptr->data.l[3] = event->data.l[3]; + ptr->data.l[4] = event->data.l[4]; + + put_event(myevent); + return 0; +} + + + +Atom BC_WindowBase::create_xatom(char *atom_name) +{ + return XInternAtom(display, atom_name, False); +} + int BC_WindowBase::get_atoms() { - SetDoneXAtom = XInternAtom(display, "BC_REPEAT_EVENT", False); - RepeaterXAtom = XInternAtom(display, "BC_CLOSE_EVENT", False); - DelWinXAtom = XInternAtom(display, "WM_DELETE_WINDOW", False); - if(ProtoXAtom = XInternAtom(display, "WM_PROTOCOLS", False)) + SetDoneXAtom = create_xatom("BC_REPEAT_EVENT"); + RepeaterXAtom = create_xatom("BC_CLOSE_EVENT"); + DelWinXAtom = create_xatom("WM_DELETE_WINDOW"); + if(ProtoXAtom = create_xatom("WM_PROTOCOLS")) XChangeProperty(display, win, ProtoXAtom, XA_ATOM, 32, PropModeReplace, (unsigned char *)&DelWinXAtom, True); + create_custom_xatoms(); return 0; + } + void BC_WindowBase::init_cursors() { arrow_cursor = XCreateFontCursor(display, XC_top_left_arrow); diff --git a/guicast/bcwindowbase.h b/guicast/bcwindowbase.h index 42668b40..9102a8e1 100644 --- a/guicast/bcwindowbase.h +++ b/guicast/bcwindowbase.h @@ -82,6 +82,25 @@ //typedef void* GLXContext; #endif + +// Struct for async event marshalling, the same as XClientMessageEvent currently, but can be changed if we change toolkit ever +// it is defined here so we don't use X headers in /cinelerra +typedef struct { + int type; /* ClientMessage */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; + Atom message_type; + int format; + union { + char b[20]; + short s[10]; + long l[5]; + } data; +} xatom_event; + + class BC_ResizeCall { public: @@ -540,6 +559,11 @@ private: int get_screen(); virtual int initialize(); int get_atoms(); +// Create custom atoms to be used for async messages between windows + virtual int create_custom_xatoms(); +// Function to overload to recieve customly defined atoms + virtual int recieve_custom_xatoms(xatom_event *event); + void init_cursors(); int init_colors(); int init_window_shape(); @@ -807,6 +831,11 @@ private: Timer *cursor_timer; // unique ID of window. int id; + +protected: + Atom create_xatom(char *atom_name); + int send_custom_xatom(xatom_event *event); + }; -- 2.11.4.GIT