/[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 1225 by schoenebeck, Sun Jun 10 10:56:11 2007 UTC revision 1456 by persson, Sun Oct 21 15:32:36 2007 UTC
# Line 22  Line 22 
22  #include <gtkmm/main.h>  #include <gtkmm/main.h>
23  #include "mainwindow.h"  #include "mainwindow.h"
24    
25  #include <libintl.h>  #include "global.h"
 #include <config.h>  
26    
27  // the app has to work from a DLL as well, so we hard code argv  namespace {
 int argc = 1;  
 const char* argv_c[] = { "gigedit" };  
 char** argv = const_cast<char**>(argv_c);  
28    
29  static void __init_app() {  // State for a gigedit thread.
30      setlocale(LC_ALL, "");  //
31      bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);  // This class is only used when gigedit is run as a plugin and makes
32      bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");  // sure that there's only one Gtk::Main event loop. The event loop is
33      textdomain(GETTEXT_PACKAGE);  // started in a separate thread. The plugin thread just dispatches an
34    // event to the main loop to open a window and then goes to sleep
35    // until the window is closed.
36    //
37    class GigEditState : public sigc::trackable {
38    public:
39        GigEditState(GigEdit* parent) : parent(parent) { }
40        void run(gig::Instrument* pInstrument);
41    
42    private:
43    
44        // simple condition variable abstraction
45        class Cond {
46        private:
47            bool pred;
48            Glib::Mutex mutex;
49            Glib::Cond cond;
50        public:
51            Cond() : pred(false) { }
52            void signal() {
53                Glib::Mutex::Lock lock(mutex);
54                pred = true;
55                cond.signal();
56            }
57            void wait() {
58                Glib::Mutex::Lock lock(mutex);
59                while (!pred) cond.wait(mutex);
60            }
61        };
62    
63        static Glib::StaticMutex mutex;
64        static Glib::Dispatcher* dispatcher;
65        static GigEditState* current;
66    
67        static void main_loop_run(Cond* intialized);
68        static void open_window_static();
69    
70        GigEdit* parent;
71        Cond open;
72        Cond close;
73        gig::Instrument* instrument;
74        MainWindow* window;
75    
76        void open_window();
77        void close_window();
78    };
79    
80    void init_app() {
81        static bool process_initialized = false;
82        if (!process_initialized) {
83            std::cout << "Initializing 3rd party services needed by gigedit.\n"
84                      << std::flush;
85            setlocale(LC_ALL, "");
86    
87    #if HAVE_GETTEXT
88            bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
89            bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
90            textdomain(GETTEXT_PACKAGE);
91    #endif // HAVE_GETTEXT
92    
93      Glib::thread_init();          // make sure thread_init() is called once and ONLY once per process
94            if (!Glib::thread_supported()) Glib::thread_init();
95    
96            process_initialized = true;
97        }
98    }
99    
100    void connect_signals(GigEdit* gigedit, MainWindow* mainwindow) {
101        // the signals of the "GigEdit" class are actually just proxies, that
102        // is they simply forward the signals of the internal classes to the
103        // outer world
104        mainwindow->signal_file_structure_to_be_changed().connect(
105            gigedit->signal_file_structure_to_be_changed().make_slot()
106        );
107        mainwindow->signal_file_structure_changed().connect(
108            gigedit->signal_file_structure_changed().make_slot()
109        );
110        mainwindow->signal_samples_to_be_removed().connect(
111            gigedit->signal_samples_to_be_removed().make_slot()
112        );
113        mainwindow->signal_samples_removed().connect(
114            gigedit->signal_samples_removed().make_slot()
115        );
116        mainwindow->signal_region_to_be_changed().connect(
117            gigedit->signal_region_to_be_changed().make_slot()
118        );
119        mainwindow->signal_region_changed().connect(
120            gigedit->signal_region_changed().make_slot()
121        );
122        mainwindow->signal_dimreg_to_be_changed().connect(
123            gigedit->signal_dimreg_to_be_changed().make_slot()
124        );
125        mainwindow->signal_dimreg_changed().connect(
126            gigedit->signal_dimreg_changed().make_slot()
127        );
128        mainwindow->signal_sample_ref_changed().connect(
129            gigedit->signal_sample_ref_changed().make_slot()
130        );
131  }  }
132    
 int GigEdit::run() {  
     __init_app();  
     Gtk::Main kit(argc, argv);  
     MainWindow window;  
     kit.run(window);  
     return 0;  
133  }  }
134    
135  int GigEdit::run(const char* pFileName) {  
136      __init_app();  int GigEdit::run(int argc, char* argv[]) {
137        init_app();
138    
139      Gtk::Main kit(argc, argv);      Gtk::Main kit(argc, argv);
140      MainWindow window;      MainWindow window;
141      if (pFileName) window.load_file(pFileName);      connect_signals(this, &window);
142        if (argc >= 2) window.load_file(argv[1]);
143      kit.run(window);      kit.run(window);
144      return 0;      return 0;
145  }  }
146    
147  int GigEdit::run(gig::Instrument* pInstrument) {  int GigEdit::run(gig::Instrument* pInstrument) {
148      __init_app();      init_app();
149      Gtk::Main kit(argc, argv);  
150      MainWindow window;      GigEditState state(this);
151      if (pInstrument) window.load_instrument(pInstrument);      state.run(pInstrument);
     kit.run(window);  
152      return 0;      return 0;
153  }  }
154    
155    sigc::signal<void, gig::File*>& GigEdit::signal_file_structure_to_be_changed() {
156        return file_structure_to_be_changed_signal;
157    }
158    
159    sigc::signal<void, gig::File*>& GigEdit::signal_file_structure_changed() {
160        return file_structure_changed_signal;
161    }
162    
163    sigc::signal<void, std::list<gig::Sample*> >& GigEdit::signal_samples_to_be_removed() {
164        return samples_to_be_removed_signal;
165    }
166    
167    sigc::signal<void>& GigEdit::signal_samples_removed() {
168        return samples_removed_signal;
169    }
170    
171    sigc::signal<void, gig::Region*>& GigEdit::signal_region_to_be_changed() {
172        return region_to_be_changed_signal;
173    }
174    
175    sigc::signal<void, gig::Region*>& GigEdit::signal_region_changed() {
176        return region_changed_signal;
177    }
178    
179    sigc::signal<void, gig::DimensionRegion*>& GigEdit::signal_dimreg_to_be_changed() {
180        return dimreg_to_be_changed_signal;
181    }
182    
183    sigc::signal<void, gig::DimensionRegion*>& GigEdit::signal_dimreg_changed() {
184        return dimreg_changed_signal;
185    }
186    
187    sigc::signal<void, gig::Sample*/*old*/, gig::Sample*/*new*/>& GigEdit::signal_sample_ref_changed() {
188        return sample_ref_changed_signal;
189    }
190    
191    
192    Glib::StaticMutex GigEditState::mutex = GLIBMM_STATIC_MUTEX_INIT;
193    Glib::Dispatcher* GigEditState::dispatcher = 0;
194    GigEditState* GigEditState::current = 0;
195    
196    void GigEditState::open_window_static() {
197        GigEditState* c = GigEditState::current;
198        c->open.signal();
199        c->open_window();
200    }
201    
202    void GigEditState::open_window() {
203        window = new MainWindow();
204    
205        connect_signals(parent, window);
206        if (instrument) window->load_instrument(instrument);
207    
208        window->signal_hide().connect(sigc::mem_fun(this,
209                                                    &GigEditState::close_window));
210        window->present();
211    }
212    
213    void GigEditState::close_window() {
214        delete window;
215        close.signal();
216    }
217    
218    void GigEditState::main_loop_run(Cond* initialized) {
219        int argc = 1;
220        const char* argv_c[] = { "gigedit" };
221        char** argv = const_cast<char**>(argv_c);
222        Gtk::Main main_loop(argc, argv);
223    
224        dispatcher = new Glib::Dispatcher();
225        dispatcher->connect(sigc::ptr_fun(&GigEditState::open_window_static));
226        initialized->signal();
227    
228        main_loop.run();
229    }
230    
231    void GigEditState::run(gig::Instrument* pInstrument) {
232        mutex.lock(); // lock access to static variables
233    
234        static bool main_loop_started = false;
235        if (!main_loop_started) {
236            Cond initialized;
237            Glib::Thread::create(
238                sigc::bind(sigc::ptr_fun(&GigEditState::main_loop_run),
239                           &initialized),
240                false);
241            initialized.wait();
242            main_loop_started = true;
243        }
244        instrument = pInstrument;
245        current = this;
246        dispatcher->emit();
247        open.wait(); // wait until the GUI thread has read current
248        mutex.unlock();
249        close.wait(); // sleep until window is closed
250    }

Legend:
Removed from v.1225  
changed lines
  Added in v.1456

  ViewVC Help
Powered by ViewVC