From b00bb4d5ff32c78dea212bc2ad71a1f87db9d2fc Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 30 Dec 2010 00:53:37 +0000 Subject: Gruesome-in-the-extreme VST hacks to attempt to allow presets to be loaded without an editor window. You may need to clean your Ethernet cable with soapy water after fetching this commit (wireless users --- open the window). git-svn-id: svn://localhost/ardour2/branches/3.0@8378 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/fst/fst.h | 2 + libs/fst/vstwin.c | 181 ++++++++++++++++++++++++++++++------------------------ 2 files changed, 104 insertions(+), 79 deletions(-) diff --git a/libs/fst/fst.h b/libs/fst/fst.h index 2e4236fe4d..6cf057d2fa 100644 --- a/libs/fst/fst.h +++ b/libs/fst/fst.h @@ -90,7 +90,9 @@ struct _FST int wantIdle; int destroy; int vst_version; + int has_editor; + int program_set_without_editor; int want_program; int want_chunk; unsigned char *wanted_chunk; diff --git a/libs/fst/vstwin.c b/libs/fst/vstwin.c index b9f372d461..5016fa12bf 100644 --- a/libs/fst/vstwin.c +++ b/libs/fst/vstwin.c @@ -24,7 +24,10 @@ struct ERect{ }; static pthread_mutex_t plugin_mutex; + +/** Head of linked list of all FSTs */ static FST* fst_first = NULL; + const char magic[] = "FST Plugin State v002"; DWORD gui_thread_id = 0; @@ -76,6 +79,8 @@ fst_new () fst->want_chunk = 0; fst->current_program = -1; fst->n_pending_keys = 0; + fst->has_editor = 0; + fst->program_set_without_editor = 0; return fst; } @@ -86,6 +91,30 @@ fst_handle_new () return fst; } +void +maybe_set_program (FST* fst) +{ + if (fst->want_program != -1) { + if (fst->vst_version >= 2) { + fst->plugin->dispatcher (fst->plugin, 67 /* effBeginSetProgram */, 0, 0, NULL, 0); + } + + fst->plugin->dispatcher (fst->plugin, effSetProgram, 0, fst->want_program, NULL, 0); + + if (fst->vst_version >= 2) { + fst->plugin->dispatcher (fst->plugin, 68 /* effEndSetProgram */, 0, 0, NULL, 0); + } + /* did it work? */ + fst->current_program = fst->plugin->dispatcher (fst->plugin, 3, /* effGetProgram */ 0, 0, NULL, 0); + fst->want_program = -1; + } + + if (fst->want_chunk == 1) { + fst->plugin->dispatcher (fst->plugin, 24 /* effSetChunk */, 1, fst->wanted_chunk_size, fst->wanted_chunk, 0); + fst->want_chunk = 0; + } +} + DWORD WINAPI gui_event_loop (LPVOID param) { MSG msg; @@ -130,18 +159,24 @@ DWORD WINAPI gui_event_loop (LPVOID param) TranslateMessage( &msg ); DispatchMessageA (&msg); - /* handle window creation requests, destroy requests, + if (msg.message != WM_TIMER) { + continue; + } + + pthread_mutex_lock (&plugin_mutex); + + /* Do things that are appropriate for plugins which have open editor windows: + handle window creation requests, destroy requests, and run idle callbacks */ - - if (msg.message == WM_TIMER) { - pthread_mutex_lock (&plugin_mutex); - + again: - for (fst = fst_first; fst; fst = fst->next) { + for (fst = fst_first; fst; fst = fst->next) { + + pthread_mutex_lock (&fst->lock); + + if (fst->has_editor == 1) { - pthread_mutex_lock (&fst->lock); - if (fst->destroy) { fprintf (stderr, "%s scheduled for destroy\n", fst->handle->name); if (fst->window) { @@ -168,28 +203,8 @@ again: /* condition/unlock: it was signalled & unlocked in fst_create_editor() */ } } - - if (fst->want_program != -1 ) { - if (fst->vst_version >= 2) { - fst->plugin->dispatcher (fst->plugin, 67 /* effBeginSetProgram */, 0, 0, NULL, 0); - } - - fst->plugin->dispatcher (fst->plugin, effSetProgram, 0, fst->want_program, NULL, 0); - - if (fst->vst_version >= 2) { - fst->plugin->dispatcher (fst->plugin, 68 /* effEndSetProgram */, 0, 0, NULL, 0); - } - /* did it work? */ - fst->current_program = fst->plugin->dispatcher (fst->plugin, 3, /* effGetProgram */ 0, 0, NULL, 0); - fst->want_program = -1; - } - - if (fst->want_chunk == 1) { - fst->plugin->dispatcher (fst->plugin, 24 /* effSetChunk */, 1, fst->wanted_chunk_size, fst->wanted_chunk, 0); - fst->want_chunk = 0; - } - if(fst->dispatcher_wantcall) { + if (fst->dispatcher_wantcall) { fst->dispatcher_retval = fst->plugin->dispatcher( fst->plugin, fst->dispatcher_opcode, fst->dispatcher_index, @@ -201,51 +216,56 @@ again: } fst->plugin->dispatcher (fst->plugin, effEditIdle, 0, 0, NULL, 0); - - if( fst->wantIdle ) { + + if (fst->wantIdle) { fst->plugin->dispatcher (fst->plugin, 53, 0, 0, NULL, 0); } - - pthread_mutex_unlock (&fst->lock); - } - pthread_mutex_unlock (&plugin_mutex); - - } - - pthread_mutex_lock (&plugin_mutex); + /* Dispatch messages to send keypresses to the plugin */ + + for (int i = 0; i < fst->n_pending_keys; ++i) { + /* I'm not quite sure what is going on here; it seems + `special' keys must be delivered with WM_KEYDOWN, + but that alphanumerics etc. must use WM_CHAR or + they will be ignored. Ours is not to reason why ... + */ + if (fst->pending_keys[i].special != 0) { + msg.message = WM_KEYDOWN; + msg.wParam = fst->pending_keys[i].special; + } else { + msg.message = WM_CHAR; + msg.wParam = fst->pending_keys[i].character; + } + msg.hwnd = GetFocus (); + msg.lParam = 0; + DispatchMessageA (&msg); + } + + fst->n_pending_keys = 0; - for (fst = fst_first; fst; fst = fst->next) { - - pthread_mutex_lock (&fst->lock); + /* See comment for maybe_set_program call below */ + maybe_set_program (fst); + fst->want_program = -1; + fst->want_chunk = 0; + } - /* Dispatch messages to send keypresses to the plugin */ - - for (int i = 0; i < fst->n_pending_keys; ++i) { - /* I'm not quite sure what is going on here; it seems - `special' keys must be delivered with WM_KEYDOWN, - but that alphanumerics etc. must use WM_CHAR or - they will be ignored. Ours is not to reason why ... - */ - if (fst->pending_keys[i].special != 0) { - msg.message = WM_KEYDOWN; - msg.wParam = fst->pending_keys[i].special; - } else { - msg.message = WM_CHAR; - msg.wParam = fst->pending_keys[i].character; - } - msg.hwnd = GetFocus (); - msg.lParam = 0; - DispatchMessageA (&msg); + /* If we don't have an editor window yet, we still need to + * set up the program, otherwise when we load a plugin without + * opening its window it will sound wrong. However, it seems + * that if you don't also load the program after opening the GUI, + * the GUI does not reflect the program properly. So we'll not + * mark that we've done this (ie we won't set want_program to -1) + * and so it will be done again if and when the GUI arrives. + */ + if (fst->program_set_without_editor == 0) { + maybe_set_program (fst); + fst->program_set_without_editor = 1; } - fst->n_pending_keys = 0; pthread_mutex_unlock (&fst->lock); - } pthread_mutex_unlock (&plugin_mutex); - } return 0; @@ -307,26 +327,15 @@ fst_exit () int fst_run_editor (FST* fst) { - pthread_mutex_lock (&plugin_mutex); - - if (fst_first == NULL) { - fst_first = fst; - } else { - FST* p = fst_first; - while (p->next) { - p = p->next; - } - p->next = fst; - } - - pthread_mutex_unlock (&plugin_mutex); - /* wait for the plugin editor window to be created (or not) */ pthread_mutex_lock (&fst->lock); + + fst->has_editor = 1; + if (!fst->window) { pthread_cond_wait (&fst->window_status_change, &fst->lock); - } + } pthread_mutex_unlock (&fst->lock); if (!fst->window) { @@ -438,7 +447,7 @@ fst_destroy_editor (FST* fst) //} pthread_cond_wait (&fst->window_status_change, &fst->lock); fprintf (stderr, "%s editor destroyed\n", fst->handle->name); - + fst->has_editor = 0; } pthread_mutex_unlock (&fst->lock); } @@ -596,6 +605,20 @@ fst_instantiate (FSTHandle* fhandle, audioMasterCallback amc, void* userptr) { FST* fst = fst_new (); + pthread_mutex_lock (&plugin_mutex); + + if (fst_first == NULL) { + fst_first = fst; + } else { + FST* p = fst_first; + while (p->next) { + p = p->next; + } + p->next = fst; + } + + pthread_mutex_unlock (&plugin_mutex); + if( fhandle == NULL ) { fst_error( "the handle was NULL\n" ); return NULL; -- cgit v1.2.3