summaryrefslogtreecommitdiff
path: root/libs/fst/vstwin.c
diff options
context:
space:
mode:
authorCarl Hetherington <carl@carlh.net>2010-12-30 00:53:37 +0000
committerCarl Hetherington <carl@carlh.net>2010-12-30 00:53:37 +0000
commitb00bb4d5ff32c78dea212bc2ad71a1f87db9d2fc (patch)
treee7a4e90ec3d937ca45dc9c1c24029b83bfe53338 /libs/fst/vstwin.c
parent72190954c49dbe5874115132e0497cf5b8d6e633 (diff)
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
Diffstat (limited to 'libs/fst/vstwin.c')
-rw-r--r--libs/fst/vstwin.c181
1 files changed, 102 insertions, 79 deletions
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;