5 #include <wine/exception.h>
9 //#include <x11/xlib.h>
10 //#include <x11/xresource.h>
11 //#include <x11/xutil.h>
12 //#include <x11/xatom.h>
24 static pthread_mutex_t plugin_mutex;
25 static FST* fst_first = NULL;
27 DWORD gui_thread_id = 0;
35 /* Define to a macro to generate an assembly function directive */
36 #define __ASM_FUNC(name) ".type " __ASM_NAME(name) ",@function"
38 /* Define to a macro to generate an assembly name from a C symbol */
39 #define __ASM_NAME(name) name
41 # define __ASM_GLOBAL_FUNC(name,code) \
42 __asm__( ".align 4\n\t" \
43 ".globl " __ASM_NAME(#name) "\n\t" \
44 __ASM_FUNC(#name) "\n" \
45 __ASM_NAME(#name) ":\n\t" \
48 __ASM_GLOBAL_FUNC( fst_get_teb, ".byte 0x64\n\tmovl 0x18,%eax\n\tret" );
52 #define DELAYED_WINDOW
55 my_window_proc (HWND w, UINT msg, WPARAM wp, LPARAM lp)
60 // if (msg != WM_TIMER) {
61 // fst_error ("window callback handler, msg = 0x%x win=%p\n", msg, w);
67 printf( "got a key\n" );
75 /* we should never get these */
83 //if (wp & WA_ACTIVE) {
84 if ((fst = GetPropA (w, "fst_ptr")) != NULL) {
85 if (fst->window && !fst->been_activated) {
86 fst->been_activated = TRUE;
88 // XSetWindowAttributes attr;
90 // attr.override_redirect = TRUE;
91 //// XChangeWindowAttributes( thread_display(), fst->xid, CWOverrideRedirect, &attr );
93 pthread_cond_signal (&fst->window_status_change);
94 pthread_mutex_unlock (&fst->lock);
105 return DefWindowProcA (w, msg, wp, lp );
111 FST* fst = (FST*) calloc (1, sizeof (FST));
113 pthread_mutex_init (&fst->lock, NULL);
114 pthread_cond_init (&fst->window_status_change, NULL);
122 FSTHandle* fst = (FSTHandle*) calloc (1, sizeof (FSTHandle));
127 static __thread int ejmpbuf_valid = FALSE;
128 static __thread jmp_buf ejmpbuf;
130 static pthread_key_t ejmpbuf_valid_key;
131 static pthread_key_t ejmpbuf_key;
134 void debreak( void ) { printf( "debreak\n" ); }
138 fst_init (void (*sighandler)(int,siginfo_t*,void*))
140 //SharedWineInit (sighandler);
141 wine_shared_premain();
146 DWORD WINAPI gui_event_loop (LPVOID param)
154 gui_thread_id = GetCurrentThreadId ();
156 /* create a dummy window for timer events */
158 if ((hInst = GetModuleHandleA (NULL)) == NULL) {
159 fst_error ("can't get module handle");
163 if ((window = CreateWindowExA (0, "FST", "dummy",
164 WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX,
165 CW_USEDEFAULT, CW_USEDEFAULT,
166 CW_USEDEFAULT, CW_USEDEFAULT,
170 fst_error ("cannot create dummy timer window");
173 if (!SetTimer (window, 1000, 100, NULL)) {
174 fst_error ("cannot set timer on dummy window");
177 while (GetMessageA (&msg, NULL, 0,0)) {
178 if( msg.message == WM_KEYDOWN ) debreak();
179 TranslateMessage( &msg );
180 DispatchMessageA (&msg);
182 /* handle window creation requests, destroy requests,
183 and run idle callbacks
187 if( msg.message == WM_TIMER ) {
188 pthread_mutex_lock (&plugin_mutex);
190 for (fst = fst_first; fst; fst = fst->next) {
194 fst->plugin->dispatcher( fst->plugin, effEditClose, 0, 0, NULL, 0.0 );
195 CloseWindow (fst->window);
197 fst->destroy = FALSE;
199 fst_event_loop_remove_plugin (fst);
200 fst->been_activated = FALSE;
201 pthread_mutex_lock (&fst->lock);
202 pthread_cond_signal (&fst->window_status_change);
203 pthread_mutex_unlock (&fst->lock);
207 if (fst->window == NULL) {
208 pthread_mutex_lock (&fst->lock);
209 if (fst_create_editor (fst)) {
210 fst_error ("cannot create editor for plugin %s", fst->handle->name);
211 fst_event_loop_remove_plugin (fst);
212 pthread_cond_signal (&fst->window_status_change);
213 pthread_mutex_unlock (&fst->lock);
216 /* condition/unlock handled when we receive WM_ACTIVATE */
219 fst->plugin->dispatcher (fst->plugin, effEditIdle, 0, 0, NULL, 0);
221 pthread_mutex_unlock (&plugin_mutex);
224 printf( "quit........\n" );
230 fst_set_focus (FST* fst)
233 SetFocus (fst->window);
238 wine_shared_premain ()
243 if ((hInst = GetModuleHandleA (NULL)) == NULL) {
244 fst_error ("can't get module handle");
248 wc.lpfnWndProc = my_window_proc;
251 wc.hInstance = hInst;
252 wc.hIcon = LoadIconA( hInst, "FST");
253 wc.hCursor = LoadCursorA( NULL, IDI_APPLICATION );
254 wc.hbrBackground = GetStockObject( BLACK_BRUSH );
255 wc.lpszMenuName = "MENU_FST";
256 wc.lpszClassName = "FST";
258 if (!RegisterClassA(&wc)){
262 if (CreateThread (NULL, 0, gui_event_loop, NULL, 0, NULL) == NULL) {
263 fst_error ("could not create new thread proxy");
271 fst_run_editor (FST* fst)
273 pthread_mutex_lock (&plugin_mutex);
275 if (fst_first == NULL) {
285 printf( "gui_thread_id = %d\n", gui_thread_id );
286 if (!PostThreadMessageA (gui_thread_id, WM_USER, 0, 0)) {
287 fst_error ("could not post message to gui thread");
291 pthread_mutex_unlock (&plugin_mutex);
293 /* wait for the plugin editor window to be created (or not) */
295 pthread_mutex_lock (&fst->lock);
297 pthread_cond_wait (&fst->window_status_change, &fst->lock);
299 pthread_mutex_unlock (&fst->lock);
302 fst_error ("no window created for VST plugin editor");
310 fst_create_editor (FST* fst)
316 /* "guard point" to trap errors that occur during plugin loading */
318 /* Note: fst->lock is held while this function is called */
320 if (!(fst->plugin->flags & effFlagsHasEditor)) {
321 fst_error ("Plugin \"%s\" has no editor", fst->handle->name);
325 if ((hInst = GetModuleHandleA (NULL)) == NULL) {
326 fst_error ("can't get module handle");
330 // if ((window = CreateWindowExA (WS_EX_TOOLWINDOW | WS_EX_TRAYWINDOW, "FST", fst->handle->name,
331 if ((window = CreateWindowExA (0, "FST", fst->handle->name,
332 (WS_OVERLAPPEDWINDOW & ~WS_THICKFRAME & ~WS_MAXIMIZEBOX),
337 fst_error ("cannot create editor window");
341 if (!SetPropA (window, "fst_ptr", fst)) {
342 fst_error ("cannot set fst_ptr on window");
345 fst->window = window;
346 fst->xid = (int) GetPropA (window, "__wine_x11_whole_window");
348 // XChangeWindowAttributes( XOpenDisplay(NULL), fst->xid, CWOverrideRedirect, ~0 );
351 #ifdef DELAYED_WINDOW
355 ShowWindow (fst->window, SW_SHOW);
357 fst->plugin->dispatcher (fst->plugin, effEditOpen, 0, 0, fst->window, 0 );
358 fst->plugin->dispatcher (fst->plugin, effEditGetRect, 0, 0, &er, 0 );
360 fst->width = er->right-er->left;
361 fst->height = er->bottom-er->top;
363 SetWindowPos (fst->window, 0, 0, 0, er->right-er->left+8, er->bottom-er->top+26, SWP_SHOWWINDOW|SWP_NOMOVE|SWP_NOZORDER);
367 pthread_cond_signal (&fst->window_status_change);
368 pthread_mutex_unlock (&fst->lock);
375 fst_show_editor (FST* fst)
377 #ifndef DELAYED_WINDOW
380 fst->plugin->dispatcher (fst->plugin, effEditOpen, 0, 0, fst->window, 0 );
381 fst->plugin->dispatcher (fst->plugin, effEditGetRect, 0, 0, &er, 0 );
382 fst->width = er->right-er->left;
383 fst->height = er->bottom-er->top;
385 SetWindowPos (window, 0, 0, 0, er->right-er->left+8, er->bottom-er->top+26, SWP_NOMOVE | SWP_NOZORDER);
386 *ejmpbuf_valid = FALSE;
391 fst_destroy_editor (FST* fst)
396 pthread_mutex_lock (&fst->lock);
399 if (!PostThreadMessageA (gui_thread_id, WM_USER, 0, 0)) {
400 fst_error ("could not post message to gui thread");
402 pthread_cond_wait (&fst->window_status_change, &fst->lock);
405 pthread_mutex_unlock (&fst->lock);
409 fst_event_loop_remove_plugin (FST* fst)
414 for (p = fst_first, prev = NULL; p->next; prev = p, p = p->next) {
417 prev->next = p->next;
422 if (fst_first == fst) {
423 fst_first = fst_first->next;
429 fst_load (const char *path)
435 fhandle = fst_handle_new ();
437 // XXX: Would be nice to find the correct call for this.
438 // if the user does not configure Z: to be / we are doomed :(
440 if (strstr (path, ".dll") == NULL) {
442 buf = (char *) malloc (strlen (path) + 7);
444 if( path[0] == '/' ) {
445 sprintf (buf, "Z:%s.dll", path);
447 sprintf (buf, "%s.dll", path);
450 fhandle->nameptr = strdup (path);
454 buf = (char *) malloc (strlen (path) + 3);
456 if( path[0] == '/' ) {
457 sprintf (buf, "Z:%s", path);
459 sprintf (buf, "%s", path);
462 fhandle->nameptr = strdup (path);
465 fhandle->name = basename (fhandle->nameptr);
469 if ((period = strrchr (fhandle->name, '.')) != NULL) {
473 if ((fhandle->dll = LoadLibraryA (buf)) == NULL) {
474 fst_unload (fhandle);
478 if ((fhandle->main_entry = GetProcAddress (fhandle->dll, "main")) == NULL) {
479 fst_unload (fhandle);
487 fst_unload (FSTHandle* fhandle)
489 if (fhandle->plugincnt) {
494 FreeLibrary (fhandle->dll);
498 if (fhandle->nameptr) {
499 free (fhandle->nameptr);
500 fhandle->name = NULL;
508 fst_instantiate (FSTHandle* fhandle, audioMasterCallback amc, void* userptr)
510 FST* fst = fst_new ();
512 if( fhandle == NULL ) {
513 fst_error( "the handle was NULL\n" );
517 if ((fst->plugin = fhandle->main_entry (amc)) == NULL) {
518 fst_error ("%s could not be instantiated\n", fhandle->name);
523 fst->handle = fhandle;
524 fst->plugin->user = userptr;
526 if (fst->plugin->magic != kEffectMagic) {
527 fst_error ("%s is not a VST plugin\n", fhandle->name);
532 fst->plugin->dispatcher (fst->plugin, effOpen, 0, 0, 0, 0);
533 //fst->plugin->dispatcher (fst->plugin, effMainsChanged, 0, 0, NULL, 0);
535 fst->handle->plugincnt++;
543 fst_destroy_editor (fst);
545 fst->plugin->dispatcher (fst->plugin, effMainsChanged, 0, 0, NULL, 0);
546 fst->plugin->dispatcher (fst->plugin, effClose, 0, 0, 0, 0);
548 if (fst->handle->plugincnt) {
549 --fst->handle->plugincnt;
554 fst_get_XID (FST* fst)