switch to using jack_set_thread_creator() and dont mess with winaudio thread
[fst.git] / vstwin.c
blob5e12d36ae12e7be7530b5985afb7997753438e02
1 #include <stdio.h>
2 #include <libgen.h>
3 #include <windows.h>
4 #include <winnt.h>
5 #include <wine/exception.h>
6 #include <pthread.h>
7 #include <signal.h>
8 #include <glib.h>
10 #include "fst.h"
12 #include <X11/X.h>
13 #include <X11/Xlib.h>
15 struct ERect{
16 short top;
17 short left;
18 short bottom;
19 short right;
22 static pthread_mutex_t plugin_mutex;
23 static FST* fst_first = NULL;
24 const char magic[] = "FST Plugin State v002";
26 DWORD gui_thread_id = 0;
28 extern boolean g_quit;
33 #define DELAYED_WINDOW 1
36 static LRESULT WINAPI
37 my_window_proc (HWND w, UINT msg, WPARAM wp, LPARAM lp)
39 FST* fst=NULL;
40 LRESULT result;
42 // if (msg != WM_TIMER) {
43 // fst_error ("window callback handler, msg = 0x%x win=%p\n", msg, w);
44 // }
46 switch (msg) {
47 case WM_KEYUP:
48 case WM_KEYDOWN:
49 break;
51 case WM_CLOSE:
52 //printf("wtf.\n" );
53 PostQuitMessage (0);
54 case WM_DESTROY:
55 case WM_NCDESTROY:
56 /* we should never get these */
57 //return 0;
58 break;
59 #if 0
60 case WM_PAINT:
61 if ((fst = GetPropA (w, "fst_ptr")) != NULL) {
62 if (fst->window && !fst->been_activated) {
63 fst->been_activated = TRUE;
64 pthread_cond_signal (&fst->window_status_change);
65 pthread_mutex_unlock (&fst->lock);
68 break;
69 #endif
71 #if 0
72 case WM_TIMER:
73 fst = GetPropA( w, "fst_ptr" );
74 if( !fst ) {
75 printf( "Timer without fst_ptr Prop :(\n" );
76 return 0;
79 fst->plugin->dispatcher(fst->plugin, effEditIdle, 0, 0, NULL, 0.0f);
80 if( fst->wantIdle )
81 fst->plugin->dispatcher(fst->plugin, 53, 0, 0, NULL, 0.0f);
82 return 0;
83 #endif
87 default:
88 break;
91 return DefWindowProcA (w, msg, wp, lp );
92 //return 0;
95 static FST*
96 fst_new ()
98 FST* fst = (FST*) calloc (1, sizeof (FST));
99 pthread_mutex_init (&fst->lock, NULL);
100 pthread_cond_init (&fst->window_status_change, NULL);
101 pthread_cond_init (&fst->plugin_dispatcher_called, NULL);
102 fst->want_program = -1;
103 return fst;
106 static FSTHandle*
107 fst_handle_new ()
109 FSTHandle* fst = (FSTHandle*) calloc (1, sizeof (FSTHandle));
110 return fst;
113 DWORD WINAPI gui_event_loop (LPVOID param)
115 MSG msg;
116 FST* fst;
117 char c;
118 HMODULE hInst;
119 HWND window;
121 gui_thread_id = GetCurrentThreadId ();
123 /* create a dummy window for timer events */
125 if ((hInst = GetModuleHandleA (NULL)) == NULL) {
126 fst_error ("can't get module handle");
127 return 1;
130 if ((window = CreateWindowExA (0, "FST", "dummy",
131 WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,
132 9999, 9999,
133 1, 1,
134 NULL, NULL,
135 hInst,
136 NULL )) == NULL) {
137 fst_error ("cannot create dummy timer window");
140 if (!SetTimer (window, 1000, 20, NULL)) {
141 fst_error ("cannot set timer on dummy window");
144 while (GetMessageA (&msg, NULL, 0,0)) {
145 TranslateMessage( &msg );
146 DispatchMessageA (&msg);
148 /* handle window creation requests, destroy requests,
149 and run idle callbacks
153 if( msg.message == WM_TIMER ) {
154 pthread_mutex_lock (&plugin_mutex);
155 again:
156 for (fst = fst_first; fst; fst = fst->next) {
158 if (fst->destroy) {
159 if (fst->window) {
160 fst->plugin->dispatcher( fst->plugin, effEditClose, 0, 0, NULL, 0.0 );
161 CloseWindow (fst->window);
162 fst->window = NULL;
163 fst->destroy = FALSE;
165 fst_event_loop_remove_plugin (fst);
166 fst->been_activated = FALSE;
167 pthread_mutex_lock (&fst->lock);
168 pthread_cond_signal (&fst->window_status_change);
169 pthread_mutex_unlock (&fst->lock);
170 goto again;
173 if (fst->window == NULL) {
174 pthread_mutex_lock (&fst->lock);
175 if (fst_create_editor (fst)) {
176 fst_error ("cannot create editor for plugin %s", fst->handle->name);
177 fst_event_loop_remove_plugin (fst);
178 pthread_cond_signal (&fst->window_status_change);
179 pthread_mutex_unlock (&fst->lock);
180 goto again;
182 /* condition/unlock handled when we receive WM_ACTIVATE */
183 /* XXX: not true. its unlocked in fst_create_editor() */
185 if(fst->want_program != -1 ) {
186 fst->plugin->dispatcher (fst->plugin, effSetProgram, 0, fst->want_program, NULL, 0);
187 fst->want_program = -1;
190 if(fst->dispatcher_wantcall) {
192 pthread_mutex_lock (&fst->lock);
193 fst->dispatcher_retval = fst->plugin->dispatcher( fst->plugin, fst->dispatcher_opcode,
194 fst->dispatcher_index,
195 fst->dispatcher_val,
196 fst->dispatcher_ptr,
197 fst->dispatcher_opt );
198 fst->dispatcher_wantcall = 0;
199 pthread_cond_signal (&fst->plugin_dispatcher_called);
200 pthread_mutex_unlock (&fst->lock);
203 pthread_mutex_lock (&fst->lock);
204 fst->plugin->dispatcher (fst->plugin, effEditIdle, 0, 0, NULL, 0);
205 if( fst->wantIdle ) {
206 fst->plugin->dispatcher (fst->plugin, 53, 0, 0, NULL, 0);
208 pthread_mutex_unlock (&fst->lock);
210 pthread_mutex_unlock (&plugin_mutex);
213 //printf( "quit........\n" );
214 //exit(0);
215 gtk_main_quit();
219 fst_init (HMODULE hInst)
221 WNDCLASSEX wclass;
222 //HMODULE hInst;
224 //if ((hInst = GetModuleHandleA (NULL)) == NULL) {
225 // fst_error ("can't get module handle");
226 // return -1;
228 wclass.cbSize = sizeof(WNDCLASSEX);
229 wclass.style = 0;
230 wclass.lpfnWndProc = my_window_proc;
231 wclass.cbClsExtra = 0;
232 wclass.cbWndExtra = 0;
233 wclass.hInstance = hInst;
234 wclass.hIcon = LoadIcon(hInst, "FST");
235 wclass.hCursor = LoadCursor(0, IDI_APPLICATION);
236 // wclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
237 wclass.lpszMenuName = "MENU_FST";
238 wclass.lpszClassName = "FST";
239 wclass.hIconSm = 0;
241 #if 0
242 wc.style = 0;
243 wc.lpfnWndProc = my_window_proc;
244 wc.cbClsExtra = 0;
245 wc.cbWndExtra = 0;
246 wc.hInstance = hInst;
247 wc.hIcon = LoadIconA( hInst, "FST");
248 wc.hCursor = LoadCursorA( NULL, IDI_APPLICATION );
249 wc.hbrBackground = GetStockObject( BLACK_BRUSH );
250 wc.lpszMenuName = "FSTMENU";
251 wc.lpszClassName = "FST";
252 //wc.hIconSm = 0;
253 #endif
255 if (!RegisterClassExA(&wclass)){
256 printf( "Class register failed :(\n" );
257 return -1;
260 if (CreateThread (NULL, 0, gui_event_loop, NULL, 0, NULL) == NULL) {
261 fst_error ("could not create new thread proxy");
262 return -1;
264 return 0;
268 fst_run_editor (FST* fst)
270 pthread_mutex_lock (&plugin_mutex);
272 if (fst_first == NULL) {
273 fst_first = fst;
274 } else {
275 FST* p = fst_first;
276 while (p->next) {
277 p = p->next;
279 p->next = fst;
282 //printf( "gui_thread_id = %d\n", gui_thread_id );
283 // if (!PostThreadMessageA (gui_thread_id, WM_USER, 0, 0)) {
284 // fst_error ("could not post message to gui thread");
285 // return -1;
286 // }
288 pthread_mutex_unlock (&plugin_mutex);
290 /* wait for the plugin editor window to be created (or not) */
292 pthread_mutex_lock (&fst->lock);
293 if (!fst->window) {
294 pthread_cond_wait (&fst->window_status_change, &fst->lock);
296 pthread_mutex_unlock (&fst->lock);
298 if (!fst->window) {
299 fst_error ("no window created for VST plugin editor");
300 return -1;
303 return 0;
307 fst_call_dispatcher(FST *fst, int opcode, int index, int val, void *ptr, float opt ) {
308 pthread_mutex_lock (&fst->lock);
309 fst->dispatcher_opcode = opcode;
310 fst->dispatcher_index = index;
311 fst->dispatcher_val = val;
312 fst->dispatcher_ptr = ptr;
313 fst->dispatcher_opt = opt;
314 fst->dispatcher_wantcall = 1;
316 pthread_cond_wait (&fst->plugin_dispatcher_called, &fst->lock);
317 pthread_mutex_unlock (&fst->lock);
319 return fst->dispatcher_retval;
323 fst_create_editor (FST* fst)
325 HMODULE hInst;
326 char class[20];
327 HWND window;
328 struct ERect* er;
330 /* "guard point" to trap errors that occur during plugin loading */
332 /* Note: fst->lock is held while this function is called */
334 if (!(fst->plugin->flags & effFlagsHasEditor)) {
335 fst_error ("Plugin \"%s\" has no editor", fst->handle->name);
336 return -1;
339 if ((hInst = GetModuleHandleA (NULL)) == NULL) {
340 fst_error ("can't get module handle");
341 return 1;
344 // if ((window = CreateWindowExA (WS_EX_TOOLWINDOW | WS_EX_TRAYWINDOW, "FST", fst->handle->name,
345 if ((window = CreateWindowExA (0, "FST", fst->handle->name,
346 (WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX),
347 // (WS_OVERLAPPEDWINDOW & ~WS_MAXIMIZEBOX),
348 9999,9999,1,1,
349 // CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
350 NULL, NULL,
351 hInst,
352 NULL)) == NULL) {
353 fst_error ("cannot create editor window");
354 return 1;
357 if (!SetPropA (window, "fst_ptr", fst)) {
358 fst_error ("cannot set fst_ptr on window");
361 fst->window = window;
362 // fst->xid = (int) GetPropA (window, "__wine_x11_whole_window");
368 //printf( "effEditOpen......\n" );
369 fst->plugin->dispatcher (fst->plugin, effEditOpen, 0, 0, fst->window, 0 );
370 fst->plugin->dispatcher (fst->plugin, effEditGetRect, 0, 0, &er, 0 );
372 fst->width = er->right-er->left;
373 fst->height = er->bottom-er->top;
374 //printf( "get rect ses... %d,%d\n", fst->width, fst->height );
376 //SetWindowPos (fst->window, 0, 9999, 9999, er->right-er->left+8, er->bottom-er->top+26, 0);
377 SetWindowPos (fst->window, 0, 9999, 9999, 2, 2, 0);
378 ShowWindow (fst->window, SW_SHOWNA);
379 //SetWindowPos (fst->window, 0, 0, 0, er->right-er->left+8, er->bottom-er->top+26, SWP_NOMOVE|SWP_NOZORDER);
381 fst->xid = (int) GetPropA (window, "__wine_x11_whole_window");
382 printf( "And xid = %x\n", fst->xid );
383 fst->been_activated = TRUE;
384 pthread_cond_signal (&fst->window_status_change);
385 pthread_mutex_unlock (&fst->lock);
387 return 0;
390 void
391 fst_destroy_editor (FST* fst)
393 FST* p;
394 FST* prev;
396 pthread_mutex_lock (&fst->lock);
397 if (fst->window) {
398 fst->destroy = TRUE;
399 //if (!PostThreadMessageA (gui_thread_id, WM_USER, 0, 0)) {
400 //if (!PostThreadMessageA (gui_thread_id, WM_QUIT, 0, 0)) {
401 // fst_error ("could not post message to gui thread");
403 pthread_cond_wait (&fst->window_status_change, &fst->lock);
406 pthread_mutex_unlock (&fst->lock);
409 void
410 fst_event_loop_remove_plugin (FST* fst)
412 FST* p;
413 FST* prev;
415 for (p = fst_first, prev = NULL; p->next; prev = p, p = p->next) {
416 if (p == fst) {
417 if (prev) {
418 prev->next = p->next;
423 if (fst_first == fst) {
424 fst_first = fst_first->next;
429 #if 0
430 int gui_event_loop (FST *fst)
432 printf( "in gui loop\n" );
433 MSG msg;
434 char c;
435 HMODULE hInst;
436 HWND window;
438 if ((hInst = GetModuleHandleA (NULL)) == NULL) {
439 fst_error ("can't get module handle");
440 return 1;
443 while (GetMessageA (&msg, NULL, 0,0)) {
444 TranslateMessage( &msg );
445 DispatchMessageA (&msg);
447 printf( "in gui loop\n" );
452 void
453 fst_set_focus (FST* fst)
455 if (fst->window) {
456 SetFocus (fst->window);
461 fst_run_editor (FST* fst, HMODULE hInst)
463 //HMODULE hInst;
464 char class[20];
465 HWND window;
466 struct ERect *er;
469 if (!(fst->plugin->flags & effFlagsHasEditor)) {
470 fst_error ("Plugin \"%s\" has no editor", fst->handle->name);
471 return -1;
475 //if ((hInst = GetModuleHandleA (NULL)) == NULL) {
476 // fst_error ("can't get module handle");
477 // return 1;
482 fst->plugin->dispatcher (fst->plugin, effEditGetRect, 0, 0, &er, 0 );
484 fst->width = er->right-er->left;
485 fst->height = er->bottom-er->top;
486 printf( "get rect ses... %d,%d\n", fst->width, fst->height );
488 //SetWindowPos (fst->window, 0, 0, 0, er->right-er->left+8, er->bottom-er->top+26, SWP_SHOWWINDOW);
490 // if ((window = CreateWindowExA (WS_EX_TOOLWINDOW | WS_EX_TRAYWINDOW, "FST", fst->handle->name,
491 if ((window = CreateWindowExA (0, "FST", fst->handle->name,
492 (WS_OVERLAPPEDWINDOW | WS_THICKFRAME & ~WS_MAXIMIZEBOX),
493 CW_USEDEFAULT, CW_USEDEFAULT,
494 fst->width+8, fst->height+26,
495 NULL, NULL,
496 hInst,
497 NULL)) == NULL) {
498 fst_error ("cannot create editor window");
499 return 1;
503 if (!SetPropA (window, "fst_ptr", fst)) {
504 fst_error ("cannot set fst_ptr on window");
507 printf( "Trying to open Editor\n" );
508 fst->plugin->dispatcher (fst->plugin, effEditOpen, 0, 0, window, 0 );
509 printf( "effEditOpen returned\n" );
510 ShowWindow (window, SW_SHOW);
512 if (!SetTimer (window, 1000, 100, NULL)) {
513 fst_error ("cannot set timer on dummy window");
516 fst->window = window;
517 fst->xid = (int) GetPropA (window, "__wine_x11_whole_window");
519 // XChangeWindowAttributes( XOpenDisplay(NULL), fst->xid, CWOverrideRedirect, ~0 );
522 return 0;
526 void
527 fst_destroy_editor (FST* fst)
529 if (fst->window) {
530 if (!PostMessageA (fst->window, WM_QUIT, 0, 0)) {
531 fst_error ("could not post message to gui thread");
535 #endif
537 HMODULE
538 fst_load_vst_library(const char * path)
540 HMODULE dll;
541 char * full_path;
542 char * envdup;
543 char * vst_path;
544 size_t len1;
545 size_t len2;
547 if ((dll = LoadLibraryA (path)) != NULL) {
548 return dll;
551 envdup = getenv ("VST_PATH");
552 if (envdup == NULL) {
553 return NULL;
556 envdup = strdup (envdup);
557 if (envdup == NULL) {
558 fst_error ("strdup failed");
559 return NULL;
562 len2 = strlen(path);
564 vst_path = strtok (envdup, ":");
565 while (vst_path != NULL) {
566 fst_error ("\"%s\"", vst_path);
567 len1 = strlen(vst_path);
568 full_path = malloc (len1 + 1 + len2 + 1);
569 memcpy(full_path, vst_path, len1);
570 full_path[len1] = '/';
571 memcpy(full_path + len1 + 1, path, len2);
572 full_path[len1 + 1 + len2] = '\0';
574 if ((dll = LoadLibraryA (full_path)) != NULL) {
575 break;
578 vst_path = strtok (NULL, ":");
581 free(envdup);
583 return dll;
586 FSTHandle*
587 fst_load (const char *path)
589 char* buf, *buf2;
590 FSTHandle* fhandle;
591 char* period;
593 fhandle = fst_handle_new ();
595 // XXX: Would be nice to find the correct call for this.
596 // if the user does not configure Z: to be / we are doomed :(
598 if (strstr (path, ".dll") == NULL) {
600 buf = (char *) malloc (strlen (path) + 7);
602 if( path[0] == '/' ) {
603 sprintf (buf, "Z:%s.dll", path);
604 } else {
605 sprintf (buf, "%s.dll", path);
608 fhandle->nameptr = strdup (path);
610 } else {
612 buf = (char *) malloc (strlen (path) + 3);
614 if( path[0] == '/' ) {
615 sprintf (buf, "Z:%s", path);
616 } else {
617 sprintf (buf, "%s", path);
620 fhandle->nameptr = strdup (path);
623 fhandle->name = basename (fhandle->nameptr);
625 /* strip off .dll */
627 if ((period = strrchr (fhandle->name, '.')) != NULL) {
628 *period = '\0';
631 if ((fhandle->dll = fst_load_vst_library (buf)) == NULL) {
632 fst_unload (fhandle);
633 return NULL;
636 if ((fhandle->main_entry = (main_entry_t) GetProcAddress (fhandle->dll, "main")) == NULL) {
637 fst_unload (fhandle);
638 return NULL;
641 return fhandle;
645 fst_unload (FSTHandle* fhandle)
647 if (fhandle->plugincnt) {
648 return -1;
651 if (fhandle->dll) {
652 FreeLibrary (fhandle->dll);
653 fhandle->dll = NULL;
656 if (fhandle->nameptr) {
657 free (fhandle->nameptr);
658 fhandle->name = NULL;
661 free (fhandle);
662 return 0;
665 FST*
666 fst_instantiate (FSTHandle* fhandle, audioMasterCallback amc, void* userptr)
668 FST* fst = fst_new ();
670 if( fhandle == NULL ) {
671 fst_error( "the handle was NULL\n" );
672 return NULL;
675 if ((fst->plugin = fhandle->main_entry (amc)) == NULL) {
676 fst_error ("%s could not be instantiated\n", fhandle->name);
677 free (fst);
678 return NULL;
681 fst->handle = fhandle;
682 fst->plugin->user = userptr;
684 if (fst->plugin->magic != kEffectMagic) {
685 fst_error ("%s is not a VST plugin\n", fhandle->name);
686 free (fst);
687 return NULL;
690 fst->plugin->dispatcher (fst->plugin, effOpen, 0, 0, 0, 0);
691 //fst->plugin->dispatcher (fst->plugin, effMainsChanged, 0, 0, NULL, 0);
693 fst->handle->plugincnt++;
694 fst->wantIdle = 0;
696 return fst;
699 void
700 fst_close (FST* fst)
702 fst_destroy_editor (fst);
704 fst->plugin->dispatcher (fst->plugin, effMainsChanged, 0, 0, NULL, 0);
705 fst->plugin->dispatcher (fst->plugin, effClose, 0, 0, 0, 0);
707 if (fst->handle->plugincnt) {
708 --fst->handle->plugincnt;
713 fst_get_XID (FST* fst)
715 return fst->xid;
718 float htonf (float v)
720 float result;
721 char * fin = (char*)&v;
722 char * fout = (char*)&result;
723 fout[0] = fin[3];
724 fout[1] = fin[2];
725 fout[2] = fin[1];
726 fout[3] = fin[0];
727 return result;
730 #if 0
731 int fst_load_state (FST * fst, char * filename)
733 FILE * f = fopen (filename, "rb");
734 if (f) {
735 char testMagic[sizeof (magic)];
736 fread (&testMagic, sizeof (magic), 1, f);
737 if (strcmp (testMagic, magic)) {
738 printf ("File corrupt\n");
739 return FALSE;
742 char productString[64];
743 char vendorString[64];
744 char effectName[64];
745 char testString[64];
746 unsigned length;
747 int success;
749 fread (&length, sizeof (unsigned), 1, f);
750 length = htonl (length);
751 fread (productString, length, 1, f);
752 productString[length] = 0;
753 printf ("Product string: %s\n", productString);
755 success = fst_call_dispatcher( fst, effGetProductString, 0, 0, testString, 0 );
756 if (success == 1) {
757 if (strcmp (testString, productString) != 0) {
758 printf ("Product string mismatch! Plugin has: %s\n", testString);
759 fclose (f);
760 return FALSE;
762 } else if (length != 0) {
763 printf ("Product string mismatch! Plugin has none.\n", testString);
764 fclose (f);
765 return FALSE;
768 fread (&length, sizeof (unsigned), 1, f);
769 length = htonl (length);
770 fread (effectName, length, 1, f);
771 effectName[length] = 0;
772 printf ("Effect name: %s\n", effectName);
774 success = fst_call_dispatcher( fst, effGetEffectName, 0, 0, testString, 0 );
775 if (success == 1) {
776 if (strcmp (testString, effectName) != 0) {
777 printf ("Effect name mismatch! Plugin has: %s\n", testString);
778 fclose (f);
779 return FALSE;
781 } else if (length != 0) {
782 printf ("Effect name mismatch! Plugin has none.\n", testString);
783 fclose (f);
784 return FALSE;
787 fread (&length, sizeof (unsigned), 1, f);
788 length = htonl (length);
789 fread (vendorString, length, 1, f);
790 vendorString[length] = 0;
791 printf ("Vendor string: %s\n", vendorString);
793 success = fst_call_dispatcher( fst, effGetVendorString, 0, 0, testString, 0 );
794 if (success == 1) {
795 if (strcmp (testString, vendorString) != 0) {
796 printf ("Vendor string mismatch! Plugin has: %s\n", testString);
797 fclose (f);
798 return FALSE;
800 } else if (length != 0) {
801 printf ("Vendor string mismatch! Plugin has none.\n", testString);
802 fclose (f);
803 return FALSE;
806 int numParam;
807 unsigned i;
808 fread (&numParam, sizeof (int), 1, f);
809 numParam = htonl (numParam);
810 for (i = 0; i < numParam; ++i) {
811 float val;
812 fread (&val, sizeof (float), 1, f);
813 val = htonf (val);
815 pthread_mutex_lock( &fst->lock );
816 fst->plugin->setParameter( fst->plugin, i, val );
817 pthread_mutex_unlock( &fst->lock );
820 int bytelen;
821 fread (&bytelen, sizeof (int), 1, f);
822 bytelen = htonl (bytelen);
823 if (bytelen) {
824 char * buf = malloc (bytelen);
825 fread (buf, bytelen, 1, f);
827 fst_call_dispatcher( fst, 24, 0, bytelen, buf, 0 );
828 free (buf);
830 } else {
831 printf ("Could not open state file\n");
832 return FALSE;
834 return TRUE;
837 #endif
839 int fst_save_state (FST * fst, char * filename)
841 FILE * f = fopen (filename, "wb");
842 if (f) {
843 int bytelen;
844 int numParams = fst->plugin->numParams;
845 unsigned i;
846 char productString[64];
847 char effectName[64];
848 char vendorString[64];
849 int success;
850 unsigned length;
852 // write header
853 fprintf( f, "<plugin_state>\n" );
855 success = fst_call_dispatcher( fst, effGetProductString, 0, 0, productString, 0 );
856 if( success == 1 ) {
857 fprintf (f, " <check field=\"productString\" value=\"%s\"/>\n", productString);
858 } else {
859 printf ("No product string\n");
862 success = fst_call_dispatcher( fst, effGetEffectName, 0, 0, effectName, 0 );
863 if( success == 1 ) {
864 fprintf (f, " <check field=\"effectName\" value=\"%s\"/>\n", effectName);
865 printf ("Effect name: %s\n", effectName);
866 } else {
867 printf ("No effect name\n");
870 success = fst_call_dispatcher( fst, effGetVendorString, 0, 0, vendorString, 0 );
871 if( success == 1 ) {
872 fprintf (f, " <check field=\"vendorString\" value=\"%s\"/>\n", vendorString);
873 printf ("Vendor string: %s\n", vendorString);
874 } else {
875 printf ("No vendor string\n");
879 if( fst->plugin->flags & 32 ) {
880 numParams = 0;
883 for( i=0; i<numParams; i++ ) {
884 float val;
886 pthread_mutex_lock( &fst->lock );
887 val = fst->plugin->getParameter( fst->plugin, i );
888 pthread_mutex_unlock( &fst->lock );
889 fprintf( f, " <param index=\"%d\" value=\"%f\"/>\n", i, val );
892 if( fst->plugin->flags & 32 ) {
893 printf( "getting chunk...\n" );
894 void * chunk;
895 bytelen = fst_call_dispatcher( fst, 23, 0, 0, &chunk, 0 );
896 printf( "got tha chunk..\n" );
897 if( bytelen ) {
898 if( bytelen < 0 ) {
899 printf( "Chunke len < 0 !!! Not saving chunk.\n" );
900 } else {
901 char *encoded = g_base64_encode( chunk, bytelen );
902 fprintf( f, " <chunk size=\"%d\">\n %s\n </chunk>\n", bytelen, encoded );
903 g_free( encoded );
908 fprintf( f, "</plugin_state>\n" );
909 fclose( f );
910 } else {
911 printf ("Could not open state file\n");
912 return FALSE;
914 return TRUE;