const char magic[] = "VSTFX Plugin State v002";
-int gui_thread_id = 0;
-static int gui_quit = 0;
+static volatile int gui_quit = 0;
/*This will be our connection to X*/
-Display* LXVST_XDisplay = NULL;
+static Display* LXVST_XDisplay = NULL;
/*The thread handle for the GUI event loop*/
-pthread_t LXVST_gui_event_thread;
+static pthread_t LXVST_gui_event_thread;
/*Util functions to get the value of a property attached to an XWindow*/
-bool LXVST_xerror;
+static bool LXVST_xerror;
int TempErrorHandler(Display *display, XErrorEvent *e)
{
vstfx->eventProc((void*)event);
}
-static void
-maybe_set_program (VSTState* vstfx)
-{
- if (vstfx->want_program != -1) {
- if (vstfx->vst_version >= 2) {
- vstfx->plugin->dispatcher (vstfx->plugin, 67 /* effBeginSetProgram */, 0, 0, NULL, 0);
- }
-
- vstfx->plugin->dispatcher (vstfx->plugin, effSetProgram, 0, vstfx->want_program, NULL, 0);
-
- if (vstfx->vst_version >= 2) {
- vstfx->plugin->dispatcher (vstfx->plugin, 68 /* effEndSetProgram */, 0, 0, NULL, 0);
- }
-
- vstfx->want_program = -1;
- }
-
- if (vstfx->want_chunk == 1) {
- vstfx->plugin->dispatcher (vstfx->plugin, 24 /* effSetChunk */, 1, vstfx->wanted_chunk_size, vstfx->wanted_chunk, 0);
- vstfx->want_chunk = 0;
- }
-}
-
/** This is the main gui event loop for the plugin, we also need to pass
any Xevents to all the UI callbacks plugins 'may' have registered on their
windows, that is if they don't manage their own UIs **/
}
}
- maybe_set_program (vstfx);
+ vststate_maybe_set_program (vstfx);
vstfx->want_program = -1;
vstfx->want_chunk = 0;
clock1 = g_get_monotonic_time();
}
- if (may_sleep && elapsed_time_ms + 1 < LXVST_sched_timer_interval) {
+ if (!gui_quit && may_sleep && elapsed_time_ms + 1 < LXVST_sched_timer_interval) {
Glib::usleep(1000 * (LXVST_sched_timer_interval - elapsed_time_ms - 1));
}
}
int vstfx_init (void* ptr)
{
+ assert (gui_quit == 0);
+ pthread_mutex_init (&plugin_mutex, NULL);
int thread_create_result;
/*Create the thread - use default attrs for now, don't think we need anything special*/
- thread_create_result = pthread_create(&LXVST_gui_event_thread, NULL, gui_event_loop, NULL);
+ thread_create_result = pthread_create(&LXVST_gui_event_thread, &thread_attributes, gui_event_loop, NULL);
if(thread_create_result!=0)
{
vstfx_error ("** ERROR ** VSTFX: Failed starting GUI event thread");
XCloseDisplay(LXVST_XDisplay);
+ gui_quit = 1;
return -1;
}
void vstfx_exit()
{
+ if (gui_quit) {
+ return;
+ }
gui_quit = 1;
/*We need to pthread_join the gui_thread here so
we know when it has stopped*/
+ // BEWARE: some Plugin GUIs can crash if the thread local storage is free()d
+ // after the shared library containing the destructor is already dl-closed.
+ // (e.g u-he LXVST GUI, crash in __nptl_deallocate_tsd) :(
pthread_join(LXVST_gui_event_thread, NULL);
+ pthread_mutex_destroy (&plugin_mutex);
}
/*Adds a new plugin (VSTFX) instance to the linked list*/
return 0;
Window parent_window;
- struct ERect* er;
+ struct ERect* er = NULL;
int x_size = 1;
int y_size = 1;
vstfx->plugin->dispatcher (vstfx->plugin, effEditGetRect, 0, 0, &er, 0 );
- x_size = er->right - er->left;
- y_size = er->bottom - er->top;
+ if (er) {
+ // Don't crash is plugin does not implement effEditGetRect
+ // it'll result in 1x1 px window but that's not our problem :)
+ x_size = er->right - er->left;
+ y_size = er->bottom - er->top;
+ }
- vstfx->width = x_size;
- vstfx->height = y_size;
+ vstfx->width = x_size;
+ vstfx->height = y_size;
XResizeWindow(LXVST_XDisplay, parent_window, x_size, y_size);