/[svn]/gigedit/trunk/src/gigedit/gigedit.cpp
ViewVC logotype

Diff of /gigedit/trunk/src/gigedit/gigedit.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2471 by persson, Sun Sep 15 17:06:45 2013 UTC revision 2474 by schoenebeck, Sun Sep 15 18:16:21 2013 UTC
# Line 1  Line 1 
1  /*  /*
2   * Copyright (C) 2007-2009 Andreas Persson   * Copyright (C) 2007-2013 Andreas Persson
3   *   *
4   * This program is free software; you can redistribute it and/or   * This program is free software; you can redistribute it and/or
5   * modify it under the terms of the GNU General Public License as   * modify it under the terms of the GNU General Public License as
# Line 23  Line 23 
23  #include <glibmm/main.h>  #include <glibmm/main.h>
24  #include <gtkmm/main.h>  #include <gtkmm/main.h>
25    
26    #if defined(__APPLE__)
27    # include <CoreFoundation/CoreFoundation.h>
28    # include "MacHelper.h"
29    #endif
30    
31  #include "mainwindow.h"  #include "mainwindow.h"
32    
33  #include "global.h"  #include "global.h"
# Line 33  Line 38 
38  #include <glibmm/miscutils.h>  #include <glibmm/miscutils.h>
39  #endif  #endif
40    
41    //TODO: (hopefully) just a temporary nasty hack for launching gigedit on the main thread on Mac (see comments below in this file for details)
42    #if defined(__APPLE__) // the following global external variables are defined in LinuxSampler's global_private.cpp ...
43    extern bool g_mainThreadCallbackSupported;
44    extern void (*g_mainThreadCallback)(void* info);
45    extern void* g_mainThreadCallbackInfo;
46    extern bool g_fireMainThreadCallback;
47    #endif
48    
49  namespace {  namespace {
50    
51  // State for a gigedit thread.  // State for a gigedit thread.
# Line 85  private: Line 98  private:
98      GigEdit* parent;      GigEdit* parent;
99      Cond open;      Cond open;
100      Cond close;      Cond close;
101        Cond initialized;
102      gig::Instrument* instrument;      gig::Instrument* instrument;
103    
104      void open_window();      void open_window();
105      void close_window();      void close_window();
106    #if defined(__APPLE__)
107        static void runInCFMainLoop(void* info);
108    #endif
109  };  };
110    
111  #ifdef WIN32  #ifdef WIN32
# Line 127  void init_app() { Line 144  void init_app() {
144                      Glib::setenv("GDK_PIXBUF_MODULE_FILE", module_file, true);                      Glib::setenv("GDK_PIXBUF_MODULE_FILE", module_file, true);
145                  }                  }
146              }              }
147  #if HAVE_GETTEXT    //FIXME: for some reason AC GETTEXT check fails on the Mac cross compiler?
148      //#if HAVE_GETTEXT
149              std::string localedir = Glib::build_filename(libdir, "locale");              std::string localedir = Glib::build_filename(libdir, "locale");
150              if (Glib::file_test(localedir, Glib::FILE_TEST_EXISTS)) {              if (Glib::file_test(localedir, Glib::FILE_TEST_EXISTS)) {
151                  gigedit_localedir = localedir;                  gigedit_localedir = localedir;
# Line 135  void init_app() { Line 153  void init_app() {
153              } else {              } else {
154                  bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);                  bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
155              }              }
156  #endif    //#endif
157          }          }
158    
159          // The gtk file dialog stores its recent files state in          // The gtk file dialog stores its recent files state in
# Line 143  void init_app() { Line 161  void init_app() {
161          g_mkdir_with_parents(          g_mkdir_with_parents(
162              Glib::build_filename(Glib::get_home_dir(),              Glib::build_filename(Glib::get_home_dir(),
163                                   ".local/share").c_str(), 0777);                                   ".local/share").c_str(), 0777);
164  #endif  #endif // __APPLE__
165    
166  #if HAVE_GETTEXT  //FIXME: for some reason AC GETTEXT check fails on the Mac cross compiler?
167    #if (HAVE_GETTEXT || defined(__APPLE__))
168    
169  #ifdef WIN32    #ifdef WIN32
170  #if GLIB_CHECK_VERSION(2, 16, 0)      #if GLIB_CHECK_VERSION(2, 16, 0)
171          gchar* root =          gchar* root =
172              g_win32_get_package_installation_directory_of_module(gigedit_dll_handle);              g_win32_get_package_installation_directory_of_module(gigedit_dll_handle);
173  #else      #else
174          gchar* root =          gchar* root =
175              g_win32_get_package_installation_directory(NULL, NULL);              g_win32_get_package_installation_directory(NULL, NULL);
176  #endif      #endif
177          gchar* temp = g_build_filename(root, "/share/locale", NULL);          gchar* temp = g_build_filename(root, "/share/locale", NULL);
178          g_free(root);          g_free(root);
179          gchar* localedir = g_win32_locale_filename_from_utf8(temp);          gchar* localedir = g_win32_locale_filename_from_utf8(temp);
180          g_free(temp);          g_free(temp);
181          bindtextdomain(GETTEXT_PACKAGE, localedir);          bindtextdomain(GETTEXT_PACKAGE, localedir);
182          g_free(localedir);          g_free(localedir);
183  #elif !defined(__APPLE__)    #elif !defined(__APPLE__)
184          bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);          bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
185  #endif    #endif
186          bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");          bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
187          textdomain(GETTEXT_PACKAGE);          textdomain(GETTEXT_PACKAGE);
188  #endif // HAVE_GETTEXT  #endif // HAVE_GETTEXT
# Line 229  int GigEdit::run(int argc, char* argv[]) Line 248  int GigEdit::run(int argc, char* argv[])
248    
249      Gtk::Main kit(argc, argv);      Gtk::Main kit(argc, argv);
250    
251  #if HAVE_GETTEXT && defined(__APPLE__)  //FIXME: for some reason AC GETTEXT check fails on the Mac cross compiler?
252    #if (/*HAVE_GETTEXT &&*/ defined(__APPLE__))
253      // Gtk::Main binds the gtk locale to a possible non-existent      // Gtk::Main binds the gtk locale to a possible non-existent
254      // directory. If we have bundled gtk locale files, we rebind here,      // directory. If we have bundled gtk locale files, we rebind here,
255      // after the Gtk::Main constructor.      // after the Gtk::Main constructor.
# Line 350  void GigEditState::main_loop_run(Cond* i Line 370  void GigEditState::main_loop_run(Cond* i
370      const char* argv_c[] = { "gigedit" };      const char* argv_c[] = { "gigedit" };
371      char** argv = const_cast<char**>(argv_c);      char** argv = const_cast<char**>(argv_c);
372      Gtk::Main main_loop(argc, argv);      Gtk::Main main_loop(argc, argv);
373  #if HAVE_GETTEXT && defined(__APPLE__)  //FIXME: for some reason AC GETTEXT check fails on the Mac cross compiler?
374    #if (/*HAVE_GETTEXT &&*/ defined(__APPLE__))
375      if (!gigedit_localedir.empty()) {      if (!gigedit_localedir.empty()) {
376          bindtextdomain("gtk20", gigedit_localedir.c_str());          bindtextdomain("gtk20", gigedit_localedir.c_str());
377      }      }
# Line 363  void GigEditState::main_loop_run(Cond* i Line 384  void GigEditState::main_loop_run(Cond* i
384      main_loop.run();      main_loop.run();
385  }  }
386    
387    #if defined(__APPLE__)
388    
389    void GigEditState::runInCFMainLoop(void* info) {
390        printf("runInCFMainLoop() entered\n"); fflush(stdout);
391        GigEditState* state = static_cast<GigEditState*>(info);
392        state->main_loop_run(
393            &state->initialized
394        );
395        printf("runInCFMainLoop() left\n"); fflush(stdout);
396    }
397    
398    #endif // __APPLE__
399    
400  void GigEditState::run(gig::Instrument* pInstrument) {  void GigEditState::run(gig::Instrument* pInstrument) {
401      mutex.lock(); // lock access to static variables      mutex.lock(); // lock access to static variables
402    
403      static bool main_loop_started = false;      static bool main_loop_started = false;
404      if (!main_loop_started) {      if (!main_loop_started) {
405          Cond initialized;  #if defined(__APPLE__)
406  #ifdef OLD_THREADS          // spawn GUI on main thread :
407            //     On OS X the Gtk GUI can only be launched on a process's "main"
408            //     thread. When trying to launch the Gtk GUI on any other thread,
409            //     there will only be a white box, because the GUI would not receive
410            //     any events, since it would listen to the wrong system event loop.
411            //     So far we haven't investigated whether there is any kind of
412            //     circumvention to allow doing that also on other OS X threads.
413            {
414                // In case the sampler was launched as standalone sampler (not as
415                // plugin), use the following global callback variable hack ...
416                if (g_mainThreadCallbackSupported) {
417                    printf("Setting callback ...\n"); fflush(stdout);
418                    g_mainThreadCallback = runInCFMainLoop;
419                    g_mainThreadCallbackInfo = this;
420                    g_fireMainThreadCallback = true;
421                    printf("Callback variables set.\n"); fflush(stdout);
422                } else { // Sampler was launched as (i.e. AU / VST) plugin ...
423                    // When the sampler was launched as plugin, we have no idea
424                    // whether any sampler thread is the process's "main" thread.
425                    // So that's why we are trying to use Apple's API for trying to
426                    // launch our callback function on the process's main thread.
427                    // However this will only work, if the plugin host application
428                    // established a CF event loop, that is if the application is
429                    // using Cocoa for its GUI. For other host applications the
430                    // callback will never be executed and thus gigedit would not
431                    // popup.
432                    
433                    // should be pretty much the same as the Objective-C solution below with macHelperRunCFuncOnMainThread()
434                    /*CFRunLoopSourceContext sourceContext = CFRunLoopSourceContext();
435                    sourceContext.info = this;
436                    sourceContext.perform = runInCFMainLoop;
437                    printf("CFRunLoopSourceCreate\n"); fflush(stdout);
438                    CFRunLoopSourceRef source = CFRunLoopSourceCreate(
439                        kCFAllocatorDefault, // allocator
440                        1, // priority
441                        &sourceContext
442                    );
443                    printf("CFRunLoopAddSource\n"); fflush(stdout);
444                    CFRunLoopAddSource(CFRunLoopGetMain(), source, kCFRunLoopDefaultMode);
445                    CFRelease(source);*/
446                    
447                    // use Apple's Objective-C API to call our callback function
448                    // 'runInCFMainLoop()' on the process's "main" thread
449                    macHelperRunCFuncOnMainThread(runInCFMainLoop, this);
450                }
451            }
452    #else
453      #ifdef OLD_THREADS
454          Glib::Thread::create(          Glib::Thread::create(
455              sigc::bind(sigc::ptr_fun(&GigEditState::main_loop_run),              sigc::bind(sigc::ptr_fun(&GigEditState::main_loop_run),
456                         &initialized),                         &initialized),
457              false);              false);
458  #else    #else
459          Glib::Threads::Thread::create(          Glib::Threads::Thread::create(
460              sigc::bind(sigc::ptr_fun(&GigEditState::main_loop_run),              sigc::bind(sigc::ptr_fun(&GigEditState::main_loop_run),
461                         &initialized));                         &initialized));
462      #endif
463  #endif  #endif
464            printf("Waiting for GUI being initialized (on main thread) ....\n"); fflush(stdout);
465          initialized.wait();          initialized.wait();
466            printf("GUI is now initialized. Everything done.\n"); fflush(stdout);
467          main_loop_started = true;          main_loop_started = true;
468      }      }
469      instrument = pInstrument;      instrument = pInstrument;

Legend:
Removed from v.2471  
changed lines
  Added in v.2474

  ViewVC Help
Powered by ViewVC