~ubuntu-branches/debian/sid/terminatorx/sid

« back to all changes in this revision

Viewing changes to .pc/16_loose_spelling_fix.patch/src/tX_mastergui.cc

  • Committer: Package Import Robot
  • Author(s): Alessio Treglia
  • Date: 2012-04-02 02:12:47 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20120402021247-0vu81d42019x18s7
Tags: 3.84-1
* New maintainer. (Closes: #660434)
* ACK NMUs (Closes: #515716)
* New upstream release (Closes: #612760):
  - introduced a workaround for terminatorX bug #29 (Closes: #637007)
  - moved to terminatorX.org
  - fixed misc gcc 4.0 warnings
  - removed fastabs() implementation - it failed with gcc > 4.0
  - fixed a compilation issue (Thanks, cyril!)
  - fixed main window menu bar layout issue
  - fixed broken mouse grab (LP: #469365), grab events are now
    handled by gui thread
  - work-around gtk+ auto mnemonics
  - fixed deprecated gtk+, jack and Xorg API
* Switch to DH 7.
* Add --parallel to dh sequencer.
* Convert packaging to source format 3.0 (quilt):
  - Port patches from dpatch to quilt.
  - Drop dpatch support.
  - Incorporate direct changes to the manual in a quilt patch.
* Fix FTBFS errors "cannot convert 'gzFile_s**' to 'gzFile' for
  argument '1'".
  Thanks to Moritz Muehlenhoff for the patch. (Closes: #663053)
* Remove debian/patches/21_fix_ftbfs_binutils_gold.patch, applied upstream.
* Refresh patches.
* Replace list of negated architectures with linux-any in debian/control.
* Fix maintainer-script-without-set-e and maintainer-script-ignores-errors
  warnings.
* Remove scrollkeeper stuff, install the desktop file to
  /usr/share/applications/.
* Run autoreconf before configuring the package.
* Drop --enable-suidroot option, no longer needed.
* Compile with --as-needed.
* The buildsystem install the man page, so there's no need to call
  dh_installman.
* Add watch file.
* Update debian/copyright.
* Update Standards-Version.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    terminatorX - realtime audio scratching software
 
3
    Copyright (C) 1999-2011  Alexander König
 
4
 
 
5
    This program is free software; you can redistribute it and/or modify
 
6
    it under the terms of the GNU General Public License as published by
 
7
    the Free Software Foundation; either version 2 of the License, or
 
8
    (at your option) any later version.
 
9
 
 
10
    This program is distributed in the hope that it will be useful,
 
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
    GNU General Public License for more details.
 
14
 
 
15
    You should have received a copy of the GNU General Public License
 
16
    along with this program; if not, write to the Free Software
 
17
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
18
 
 
19
    File: tX_mastergui.cc
 
20
 
 
21
    Description: This implements the main (aka master) gtk+ GUI of terminatorX
 
22
                 It serves as a container for the vtt-guis.
 
23
*/    
 
24
 
 
25
#include <gtk/gtk.h>
 
26
#include <gdk/gdkx.h>
 
27
#include <X11/Xlib.h>
 
28
#include <math.h>
 
29
#include <unistd.h>
 
30
#include <string.h>
 
31
#include <gdk/gdkkeysyms.h>
 
32
#include "version.h"
 
33
#include "tX_global.h"
 
34
#include "tX_engine.h"
 
35
#include "tX_vttgui.h"
 
36
#include "tX_vtt.h"
 
37
#include "tX_flash.h"
 
38
#include "tX_dialog.h"
 
39
#include "tX_loaddlg.h"
 
40
#include "tX_seqpar.h"
 
41
#include "tX_pbutton.h"
 
42
#include "tX_sequencer.h"
 
43
#include "tX_mastergui.h"
 
44
#include "tX_knobloader.h"
 
45
#include "tX_glade_interface.h"
 
46
#include "tX_glade_support.h"
 
47
#include <sys/time.h>
 
48
#include <sys/wait.h>
 
49
#include "tX_midiin.h"
 
50
#include "tX_mouse.h"
 
51
 
 
52
#ifdef USE_SCHEDULER
 
53
#include <sys/resource.h>
 
54
#endif
 
55
 
 
56
#define TX_SET_ID_10 "terminatorX turntable set file - version 1.0 - data:"
 
57
#define TX_SET_ID_11 "terminatorX turntable set file - version 1.1 - data:"
 
58
#define TX_SET_ID_12 "terminatorX turntable set file - version 1.2 - data:"
 
59
#define TX_SET_ID_13 "terminatorX turntable set file - version 1.3 - data:"
 
60
#define TX_SET_ID_14 "terminatorX turntable set file - version 1.4 - data:"
 
61
 
 
62
int audioon=0;
 
63
int sequencer_ready=1;
 
64
 
 
65
bool tX_shutdown=false;
 
66
tx_mouse mouse;
 
67
 
 
68
GtkWidget *tt_parent;
 
69
GtkWidget *control_parent;
 
70
GtkWidget *audio_parent;
 
71
GtkWidget *main_window;
 
72
GtkWidget *grab_button;
 
73
GtkWidget *main_flash;
 
74
 
 
75
GtkWidget *seq_rec_btn;
 
76
GtkWidget *seq_play_btn;
 
77
GtkWidget *seq_stop_btn;
 
78
GtkAdjustment *seq_adj;
 
79
GtkWidget *seq_slider;
 
80
GtkWidget *seq_entry;
 
81
GtkWidget *panel_bar;
 
82
 
 
83
int buttons_on_panel_bar=0;
 
84
 
 
85
int seq_adj_care=1;
 
86
int seq_stop_override=0;
 
87
 
 
88
GtkAdjustment *volume_adj;
 
89
GtkAdjustment *pitch_adj;
 
90
 
 
91
/* seq-pars */
 
92
tX_seqpar_master_volume sp_master_volume;
 
93
tX_seqpar_master_pitch sp_master_pitch;
 
94
 
 
95
GtkWidget *engine_btn;
 
96
 
 
97
GtkWidget *main_menubar;
 
98
GtkWidget *rec_menu_item;
 
99
GtkWidget *fullscreen_item;
 
100
 
 
101
int rec_dont_care=0;
 
102
gint update_tag;
 
103
 
 
104
#define connect_entry(wid, func, ptr); g_signal_connect(G_OBJECT(wid), "activate", (GtkSignalFunc) func, (void *) ptr);
 
105
#define connect_adj(wid, func, ptr); g_signal_connect(G_OBJECT(wid), "value_changed", (GtkSignalFunc) func, (void *) ptr);
 
106
#define connect_button(wid, func, ptr); g_signal_connect(G_OBJECT(wid), "clicked", (GtkSignalFunc) func, (void *) ptr);
 
107
 
 
108
Window x_window;
 
109
GdkWindow* top_window;
 
110
#define WID_DYN TRUE, TRUE, 0
 
111
#define WID_FIX FALSE, FALSE, 0
 
112
extern void add_vtt(GtkWidget *ctrl, GtkWidget *audio, char *fn);
 
113
extern void destroy_gui(vtt_class *vtt);
 
114
extern void gui_show_frame(vtt_class *vtt, int show);
 
115
 
 
116
#ifndef USE_FILECHOOSER
 
117
GdkWindow *save_dialog_win=NULL;
 
118
GdkWindow *load_dialog_win=NULL;
 
119
 
 
120
GtkWidget *save_dialog=NULL;
 
121
GtkWidget *load_dialog=NULL;
 
122
#endif
 
123
 
 
124
GdkWindow *rec_dialog_win=NULL;
 
125
GtkWidget *rec_dialog=NULL;
 
126
 
 
127
//GtkWidget *no_of_vtts=NULL;
 
128
GtkWidget *used_mem=NULL;
 
129
 
 
130
int stop_update=0;
 
131
int update_delay;
 
132
 
 
133
vtt_class *old_focus=NULL;
 
134
 
 
135
int grab_status=0;
 
136
int last_grab_status=0;
 
137
 
 
138
GtkWidget *delete_all_item=NULL;
 
139
GtkWidget *delete_all_vtt_item=NULL;
 
140
 
 
141
GtkTooltips *gui_tooltips=NULL;
 
142
 
 
143
void gui_set_tooltip(GtkWidget *wid, const char *tip)
 
144
{
 
145
        gtk_tooltips_set_tip(gui_tooltips, wid, tip, NULL);
 
146
}
 
147
 
 
148
void turn_audio_off(void)
 
149
{
 
150
        if (audioon) {
 
151
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(engine_btn), 0);
 
152
                while (gtk_events_pending()) gtk_main_iteration();              
 
153
        }
 
154
}
 
155
 
 
156
gint pos_update(gpointer data)
 
157
{
 
158
        f_prec temp,temp2;
 
159
 
 
160
        if (stop_update) {              
 
161
                cleanup_all_vtts();
 
162
                tX_seqpar :: update_all_graphics();
 
163
                if (old_focus) gui_show_frame(old_focus, 0);
 
164
                old_focus=NULL;
 
165
                gtk_tx_flash_clear(main_flash);
 
166
                gdk_flush();    
 
167
                update_tag=0;
 
168
                return FALSE;
 
169
        } else {
 
170
                update_all_vtts();
 
171
                
 
172
                /*main vu meter */
 
173
                temp=vtt_class::mix_max_l;
 
174
                vtt_class::mix_max_l=0;
 
175
                temp2=vtt_class::mix_max_r;
 
176
                vtt_class::mix_max_r=0;
 
177
                gtk_tx_flash_set_level(main_flash, temp/FL_SHRT_MAX, temp2/FL_SHRT_MAX);
 
178
 
 
179
                if (vtt_class::focused_vtt!=old_focus) {
 
180
                        if (old_focus) gui_show_frame(old_focus, 0);
 
181
                        old_focus=vtt_class::focused_vtt;
 
182
                        if (old_focus) gui_show_frame(old_focus, 1);                    
 
183
                }
 
184
 
 
185
                grab_status = mouse.is_grabbed();
 
186
 
 
187
                if (grab_status!=last_grab_status) {
 
188
                        last_grab_status=grab_status;
 
189
                        if (!grab_status) {
 
190
                                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(grab_button), 0);
 
191
                        }
 
192
                }
 
193
                gdk_flush();    
 
194
                update_delay--;
 
195
                
 
196
                if (update_delay < 0) {
 
197
                        seq_update();
 
198
                        tX_seqpar::update_all_graphics();
 
199
                        update_delay=globals.update_delay;
 
200
                }
 
201
                
 
202
                if (tX_engine::get_instance()->check_error()) {
 
203
                        tX_error("ouch - error while playback...");
 
204
                        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(engine_btn), 0);                 
 
205
                        return FALSE;
 
206
                }               
 
207
                
 
208
                // let the audio engine we got the chance to do something
 
209
                tX_engine::get_instance()->reset_cycles_ctr();
 
210
                
 
211
                return TRUE;
 
212
        }
 
213
}
 
214
 
 
215
#define TX_MEMTAG "VmData:"
 
216
 
 
217
void mg_update_status()
 
218
{
 
219
        FILE *procfs;
 
220
        pid_t mypid;
 
221
        char filename[PATH_MAX];
 
222
        char buffer[256];
 
223
        int found=0;    
 
224
        int mem;
 
225
        
 
226
        mypid=getpid();
 
227
        sprintf(filename, "/proc/%i/status", mypid);
 
228
        procfs=fopen(filename, "r");
 
229
        if (procfs) {
 
230
                while((!feof(procfs)) && !found) {
 
231
                        char *res = fgets(buffer, 256, procfs);
 
232
                        
 
233
                        if (strncmp(TX_MEMTAG, buffer, sizeof(TX_MEMTAG)-1)==0) {
 
234
                                found=1;
 
235
                                sscanf(buffer, TX_MEMTAG" %i kB", &mem);
 
236
                                sprintf(buffer, "%.1lf M", ((double) mem)/1024.0);
 
237
                                gtk_label_set_text(GTK_LABEL(used_mem), buffer);
 
238
                        }
 
239
                }
 
240
                fclose(procfs); 
 
241
        } else {
 
242
                gtk_label_set_text(GTK_LABEL(used_mem), "");
 
243
        }
 
244
        
 
245
        /*sprintf(buffer, "%i", vtt_class::vtt_amount);
 
246
        gtk_label_set_text(GTK_LABEL(no_of_vtts), buffer);*/
 
247
}
 
248
 
 
249
GtkSignalFunc new_table(GtkWidget *, char *fn)
 
250
{
 
251
        //turn_audio_off();
 
252
                
 
253
        if (fn) {
 
254
                ld_create_loaddlg(TX_LOADDLG_MODE_SINGLE, 1);
 
255
                ld_set_filename(fn);
 
256
        }
 
257
        
 
258
        add_vtt(control_parent, audio_parent, fn);                              
 
259
        
 
260
        if (fn) ld_destroy();           
 
261
        mg_update_status();
 
262
        
 
263
#ifdef USE_ALSA_MIDI_IN
 
264
        if (globals.auto_assign_midi) tX_midiin::auto_assign_midi_mappings(NULL, NULL);
 
265
#endif
 
266
        
 
267
        return NULL;
 
268
}
 
269
 
 
270
bool tx_mg_have_setname=false;
 
271
char tx_mg_current_setname[PATH_MAX]="";
 
272
 
 
273
GtkSignalFunc new_tables() {
 
274
        GtkWidget *dialog=gtk_message_dialog_new(GTK_WINDOW(main_window), 
 
275
                GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
 
276
                "Are you sure you want to loose all turntables and events?");
 
277
        
 
278
        int res=gtk_dialog_run(GTK_DIALOG(dialog));
 
279
        gtk_widget_destroy(dialog);
 
280
                
 
281
        if (res!=GTK_RESPONSE_YES) {
 
282
                return NULL;
 
283
        }
 
284
 
 
285
        vtt_class::delete_all();
 
286
        new_table(NULL, NULL);
 
287
 
 
288
#ifdef USE_ALSA_MIDI_IN
 
289
        if (globals.auto_assign_midi) tX_midiin::auto_assign_midi_mappings(NULL, NULL);
 
290
#endif
 
291
        
 
292
        gtk_window_set_title(GTK_WINDOW(main_window), "terminatorX");
 
293
 
 
294
        return NULL;
 
295
}
 
296
 
 
297
/* Loading saved setups */
 
298
#ifndef USE_FILECHOOSER
 
299
GtkSignalFunc cancel_load_tables(GtkWidget *wid)
 
300
{
 
301
        gtk_widget_destroy(load_dialog);
 
302
        load_dialog=NULL;
 
303
        load_dialog_win=NULL;
 
304
        return(0);
 
305
}
 
306
#endif
 
307
 
 
308
void load_tt_part(char * buffer)
 
309
{
 
310
        char wbuf[PATH_MAX];
 
311
        xmlDocPtr doc;
 
312
#ifdef ENABLE_TX_LEGACY
 
313
        FILE *in;
 
314
#endif  
 
315
        turn_audio_off();
 
316
        
 
317
        strncpy(globals.tables_filename, buffer, sizeof(globals.tables_filename));
 
318
        
 
319
        doc = xmlParseFile(buffer);
 
320
        if (doc) {
 
321
                vtt_class::load_all(doc, buffer);
 
322
                xmlFreeDoc(doc);
 
323
        } 
 
324
        
 
325
#ifdef ENABLE_TX_LEGACY
 
326
        else {  
 
327
                in=fopen(buffer, "r");  
 
328
        
 
329
                if (in) {
 
330
                        char idbuff[256];
 
331
                        
 
332
                        fread(idbuff, strlen(TX_SET_ID_10), 1, in);
 
333
                        if (strncmp(idbuff, TX_SET_ID_10, strlen(TX_SET_ID_10))==0) {
 
334
                                if (vtt_class::load_all_10(in, buffer)) tx_note("Error while reading set.", true);
 
335
                        } else if (strncmp(idbuff, TX_SET_ID_11, strlen(TX_SET_ID_11))==0)      {
 
336
                                if (vtt_class::load_all_11(in, buffer)) tx_note("Error while reading set.", true);                      
 
337
                        } else if (strncmp(idbuff, TX_SET_ID_12, strlen(TX_SET_ID_12))==0) {
 
338
                                if (vtt_class::load_all_12(in, buffer)) tx_note("Error while reading set.", true);                      
 
339
                        } else if (strncmp(idbuff, TX_SET_ID_13, strlen(TX_SET_ID_13))==0) {
 
340
                                if (vtt_class::load_all_13(in, buffer)) tx_note("Error while reading set.", true);                      
 
341
                        } else if (strncmp(idbuff, TX_SET_ID_14, strlen(TX_SET_ID_14))==0) {
 
342
                                if (vtt_class::load_all_14(in, buffer)) tx_note("Error while reading set.", true);                      
 
343
                        }       else {
 
344
                                tx_note("This file is not a terminatorX set-file.", true);
 
345
                                fclose(in);
 
346
                                return;
 
347
                        }
 
348
                        fclose(in);     
 
349
                } else {
 
350
                        char message[PATH_MAX+256];
 
351
                        sprintf(message, "Failed to acesss file: \"%s\"", globals.tables_filename);
 
352
                        tx_note(message, true);
 
353
                        
 
354
                        return;
 
355
                }
 
356
        }
 
357
#else
 
358
        else {
 
359
                char message[PATH_MAX+256];
 
360
                sprintf(message, "Failed to acesss file: \"%s\"", globals.tables_filename);
 
361
                tx_note(message, true);
 
362
                
 
363
                return;
 
364
        }
 
365
#endif  
 
366
        
 
367
        tx_mg_have_setname=true;
 
368
        strcpy(tx_mg_current_setname, buffer);
 
369
        
 
370
        tX_seqpar :: init_all_graphics();
 
371
        vg_init_all_non_seqpars();
 
372
                
 
373
        gtk_adjustment_set_value(volume_adj, globals.volume);
 
374
        gtk_adjustment_set_value(pitch_adj, globals.pitch);
 
375
        sprintf(wbuf,"terminatorX - %s", strip_path(buffer));
 
376
#ifdef USE_ALSA_MIDI_IN
 
377
        if (globals.auto_assign_midi) tX_midiin::auto_assign_midi_mappings(NULL, NULL);
 
378
#endif  
 
379
        gtk_window_set_title(GTK_WINDOW(main_window), wbuf);            
 
380
}
 
381
 
 
382
#ifndef USE_FILECHOOSER
 
383
void do_load_tables(GtkWidget *wid)
 
384
{
 
385
        char buffer[PATH_MAX];
 
386
        
 
387
        strcpy(buffer, gtk_file_selection_get_filename(GTK_FILE_SELECTION(load_dialog)));
 
388
        
 
389
        gtk_widget_destroy(load_dialog);
 
390
        
 
391
        load_dialog=NULL;
 
392
        load_dialog_win=NULL;
 
393
 
 
394
        tX_cursor::set_cursor(tX_cursor::WAIT_CURSOR);
 
395
        load_tt_part(buffer);
 
396
        tX_cursor::reset_cursor();
 
397
}
 
398
#endif
 
399
 
 
400
GtkSignalFunc load_tables()
 
401
{
 
402
#ifdef USE_FILECHOOSER  
 
403
        GtkWidget * dialog = gtk_file_chooser_dialog_new ("Open Set File",
 
404
                GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_OPEN,
 
405
                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,  
 
406
            GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, NULL);
 
407
                                      
 
408
 
 
409
        GtkFileFilter *filter=gtk_file_filter_new();
 
410
        gtk_file_filter_add_pattern (filter, "*.tX");
 
411
        gtk_file_filter_add_pattern (filter, "*.tx");
 
412
        gtk_file_filter_set_name(filter, "terminatorX Set Files");
 
413
        gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); 
 
414
 
 
415
        filter=gtk_file_filter_new();
 
416
        gtk_file_filter_add_pattern (filter, "*");
 
417
        gtk_file_filter_set_name(filter, "All Files");
 
418
        gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), filter); 
 
419
        
 
420
        if (strlen(globals.tables_filename)) {
 
421
                gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), globals.tables_filename);
 
422
        }       
 
423
        
 
424
        if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
 
425
        char * filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
 
426
                gtk_widget_hide(dialog);
 
427
                tX_cursor::set_cursor(tX_cursor::WAIT_CURSOR);
 
428
                load_tt_part(filename);
 
429
                tX_cursor::reset_cursor();              
 
430
        }       
 
431
        
 
432
        gtk_widget_destroy(dialog);
 
433
#else
 
434
        if (load_dialog_win) {
 
435
                gdk_window_raise(load_dialog_win);
 
436
                return 0;
 
437
        }
 
438
 
 
439
        load_dialog=gtk_file_selection_new("Load Set"); 
 
440
        
 
441
        gtk_file_selection_show_fileop_buttons(GTK_FILE_SELECTION(load_dialog));
 
442
        gtk_file_selection_complete(GTK_FILE_SELECTION(load_dialog), "*.tX");
 
443
        
 
444
        if (strlen(globals.tables_filename)) {
 
445
                gtk_file_selection_set_filename(GTK_FILE_SELECTION(load_dialog), globals.tables_filename);
 
446
        }
 
447
        
 
448
        gtk_widget_show(load_dialog);
 
449
        
 
450
        load_dialog_win=load_dialog->window;
 
451
        
 
452
        g_signal_connect (G_OBJECT(GTK_FILE_SELECTION(load_dialog)->ok_button), "clicked", G_CALLBACK(do_load_tables), NULL);
 
453
        g_signal_connect (G_OBJECT(GTK_FILE_SELECTION(load_dialog)->cancel_button), "clicked", G_CALLBACK (cancel_load_tables), NULL);  
 
454
        g_signal_connect (G_OBJECT(load_dialog), "delete-event", G_CALLBACK(cancel_load_tables), NULL); 
 
455
        
 
456
#endif
 
457
 
 
458
        return NULL;
 
459
}
 
460
 
 
461
vtt_class* choose_vtt() {
 
462
        GtkWidget *dialog = gtk_dialog_new_with_buttons("Select Turntable",
 
463
                GTK_WINDOW(main_window), GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
 
464
                GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL);       
 
465
 
 
466
        GtkWidget *label = gtk_label_new ("Select turntable to load audio file to:");
 
467
        gtk_widget_show(label);
 
468
        gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), label);
 
469
        gtk_container_set_border_width(GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), 10);
 
470
        
 
471
        list <GtkWidget *> radio_buttons;
 
472
        list <vtt_class *> :: iterator iter;
 
473
        bool first = true;
 
474
        GtkWidget *radio;
 
475
        vtt_class *res_vtt = NULL;
 
476
        
 
477
        pthread_mutex_lock(&vtt_class::render_lock);
 
478
        
 
479
        for (iter = vtt_class::main_list.begin(); iter!=vtt_class::main_list.end(); iter++)  {
 
480
                if (first) {
 
481
                        first = false;
 
482
                        radio = gtk_radio_button_new_with_label(NULL, (*iter)->name);
 
483
                } else {
 
484
                        radio = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(radio), (*iter)->name);
 
485
                }
 
486
                g_object_set_data(G_OBJECT(radio), "tX_vtt", (*iter));
 
487
                gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), radio);
 
488
                gtk_widget_show(radio);
 
489
                radio_buttons.push_back(radio);
 
490
        }       
 
491
        
 
492
        pthread_mutex_unlock(&vtt_class::render_lock);
 
493
        
 
494
        // Giving up the lock here is necessary if we want audio to keep running
 
495
        // however it is also wrong. Anyway as it is a modal dialog not too many
 
496
        // evil things can happen. This sounds like some famous last words...
 
497
        
 
498
        gint result = gtk_dialog_run (GTK_DIALOG (dialog));
 
499
        
 
500
        if (result == GTK_RESPONSE_ACCEPT) {
 
501
                list <GtkWidget *> :: iterator radio;
 
502
                
 
503
                for (radio = radio_buttons.begin(); radio!=radio_buttons.end(); radio++) {
 
504
                        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON((*radio)))) {
 
505
                                res_vtt = (vtt_class*) g_object_get_data(G_OBJECT(*radio), "tX_vtt");
 
506
                        }
 
507
                }
 
508
        } 
 
509
        
 
510
        gtk_widget_destroy(dialog);
 
511
        
 
512
        return res_vtt;
 
513
}
 
514
 
 
515
 
 
516
GtkSignalFunc load_audio() {
 
517
        vtt_class *vtt = NULL;
 
518
        
 
519
        pthread_mutex_lock(&vtt_class::render_lock);
 
520
        if (vtt_class::main_list.size()==1) {
 
521
                vtt=(* vtt_class::main_list.begin());
 
522
        }
 
523
        pthread_mutex_unlock(&vtt_class::render_lock);
 
524
        
 
525
        if (vtt==NULL) {
 
526
                vtt = choose_vtt();
 
527
        }
 
528
        
 
529
        if (vtt!=NULL) load_file(NULL, vtt);
 
530
        
 
531
        return NULL;
 
532
}
 
533
 
 
534
GtkSignalFunc drop_set(GtkWidget *widget, GdkDragContext *context,
 
535
                gint x, gint y, GtkSelectionData *selection_data,
 
536
                guint info, guint time, vtt_class *vtt)
 
537
{
 
538
        char filename[PATH_MAX];
 
539
        char *fn;
 
540
        
 
541
        strncpy(filename, (char *) selection_data->data, (size_t) selection_data->length);
 
542
        filename[selection_data->length]=0;
 
543
 
 
544
        fn = strchr (filename, '\r');
 
545
        *fn=0;  
 
546
        
 
547
        fn = strchr (filename, ':');
 
548
        if (fn) fn++; else fn=(char *) selection_data->data;
 
549
        
 
550
        load_tt_part(fn);
 
551
 
 
552
        strcpy (filename, "dont segfault workaround ;)");
 
553
        return NULL;
 
554
}
 
555
 
 
556
/* save tables */
 
557
 
 
558
#ifndef USE_FILECHOOSER
 
559
GtkSignalFunc cancel_save_tables(GtkWidget *wid)
 
560
{
 
561
        gtk_widget_destroy(save_dialog);
 
562
        save_dialog=NULL;
 
563
        save_dialog_win=NULL;
 
564
        return(0);
 
565
}
 
566
 
 
567
gboolean do_save_from_selection(GtkWidget *wid) {
 
568
        char buffer[PATH_MAX];
 
569
        
 
570
        if (wid) {
 
571
                strcpy(buffer, gtk_file_selection_get_filename(GTK_FILE_SELECTION(save_dialog)));
 
572
                int len=strlen(buffer);
 
573
                if (!len || (buffer[len-1]=='/')) {                     
 
574
                        tx_note("Invalid filename for set file.", true);                        
 
575
                        return FALSE;
 
576
                }
 
577
                gtk_widget_destroy(save_dialog);
 
578
                save_dialog=NULL;
 
579
                save_dialog_win=NULL;
 
580
        } else {
 
581
                strcpy(buffer, tx_mg_current_setname);
 
582
        }       
 
583
        
 
584
        do_save_tables(buffer);
 
585
        
 
586
        return TRUE;
 
587
}
 
588
#endif
 
589
 
 
590
void do_save_tables(char *buffer)
 
591
{
 
592
        FILE *out;
 
593
        gzFile zout;
 
594
        char wbuf[PATH_MAX];
 
595
        char *ext;
 
596
        
 
597
        ext=strrchr(buffer, '.');
 
598
        
 
599
        if (ext) {
 
600
                if (strcmp(ext, ".tX")) strcat(buffer, ".tX");
 
601
        } else {
 
602
                strcat(buffer, ".tX");
 
603
        }
 
604
 
 
605
        tx_mg_have_setname=true;
 
606
        strcpy(tx_mg_current_setname, buffer);
 
607
        strcpy(globals.tables_filename, buffer);
 
608
        
 
609
        if (globals.compress_set_files) {
 
610
                _store_compress_xml=1;
 
611
                out=NULL;
 
612
                zout=gzopen(buffer, "w");
 
613
        } else {
 
614
                _store_compress_xml=0;
 
615
                out=fopen(buffer, "w");
 
616
                zout=NULL;
 
617
        }
 
618
        
 
619
        if (out || zout) {
 
620
                if (vtt_class::save_all(out, zout)) tx_note("Error while saving set.", true);
 
621
                if (out) fclose(out); 
 
622
                else if (zout) gzclose(zout);
 
623
                sprintf(wbuf,"terminatorX - %s", strip_path(buffer));
 
624
                gtk_window_set_title(GTK_WINDOW(main_window), wbuf);                            
 
625
        } else {
 
626
                tx_note("Failed to open file for write access.", true);
 
627
        }
 
628
}
 
629
 
 
630
GtkSignalFunc save_tables_as()
 
631
{
 
632
#ifdef USE_FILECHOOSER
 
633
        GtkWidget * dialog = gtk_file_chooser_dialog_new ("Save Set",
 
634
                GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_SAVE, 
 
635
                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 
 
636
                GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,NULL);
 
637
        
 
638
        if (tx_mg_have_setname) {
 
639
                gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), tx_mg_current_setname);
 
640
        }
 
641
                                      
 
642
        if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
 
643
        char buffer[PATH_MAX];
 
644
                char *filename=gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
 
645
                strcpy(buffer, filename);
 
646
                g_free(filename);
 
647
                do_save_tables(buffer);
 
648
        }       
 
649
        
 
650
        gtk_widget_destroy(dialog);     
 
651
#else
 
652
        if (save_dialog_win) {
 
653
                gtk_widget_destroy(save_dialog);
 
654
                save_dialog=NULL;
 
655
                save_dialog_win=NULL;
 
656
        }
 
657
        
 
658
        save_dialog=gtk_file_selection_new("Save Set"); 
 
659
 
 
660
        if (tx_mg_have_setname) {
 
661
                gtk_file_selection_set_filename(GTK_FILE_SELECTION(save_dialog), tx_mg_current_setname);
 
662
        }
 
663
        
 
664
        gtk_widget_show(save_dialog);
 
665
        
 
666
        save_dialog_win=save_dialog->window;
 
667
        
 
668
        g_signal_connect (G_OBJECT(GTK_FILE_SELECTION(save_dialog)->ok_button), "clicked", G_CALLBACK(do_save_from_selection), NULL);
 
669
        g_signal_connect (G_OBJECT(GTK_FILE_SELECTION(save_dialog)->cancel_button), "clicked", G_CALLBACK (cancel_save_tables), NULL);  
 
670
        g_signal_connect (G_OBJECT(save_dialog), "delete-event", G_CALLBACK(cancel_save_tables), NULL); 
 
671
#endif
 
672
        return NULL;
 
673
}
 
674
 
 
675
GtkSignalFunc save_tables()
 
676
{
 
677
        if (!tx_mg_have_setname) {
 
678
                save_tables_as();
 
679
        } else {
 
680
                do_save_tables(tx_mg_current_setname);
 
681
        }
 
682
        
 
683
        return NULL;
 
684
}
 
685
 
 
686
GtkSignalFunc master_volume_changed (GtkWidget *wid, void *d)
 
687
{
 
688
        sp_master_volume.receive_gui_value((float) GTK_ADJUSTMENT(wid)->value);
 
689
        return NULL;    
 
690
}
 
691
 
 
692
GtkSignalFunc master_pitch_changed(GtkWidget *wid, void *d)
 
693
{
 
694
        sp_master_pitch.receive_gui_value((float) GTK_ADJUSTMENT(wid)->value);  
 
695
        return NULL;    
 
696
}
 
697
 
 
698
void mg_enable_critical_buttons(int enable)
 
699
{
 
700
        gtk_widget_set_sensitive(seq_rec_btn, enable);
 
701
        gtk_widget_set_sensitive(seq_play_btn, enable);
 
702
        gtk_widget_set_sensitive(seq_slider, enable);
 
703
 
 
704
        gtk_widget_set_sensitive(rec_menu_item, enable);
 
705
        gtk_widget_set_sensitive(delete_all_item, enable);
 
706
        gtk_widget_set_sensitive(delete_all_vtt_item, enable);
 
707
        
 
708
        vg_enable_critical_buttons(enable);
 
709
}
 
710
 
 
711
GtkSignalFunc seq_stop(GtkWidget *w, void *);
 
712
 
 
713
static bool stop_override=false;
 
714
 
 
715
GtkSignalFunc audio_on(GtkWidget *w, void *d)
 
716
{
 
717
        tX_engine_error res;
 
718
        
 
719
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) {               
 
720
                sequencer_ready=0;
 
721
                mg_enable_critical_buttons(0);
 
722
                res=tX_engine::get_instance()->run();
 
723
 
 
724
                if (res!=NO_ERROR) {
 
725
                        mg_enable_critical_buttons(1);
 
726
                        stop_override=true;
 
727
                        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 0);
 
728
                        stop_override=false;                    
 
729
 
 
730
                        switch(res) {
 
731
                                case ERROR_BUSY:
 
732
                                tx_note("Error starting engine: engine is already running.", true);
 
733
                                break;
 
734
                                case ERROR_AUDIO:
 
735
                                tx_note("Error starting engine: failed to access audiodevice.\nPlease check the audio device settings in the \"Preferences\" dialog.", true);
 
736
                                break;
 
737
                                case ERROR_TAPE:
 
738
                                tx_note("Error starting engine: failed to open the recording file.", true);
 
739
                                break;
 
740
                                default:tx_note("Error starting engine: Unknown error.", true);
 
741
                        }
 
742
                        
 
743
                        return 0;
 
744
                }
 
745
                
 
746
                sequencer_ready=1;
 
747
                stop_update=0;
 
748
                audioon=1;
 
749
                update_delay=globals.update_delay;
 
750
                update_tag=gtk_timeout_add(globals.update_idle, (GtkFunction) pos_update, NULL);
 
751
                gtk_widget_set_sensitive(grab_button, 1);
 
752
        } else {        
 
753
                if (stop_override) return NULL;
 
754
                if (!sequencer_ready) return NULL;
 
755
                gtk_widget_set_sensitive(grab_button, 0);
 
756
                tX_engine::get_instance()->stop();
 
757
                stop_update=1;
 
758
                audioon=0;
 
759
                if (tX_engine::get_instance()->get_recording_request()) {
 
760
                        tX_engine::get_instance()->set_recording_request(false);
 
761
                        rec_dont_care=1;
 
762
                        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(rec_menu_item), 0);
 
763
                        rec_dont_care=0;
 
764
                }
 
765
                
 
766
                seq_stop(NULL, NULL);
 
767
                mg_enable_critical_buttons(1);
 
768
                
 
769
                if (tX_engine::get_instance()->get_runtime_error()) {
 
770
                        tx_note("Fatal: The audio device broke down while playing\nback audio. Note that that some audio devices can not\nrecover from such a breakdown.", true);
 
771
                }
 
772
                if (tX_engine::get_instance()->get_overload_error()) {
 
773
                        tx_note("Fatal: The audio engine was stopped due to an overload\ncondition. Try reducing the amount of plugins or\nturntables.", true);
 
774
                }
 
775
        }
 
776
        
 
777
        return NULL;
 
778
}
 
779
 
 
780
GtkSignalFunc cancel_rec(GtkWidget *wid)
 
781
{
 
782
        gtk_widget_destroy(rec_dialog);
 
783
        rec_dialog=NULL;
 
784
        rec_dialog_win=NULL;
 
785
        rec_dont_care=0;
 
786
        return(0);
 
787
}
 
788
 
 
789
void do_rec(GtkWidget *wid)
 
790
{
 
791
        char buffer[PATH_MAX];
 
792
        
 
793
        strcpy(buffer, gtk_file_selection_get_filename(GTK_FILE_SELECTION(rec_dialog)));
 
794
 
 
795
        if (strlen(buffer)) {
 
796
                strcpy(globals.record_filename, buffer);                
 
797
                tX_engine::get_instance()->set_recording_request(true);
 
798
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(rec_menu_item), 1);
 
799
        } 
 
800
        
 
801
        rec_dont_care=0;
 
802
        
 
803
        gtk_widget_destroy(rec_dialog);
 
804
        
 
805
        rec_dialog=NULL;
 
806
        rec_dialog_win=NULL;
 
807
}
 
808
 
 
809
GtkSignalFunc select_rec_file()
 
810
{
 
811
#ifdef USE_FILECHOOSER
 
812
        GtkWidget * dialog = gtk_file_chooser_dialog_new ("Record To Disk",
 
813
                GTK_WINDOW(main_window), GTK_FILE_CHOOSER_ACTION_SAVE, 
 
814
                GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 
 
815
                GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,NULL);
 
816
        
 
817
        if (strlen(globals.record_filename)) {
 
818
                gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), globals.record_filename);
 
819
        }
 
820
                                      
 
821
        if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
 
822
                char *filename=gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
 
823
                strncpy(globals.record_filename, filename, sizeof(globals.record_filename)-1);
 
824
                g_free(filename);
 
825
                
 
826
                tX_engine::get_instance()->set_recording_request(true);
 
827
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(rec_menu_item), 1);
 
828
        } else {
 
829
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(rec_menu_item), 0);
 
830
        }
 
831
        
 
832
        rec_dont_care = 0;
 
833
        
 
834
        gtk_widget_destroy(dialog);
 
835
        
 
836
#else   
 
837
        if (rec_dialog_win) {
 
838
                gdk_window_raise(rec_dialog_win);
 
839
                return 0;
 
840
        }
 
841
        
 
842
        rec_dialog=gtk_file_selection_new("Record To Disk");    
 
843
        
 
844
        if (strlen(globals.record_filename)) {
 
845
                gtk_file_selection_set_filename(GTK_FILE_SELECTION(rec_dialog), globals.record_filename);
 
846
        }
 
847
        
 
848
        gtk_widget_show(rec_dialog);
 
849
        
 
850
        rec_dialog_win=rec_dialog->window;
 
851
        
 
852
        g_signal_connect (G_OBJECT(GTK_FILE_SELECTION(rec_dialog)->ok_button), "clicked", G_CALLBACK(do_rec), NULL);
 
853
        g_signal_connect (G_OBJECT(GTK_FILE_SELECTION(rec_dialog)->cancel_button), "clicked", G_CALLBACK (cancel_rec), NULL);   
 
854
        g_signal_connect (G_OBJECT(rec_dialog), "delete-event", G_CALLBACK(cancel_rec), NULL);  
 
855
        
 
856
#endif
 
857
 
 
858
        return NULL;
 
859
}
 
860
 
 
861
GtkSignalFunc tape_on(GtkWidget *w, void *d)
 
862
{
 
863
        if (rec_dont_care) return 0;
 
864
 
 
865
        if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(w))) {   
 
866
                rec_dont_care=1;
 
867
                gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(w), 0);
 
868
                select_rec_file();
 
869
        } else {
 
870
                        tX_engine::get_instance()->set_recording_request(false);
 
871
        }
 
872
        
 
873
        return NULL;
 
874
}
 
875
 
 
876
void grab_on(GtkWidget *w, void *d)
 
877
{
 
878
        if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w))) {
 
879
                if (mouse.grab() != 0) {
 
880
                        //tX_engine::get_instance()->set_grab_request();
 
881
                        // TODO: handle error
 
882
                }
 
883
        }
 
884
        grab_status=1;
 
885
}
 
886
 
 
887
void grab_off()
 
888
{
 
889
        grab_status=0;
 
890
}
 
891
 
 
892
gboolean quit()
 
893
{       
 
894
        if (globals.quit_confirm) {
 
895
                GtkWidget *dialog=gtk_message_dialog_new(GTK_WINDOW(main_window), 
 
896
                GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
 
897
                "Exit terminatorX and loose all unsaved data?");
 
898
                
 
899
                int res=gtk_dialog_run(GTK_DIALOG(dialog));
 
900
                gtk_widget_destroy(dialog);
 
901
                        
 
902
                if (res!=GTK_RESPONSE_YES) {
 
903
                        return TRUE;
 
904
                }
 
905
        }
 
906
        
 
907
        tX_shutdown=true;
 
908
        
 
909
        turn_audio_off();
 
910
        vtt_class::delete_all();
 
911
 
 
912
        if (update_tag)
 
913
        gtk_timeout_remove(update_tag);
 
914
        globals.width=main_window->allocation.width;
 
915
        globals.height=main_window->allocation.height;
 
916
 
 
917
        gtk_main_quit();
 
918
        
 
919
        return true;
 
920
}
 
921
 
 
922
void mplcfitx()
 
923
/* Most Probably Least Called Function In terminatorX :) */
 
924
{
 
925
        show_about(0);
 
926
}
 
927
 
 
928
GtkSignalFunc seq_play(GtkWidget *w, void *)
 
929
{
 
930
        if ((sequencer.is_empty()) &&   (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(seq_rec_btn)))) {
 
931
                if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w)))
 
932
                 {
 
933
                        tx_note("Sequencer playback triggered - but no events recorded yet - nothing to playback!\n\nTo perform live with terminatorX just activate the audio engine with the \"Power\" button.");
 
934
                        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 0);
 
935
                 }
 
936
        } else {
 
937
                if (seq_stop_override) return NULL;
 
938
                        
 
939
                seq_adj_care=0;
 
940
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 1);
 
941
                sequencer.trig_play();
 
942
        
 
943
                gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(engine_btn), 1);
 
944
        }
 
945
        
 
946
        return NULL;
 
947
}
 
948
 
 
949
GtkSignalFunc seq_stop(GtkWidget *w, void *)
 
950
{
 
951
        if (!sequencer_ready) return NULL;
 
952
        sequencer.trig_stop();
 
953
        seq_adj_care=1;
 
954
        seq_stop_override=1;
 
955
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(seq_play_btn), 0);
 
956
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(seq_rec_btn), 0);
 
957
        while (gtk_events_pending()) gtk_main_iteration();              
 
958
        seq_stop_override=0;
 
959
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(engine_btn), 0); 
 
960
        gtk_widget_set_sensitive(seq_slider, 1);        
 
961
        gtk_widget_set_sensitive(engine_btn, 1);
 
962
        gtk_widget_set_sensitive(seq_rec_btn, 1);
 
963
 
 
964
        return NULL;
 
965
}
 
966
 
 
967
GtkSignalFunc seq_rec(GtkWidget *w, void *)
 
968
{
 
969
        seq_adj_care=0;
 
970
        gtk_widget_set_sensitive(seq_slider, 0);
 
971
 
 
972
        if (seq_stop_override) return NULL;
 
973
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w), 1);
 
974
        gtk_widget_set_sensitive(engine_btn, 0);
 
975
        gtk_widget_set_sensitive(seq_rec_btn, 0);
 
976
        sequencer.trig_rec();
 
977
        
 
978
        return NULL;
 
979
}
 
980
 
 
981
void seq_update_entry(const guint32 timestamp)
 
982
{
 
983
        char buffer[20];
 
984
        guint32 samples;
 
985
        guint32 minu,sec,hun;   
 
986
        guint32 sr;
 
987
        
 
988
        samples=timestamp*vtt_class::get_mix_buffer_size();
 
989
        sr=vtt_class::get_last_sample_rate();
 
990
        
 
991
        if (samples>0) {
 
992
                minu=samples/(sr*60);
 
993
                samples-=(sr*60)*minu;
 
994
        
 
995
                sec=samples/sr;
 
996
                samples-=sr*sec;
 
997
        
 
998
                hun=samples/(sr/100);
 
999
        } else {
 
1000
                minu=sec=hun=0;
 
1001
        }
 
1002
        
 
1003
        sprintf(buffer, "%02i:%02i.%02i", minu, sec, hun);
 
1004
        gtk_entry_set_text(GTK_ENTRY(seq_entry), buffer);
 
1005
}
 
1006
 
 
1007
void seq_update()
 
1008
{
 
1009
        seq_update_entry(sequencer.get_timestamp());
 
1010
        gtk_adjustment_set_value(seq_adj, sequencer.get_timestamp_as_float());
 
1011
        
 
1012
}
 
1013
gboolean seq_slider_released(GtkWidget *wid, void *d)
 
1014
{
 
1015
        seq_adj_care=0;
 
1016
        gtk_widget_set_sensitive(seq_slider, 0);        
 
1017
        sequencer.forward_to_start_timestamp(0);
 
1018
        gtk_widget_set_sensitive(seq_slider, 1);        
 
1019
        seq_adj_care=1;
 
1020
        
 
1021
        return FALSE;
 
1022
}
 
1023
void sequencer_move(GtkWidget *wid, void *d)
 
1024
{
 
1025
        guint32 pos;
 
1026
        
 
1027
        if (seq_adj_care) {
 
1028
                pos=sequencer.set_start_timestamp((float) GTK_ADJUSTMENT(wid)->value);
 
1029
                seq_update_entry(pos);  
 
1030
        }
 
1031
}
 
1032
 
 
1033
#define add_sep();      dummy=gtk_hseparator_new ();\
 
1034
        gtk_box_pack_start(GTK_BOX(right_hbox), dummy, WID_FIX);\
 
1035
        gtk_widget_show(dummy);\
 
1036
 
 
1037
#define add_sep2();     dummy=gtk_hseparator_new ();\
 
1038
        gtk_box_pack_end(GTK_BOX(status_box), dummy, WID_FIX);\
 
1039
        gtk_widget_show(dummy);\
 
1040
 
 
1041
void fullscreen_toggle(GtkCheckMenuItem *item, gpointer data);
 
1042
void display_help();
 
1043
void display_browser();
 
1044
 
 
1045
tX_seqpar *del_sp=NULL;
 
1046
vtt_class *del_vtt=NULL;
 
1047
tx_menu_del_mode menu_del_mode=ALL_EVENTS_ALL_TURNTABLES;
 
1048
 
 
1049
GtkWidget *del_dialog=NULL;
 
1050
 
 
1051
GCallback menu_delete_all_events(GtkWidget *, void *param)
 
1052
{       
 
1053
        del_dialog=create_tx_del_mode();
 
1054
        tX_set_icon(del_dialog);
 
1055
        
 
1056
        GtkWidget *label=lookup_widget(del_dialog, "delmode_label");
 
1057
        
 
1058
        menu_del_mode=ALL_EVENTS_ALL_TURNTABLES;
 
1059
        
 
1060
        gtk_label_set_markup(GTK_LABEL(label), "Delete <b>all</b> events for <b>all</b> turntables.");
 
1061
        gtk_widget_show(del_dialog);
 
1062
        
 
1063
        return NULL;
 
1064
}
 
1065
 
 
1066
GCallback menu_delete_all_events_for_vtt(GtkWidget *, vtt_class *vtt)
 
1067
{       
 
1068
        if (!vtt) {
 
1069
                tX_error("No vtt passed to menu_delete_all_events_for_vtt().");
 
1070
                return FALSE;
 
1071
        }
 
1072
        
 
1073
        char label_str[512];
 
1074
        
 
1075
        del_dialog=create_tx_del_mode();
 
1076
        tX_set_icon(del_dialog);
 
1077
 
 
1078
        del_vtt=vtt;
 
1079
        GtkWidget *label=lookup_widget(del_dialog, "delmode_label");
 
1080
        
 
1081
        menu_del_mode=ALL_EVENTS_FOR_TURNTABLE;
 
1082
        
 
1083
        sprintf(label_str, "Delete <b>all</b> events for turntable <b>%s</b>.", vtt->name);
 
1084
        gtk_label_set_markup(GTK_LABEL(label), label_str);
 
1085
        gtk_widget_show(del_dialog);
 
1086
        
 
1087
        return NULL;
 
1088
}
 
1089
 
 
1090
GCallback menu_delete_all_events_for_sp(GtkWidget *, tX_seqpar *sp)
 
1091
{       
 
1092
        if (!sp) {
 
1093
                tX_error("No sp passed to menu_delete_all_events_for_sp().");
 
1094
                return FALSE;
 
1095
        }
 
1096
        
 
1097
        char label_str[512];
 
1098
        
 
1099
        del_dialog=create_tx_del_mode();
 
1100
        tX_set_icon(del_dialog);
 
1101
        
 
1102
        GtkWidget *label=lookup_widget(del_dialog, "delmode_label");
 
1103
        
 
1104
        menu_del_mode=ALL_EVENTS_FOR_SP;
 
1105
        del_sp=sp;
 
1106
        sprintf(label_str, "Delete all <b>%s</b> events for turntable '%s'.", sp->get_name(), sp->get_vtt_name());
 
1107
        gtk_label_set_markup(GTK_LABEL(label), label_str);
 
1108
        gtk_widget_show(del_dialog);
 
1109
 
 
1110
        return NULL;
 
1111
}
 
1112
 
 
1113
static GtkWidget *table_menu=NULL;
 
1114
static GtkWidget *table_menu_item=NULL;
 
1115
 
 
1116
GCallback create_table_sequencer_menu(GtkWidget *widget, void *param) 
 
1117
{
 
1118
        char label[328];
 
1119
        table_menu=gtk_menu_new();
 
1120
        
 
1121
        list <vtt_class *> :: iterator vtt;
 
1122
 
 
1123
        for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++) {
 
1124
                GtkWidget *menu_item=gtk_menu_item_new_with_label((*vtt)->name);
 
1125
                gtk_container_add (GTK_CONTAINER (table_menu), menu_item);
 
1126
                gtk_widget_show(menu_item);
 
1127
                
 
1128
                GtkWidget *seqpar_menu=gtk_menu_new();
 
1129
                list <tX_seqpar *> :: iterator sp;
 
1130
                
 
1131
                GtkWidget *all=gtk_menu_item_new_with_label("Delete All Events");
 
1132
                gtk_container_add (GTK_CONTAINER (seqpar_menu), all);
 
1133
                g_signal_connect(all, "activate", (GCallback) menu_delete_all_events_for_vtt, (*vtt));
 
1134
                gtk_widget_show(all);
 
1135
 
 
1136
                GtkWidget *sep = gtk_menu_item_new ();
 
1137
                gtk_widget_show(sep);
 
1138
                gtk_container_add(GTK_CONTAINER (seqpar_menu), sep);
 
1139
                gtk_widget_set_sensitive (sep, FALSE);
 
1140
                
 
1141
                for (sp=tX_seqpar::all->begin(); sp!=tX_seqpar::all->end(); sp++) {
 
1142
                        if ((*sp)->vtt==(*vtt)) {
 
1143
                                sprintf(label, "Delete '%s' Events", (*sp)->get_name());
 
1144
                                GtkWidget *menu_item=gtk_menu_item_new_with_label(label);
 
1145
                                g_signal_connect(menu_item, "activate", (GCallback) menu_delete_all_events_for_sp, (*sp));
 
1146
                                gtk_container_add(GTK_CONTAINER(seqpar_menu), menu_item);
 
1147
                                gtk_widget_show(menu_item);
 
1148
                        }
 
1149
                }
 
1150
                gtk_menu_item_set_submenu(GTK_MENU_ITEM(menu_item), seqpar_menu);
 
1151
        }
 
1152
        
 
1153
        gtk_menu_item_set_submenu(GTK_MENU_ITEM(table_menu_item), table_menu);
 
1154
        
 
1155
        return NULL;
 
1156
}
 
1157
 
 
1158
GCallback toggle_confirm_events(GtkWidget *widget, void *dummy)
 
1159
{       
 
1160
        globals.confirm_events=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));     
 
1161
        return NULL;    
 
1162
}
 
1163
 
 
1164
GCallback toggle_auto_assign(GtkWidget *widget, void *dummy)
 
1165
{       
 
1166
        globals.auto_assign_midi=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
 
1167
#ifdef USE_ALSA_MIDI_IN
 
1168
        tX_midiin::auto_assign_midi_mappings(NULL, NULL);
 
1169
#endif
 
1170
/*      if (globals.auto_assign_midi) {
 
1171
                GtkWidget *dialog=gtk_message_dialog_new(GTK_WINDOW(main_window), 
 
1172
                GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_WARNING, GTK_BUTTONS_YES_NO,
 
1173
                "Note: Enabling \"Auto Assign Default MIDI Settings\" will constantly overwrite the\
 
1174
MIDI mappings for the standard parameters. \
 
1175
Are you sure you really want this?");
 
1176
                
 
1177
                int res=gtk_dialog_run(GTK_DIALOG(dialog));
 
1178
                gtk_widget_destroy(dialog);
 
1179
                        
 
1180
                if (res!=GTK_RESPONSE_YES) {
 
1181
                        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), 0);
 
1182
                }                       
 
1183
        } */
 
1184
        return NULL;    
 
1185
}
 
1186
 
 
1187
void create_master_menu() 
 
1188
{
 
1189
        GtkWidget *menu_item;
 
1190
        GtkWidget *sub_menu;
 
1191
        GtkWidget *label;
 
1192
        
 
1193
        GtkAccelGroup* accel_group=gtk_accel_group_new();
 
1194
        gtk_window_add_accel_group(GTK_WINDOW(main_window), accel_group);
 
1195
 
 
1196
        /* FILE */
 
1197
        menu_item = gtk_menu_item_new_with_mnemonic ("_File");
 
1198
        gtk_widget_show (menu_item);
 
1199
        gtk_container_add (GTK_CONTAINER (main_menubar), menu_item);
 
1200
 
 
1201
        sub_menu = gtk_menu_new ();
 
1202
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
 
1203
 
 
1204
        menu_item = gtk_image_menu_item_new_from_stock ("gtk-open", accel_group);
 
1205
        label = gtk_bin_get_child(GTK_BIN(menu_item));
 
1206
        gtk_label_set_text(GTK_LABEL(label), "Load Audio File");
 
1207
        // Warning: gtk+ stock hacks ahead...
 
1208
        gtk_widget_remove_accelerator(menu_item, accel_group, GDK_O, GDK_CONTROL_MASK);
 
1209
        gtk_widget_add_accelerator (menu_item, "activate", accel_group, GDK_F, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
 
1210
        gtk_widget_show (menu_item);
 
1211
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1212
        g_signal_connect(menu_item, "activate", (GCallback) load_audio, NULL);
 
1213
 
 
1214
        menu_item = gtk_menu_item_new ();
 
1215
        gtk_widget_show (menu_item);
 
1216
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1217
        gtk_widget_set_sensitive (menu_item, FALSE);
 
1218
 
 
1219
        menu_item = gtk_image_menu_item_new_from_stock ("gtk-new", accel_group);
 
1220
        label = gtk_bin_get_child(GTK_BIN(menu_item));
 
1221
        gtk_label_set_text(GTK_LABEL(label), "New Set");
 
1222
        gtk_widget_show (menu_item);
 
1223
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1224
        g_signal_connect(menu_item, "activate", (GCallback) new_tables, NULL);
 
1225
 
 
1226
        menu_item = gtk_image_menu_item_new_from_stock ("gtk-open", accel_group);
 
1227
        label = gtk_bin_get_child(GTK_BIN(menu_item));
 
1228
        gtk_label_set_text(GTK_LABEL(label), "Open Set File");
 
1229
        gtk_widget_show (menu_item);
 
1230
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1231
        g_signal_connect(menu_item, "activate", (GCallback) load_tables, NULL);
 
1232
 
 
1233
        menu_item = gtk_image_menu_item_new_from_stock ("gtk-save", accel_group);
 
1234
        label = gtk_bin_get_child(GTK_BIN(menu_item));
 
1235
        gtk_label_set_text(GTK_LABEL(label), "Save Set");
 
1236
        gtk_widget_show (menu_item);
 
1237
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1238
        g_signal_connect(menu_item, "activate", (GCallback) save_tables, NULL);
 
1239
 
 
1240
        menu_item = gtk_image_menu_item_new_from_stock ("gtk-save-as", accel_group);
 
1241
        label = gtk_bin_get_child(GTK_BIN(menu_item));
 
1242
        gtk_label_set_text(GTK_LABEL(label), "Save Set As");
 
1243
        gtk_widget_show (menu_item);
 
1244
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1245
        g_signal_connect(menu_item, "activate", (GCallback) save_tables_as, NULL);
 
1246
 
 
1247
        menu_item = gtk_menu_item_new ();
 
1248
        gtk_widget_show (menu_item);
 
1249
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1250
        gtk_widget_set_sensitive (menu_item, FALSE);
 
1251
 
 
1252
        menu_item = gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group);
 
1253
        gtk_widget_show (menu_item);
 
1254
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1255
        g_signal_connect(menu_item, "activate", (GCallback) quit, NULL);
 
1256
 
 
1257
        /* Turntables */
 
1258
        menu_item = gtk_menu_item_new_with_mnemonic ("_Turntables");
 
1259
        gtk_widget_show (menu_item);
 
1260
        gtk_container_add (GTK_CONTAINER (main_menubar), menu_item);
 
1261
        
 
1262
        sub_menu = gtk_menu_new ();
 
1263
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
 
1264
 
 
1265
        menu_item = gtk_menu_item_new_with_mnemonic("_Add Turntable");
 
1266
        gtk_widget_show (menu_item);
 
1267
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1268
        gtk_widget_add_accelerator (menu_item, "activate", accel_group, GDK_A, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);    
 
1269
        g_signal_connect(menu_item, "activate", (GCallback) new_table, NULL);
 
1270
 
 
1271
        menu_item = gtk_menu_item_new ();
 
1272
        gtk_widget_show (menu_item);
 
1273
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1274
        gtk_widget_set_sensitive (menu_item, FALSE);
 
1275
 
 
1276
        menu_item = gtk_menu_item_new_with_mnemonic("Assign _Default MIDI Mappings");
 
1277
        gtk_widget_show (menu_item);
 
1278
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1279
        gtk_widget_add_accelerator (menu_item, "activate", accel_group, GDK_M, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
 
1280
 
 
1281
#ifdef USE_ALSA_MIDI_IN
 
1282
        g_signal_connect(menu_item, "activate", G_CALLBACK(tX_midiin::auto_assign_midi_mappings), (void *) true);
 
1283
#else
 
1284
        gtk_widget_set_sensitive(menu_item, FALSE);
 
1285
#endif
 
1286
 
 
1287
        menu_item = gtk_check_menu_item_new_with_mnemonic("A_uto Assign Default MIDI Mappings");
 
1288
        gtk_widget_show (menu_item);
 
1289
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1290
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), globals.auto_assign_midi);
 
1291
#ifdef USE_ALSA_MIDI_IN 
 
1292
        g_signal_connect(menu_item, "activate", (GCallback) toggle_auto_assign, NULL);
 
1293
#else
 
1294
        gtk_widget_set_sensitive(menu_item, FALSE);
 
1295
#endif
 
1296
 
 
1297
        menu_item = gtk_menu_item_new_with_mnemonic("_Clear MIDI Mappings");
 
1298
        gtk_widget_show (menu_item);
 
1299
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1300
        gtk_widget_add_accelerator (menu_item, "activate", accel_group, GDK_C, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
 
1301
 
 
1302
#ifdef USE_ALSA_MIDI_IN
 
1303
        g_signal_connect(menu_item, "activate", G_CALLBACK(tX_midiin::clear_midi_mappings), (void *) true);
 
1304
#else
 
1305
        gtk_widget_set_sensitive(menu_item, FALSE);
 
1306
#endif
 
1307
 
 
1308
        menu_item = gtk_menu_item_new ();
 
1309
        gtk_widget_show (menu_item);
 
1310
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1311
        gtk_widget_set_sensitive (menu_item, FALSE);
 
1312
 
 
1313
        menu_item = gtk_check_menu_item_new_with_mnemonic("_Record Audio To Disk");
 
1314
        rec_menu_item = menu_item;
 
1315
        gtk_widget_add_accelerator (menu_item, "activate", accel_group, GDK_R, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE);
 
1316
        gtk_widget_show (menu_item);
 
1317
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1318
        g_signal_connect(menu_item, "activate", (GCallback) tape_on, NULL);
 
1319
 
 
1320
        /* Sequencer */
 
1321
        
 
1322
        menu_item = gtk_menu_item_new_with_mnemonic("_Sequencer");
 
1323
        gtk_widget_show (menu_item);
 
1324
        gtk_container_add (GTK_CONTAINER (main_menubar), menu_item);
 
1325
 
 
1326
        sub_menu = gtk_menu_new ();
 
1327
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
 
1328
                
 
1329
        table_menu = gtk_menu_new();
 
1330
        menu_item = gtk_menu_item_new_with_mnemonic("Delete _Events");
 
1331
        delete_all_vtt_item = menu_item;
 
1332
        table_menu_item = menu_item;
 
1333
        gtk_menu_item_set_submenu(GTK_MENU_ITEM(table_menu_item), table_menu);
 
1334
        
 
1335
        gtk_widget_show (menu_item);
 
1336
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1337
        g_signal_connect_swapped (G_OBJECT (menu_item), "select", G_CALLBACK (create_table_sequencer_menu), NULL);
 
1338
        
 
1339
        menu_item = gtk_menu_item_new_with_mnemonic("Delete _All Events");
 
1340
        delete_all_item = menu_item;
 
1341
        gtk_widget_show (menu_item);
 
1342
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1343
        g_signal_connect(menu_item, "activate", (GCallback) menu_delete_all_events, NULL);
 
1344
 
 
1345
        menu_item = gtk_menu_item_new ();
 
1346
        gtk_widget_show (menu_item);
 
1347
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1348
        gtk_widget_set_sensitive (menu_item, FALSE);
 
1349
 
 
1350
        menu_item = gtk_check_menu_item_new_with_mnemonic("_Confirm Recorded Events");
 
1351
        //rec_menu_item = menu_item;
 
1352
        gtk_widget_show (menu_item);
 
1353
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1354
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), globals.confirm_events);
 
1355
        g_signal_connect(menu_item, "activate", (GCallback) toggle_confirm_events, NULL);
 
1356
 
 
1357
        /* Options */
 
1358
        menu_item = gtk_menu_item_new_with_mnemonic ("_Options");
 
1359
        gtk_widget_show (menu_item);
 
1360
        gtk_container_add (GTK_CONTAINER (main_menubar), menu_item);
 
1361
 
 
1362
        sub_menu = gtk_menu_new ();
 
1363
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
 
1364
                
 
1365
        menu_item = gtk_check_menu_item_new_with_mnemonic("_Fullscreen");
 
1366
        fullscreen_item = menu_item;
 
1367
        gtk_widget_show (menu_item);
 
1368
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1369
 
 
1370
        gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), globals.fullscreen_enabled);
 
1371
        gtk_widget_add_accelerator (menu_item, "activate", accel_group, GDK_F11, (GdkModifierType) 0, GTK_ACCEL_VISIBLE);
 
1372
        g_signal_connect(menu_item, "activate", (GCallback) fullscreen_toggle, NULL);
 
1373
        
 
1374
        menu_item = gtk_menu_item_new ();
 
1375
        gtk_widget_show (menu_item);
 
1376
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1377
        gtk_widget_set_sensitive (menu_item, FALSE);
 
1378
 
 
1379
        menu_item = gtk_image_menu_item_new_from_stock ("gtk-preferences", accel_group);
 
1380
        gtk_widget_show (menu_item);
 
1381
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1382
        g_signal_connect(menu_item, "activate", (GCallback) display_options, NULL);
 
1383
 
 
1384
        /* HELP */ 
 
1385
        menu_item = gtk_menu_item_new_with_mnemonic ("_Help");
 
1386
        gtk_widget_show (menu_item);
 
1387
        gtk_container_add (GTK_CONTAINER (main_menubar), menu_item);
 
1388
        gtk_menu_item_set_right_justified(GTK_MENU_ITEM(menu_item), TRUE);
 
1389
        
 
1390
        sub_menu = gtk_menu_new ();
 
1391
        gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
 
1392
 
 
1393
        menu_item = gtk_menu_item_new_with_mnemonic ("_Contents");
 
1394
        gtk_widget_show (menu_item);
 
1395
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1396
        g_signal_connect(menu_item, "activate", (GCallback) display_help, NULL);
 
1397
        gtk_widget_add_accelerator (menu_item, "activate", accel_group, GDK_F1, (GdkModifierType) 0, GTK_ACCEL_VISIBLE);
 
1398
 
 
1399
        menu_item = gtk_menu_item_new_with_mnemonic ("_About");
 
1400
        gtk_widget_show (menu_item);
 
1401
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1402
        g_signal_connect(menu_item, "activate", (GCallback) mplcfitx, NULL);
 
1403
        
 
1404
        menu_item = gtk_menu_item_new ();
 
1405
        gtk_widget_show (menu_item);
 
1406
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1407
        gtk_widget_set_sensitive (menu_item, FALSE);
 
1408
 
 
1409
        menu_item = gtk_menu_item_new_with_mnemonic ("_Visit terminatorX.org");
 
1410
        gtk_widget_show (menu_item);
 
1411
        gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
 
1412
        g_signal_connect(menu_item, "activate", (GCallback) display_browser, NULL);
 
1413
}
 
1414
 
 
1415
void create_mastergui(int x, int y)
 
1416
{
 
1417
        GtkWidget *mother_of_all_boxen;
 
1418
        GtkWidget *main_vbox;
 
1419
        GtkWidget *right_hbox;
 
1420
        GtkWidget *left_hbox;
 
1421
        GtkWidget *control_box;
 
1422
        //GtkWidget *sequencer_box;
 
1423
        GtkAdjustment *dumadj;
 
1424
        GtkWidget *dummy;
 
1425
        GtkWidget *master_vol_box;
 
1426
        GtkWidget *status_box;
 
1427
        GtkWidget *wrapbox;
 
1428
        
 
1429
        gui_tooltips=gtk_tooltips_new();
 
1430
 
 
1431
        main_window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
 
1432
 
 
1433
        gtk_window_set_wmclass(GTK_WINDOW(main_window), "terminatorX", "tX_mastergui");
 
1434
 
 
1435
        gtk_window_set_title(GTK_WINDOW(main_window), "terminatorX");
 
1436
 
 
1437
        gtk_widget_realize(main_window);
 
1438
 
 
1439
        wrapbox=gtk_vbox_new(FALSE, 5);
 
1440
        gtk_container_add(GTK_CONTAINER(main_window), wrapbox);
 
1441
        gtk_widget_show(wrapbox);
 
1442
 
 
1443
        main_menubar=gtk_menu_bar_new();
 
1444
        gtk_box_pack_start(GTK_BOX(wrapbox), main_menubar, WID_FIX);
 
1445
        gtk_widget_show(main_menubar);
 
1446
 
 
1447
        mother_of_all_boxen=gtk_vbox_new(FALSE, 5);
 
1448
        gtk_container_set_border_width(GTK_CONTAINER(mother_of_all_boxen), 5);
 
1449
        gtk_container_add(GTK_CONTAINER(wrapbox), mother_of_all_boxen);
 
1450
        gtk_widget_show(mother_of_all_boxen);   
 
1451
 
 
1452
        create_master_menu();
 
1453
 
 
1454
        g_signal_connect(G_OBJECT(main_window), "motion_notify_event", G_CALLBACK(tx_mouse::motion_notify_wrap), &mouse);
 
1455
        g_signal_connect(G_OBJECT(main_window), "button_press_event", G_CALLBACK(tx_mouse::button_press_wrap), &mouse);
 
1456
        g_signal_connect(G_OBJECT(main_window), "button_release_event", G_CALLBACK(tx_mouse::button_release_wrap), &mouse);
 
1457
        g_signal_connect(G_OBJECT(main_window), "key_press_event", G_CALLBACK(tx_mouse::key_press_wrap), &mouse);
 
1458
        g_signal_connect(G_OBJECT(main_window), "key_release_event", G_CALLBACK(tx_mouse::key_release_wrap), &mouse);
 
1459
        
 
1460
        main_vbox=gtk_hbox_new(FALSE, 5);
 
1461
        gtk_box_pack_start(GTK_BOX(mother_of_all_boxen), main_vbox, WID_DYN);
 
1462
        gtk_widget_show(main_vbox);
 
1463
        
 
1464
        left_hbox=gtk_vbox_new(FALSE, 5);
 
1465
        gtk_box_pack_start(GTK_BOX(main_vbox), left_hbox, WID_DYN);
 
1466
        gtk_widget_show(left_hbox);
 
1467
        
 
1468
        control_box=gtk_hbox_new(FALSE, 5);
 
1469
        gtk_box_pack_start(GTK_BOX(left_hbox), control_box, WID_FIX);
 
1470
        gtk_widget_show(control_box);
 
1471
        
 
1472
        dummy=gtk_hseparator_new();
 
1473
        gtk_box_pack_start(GTK_BOX(left_hbox), dummy, WID_FIX);
 
1474
        gtk_widget_show(dummy);
 
1475
 
 
1476
    /* control_box contents */
 
1477
 
 
1478
        dummy=tx_xpm_label_box(AUDIOENGINE, "Audio");
 
1479
        gtk_box_pack_start(GTK_BOX(control_box), dummy, WID_FIX);
 
1480
        gtk_widget_show(dummy);
 
1481
        
 
1482
        dummy=tx_xpm_button_new(POWER,"Power ", 1);
 
1483
        connect_button(dummy,audio_on, NULL);
 
1484
        gtk_box_pack_start(GTK_BOX(control_box), dummy, WID_FIX);
 
1485
        gui_set_tooltip(dummy, "Turn the audio engine on/off.");
 
1486
        gtk_widget_show(dummy);
 
1487
        engine_btn=dummy;
 
1488
        
 
1489
        grab_button=tx_xpm_button_new(GRAB, "Mouse Grab ", 1);
 
1490
        gtk_box_pack_start(GTK_BOX(control_box), grab_button, WID_FIX);
 
1491
        connect_button(grab_button, grab_on, NULL);
 
1492
        gui_set_tooltip(grab_button, "Enter the mouse grab mode operation. Press <ESCAPE> to exit grab mode.");
 
1493
        gtk_widget_show(grab_button);
 
1494
 
 
1495
        dummy=gtk_vseparator_new();
 
1496
        gtk_box_pack_start(GTK_BOX(control_box), dummy, WID_FIX);
 
1497
        gtk_widget_show(dummy);
 
1498
    
 
1499
        dummy=tx_xpm_label_box(SEQUENCER, "Seq.");
 
1500
        gtk_box_pack_start(GTK_BOX(control_box), dummy, WID_FIX);
 
1501
        gtk_widget_show(dummy);
 
1502
 
 
1503
        dummy=tx_xpm_button_new(PLAY,"Play ", 1);
 
1504
        connect_button(dummy, seq_play, NULL);
 
1505
        seq_play_btn=dummy;
 
1506
        gtk_box_pack_start(GTK_BOX(control_box), dummy, WID_FIX);
 
1507
        gui_set_tooltip(dummy, "Playback previously recorded events from the sequencer. This will turn on the audio engine automagically.");
 
1508
        gtk_widget_show(dummy);
 
1509
 
 
1510
        dummy=tx_xpm_button_new(STOP,"Stop ", 0);
 
1511
        seq_stop_btn=dummy;
 
1512
        connect_button(dummy, seq_stop, NULL);  
 
1513
        gtk_box_pack_start(GTK_BOX(control_box), dummy, WID_FIX);
 
1514
        gui_set_tooltip(dummy, "Stop the playback of sequencer events.");
 
1515
        gtk_widget_show(dummy);
 
1516
 
 
1517
        dummy=tx_xpm_button_new(RECORD,"Record ", 1);
 
1518
        connect_button(dummy, seq_rec, NULL);
 
1519
        seq_rec_btn=dummy;
 
1520
        gtk_box_pack_start(GTK_BOX(control_box), dummy, WID_FIX);
 
1521
        gui_set_tooltip(dummy, "Enable recording of *events* into the sequencer. All touched controls will be recorded. Existing events for the song-time recording will be overwritten for touched controls.");
 
1522
        gtk_widget_show(dummy);
 
1523
 
 
1524
        dummy=gtk_label_new("Pos:");
 
1525
        gtk_box_pack_start(GTK_BOX(control_box), dummy, WID_FIX);
 
1526
        gtk_widget_show(dummy);
 
1527
        
 
1528
        dummy=gtk_entry_new();
 
1529
        gtk_entry_set_max_length(GTK_ENTRY(dummy), 12);
 
1530
        seq_entry=dummy;
 
1531
        //gtk_widget_set_usize(dummy, 65, 20);
 
1532
        gtk_entry_set_text(GTK_ENTRY(dummy), "00:00.00");
 
1533
#if GTK_CHECK_VERSION(2,4,0)
 
1534
        gtk_entry_set_alignment(GTK_ENTRY(dummy), 0.5);
 
1535
#endif  
 
1536
        gtk_entry_set_width_chars(GTK_ENTRY(dummy), 9);
 
1537
        gtk_box_pack_start(GTK_BOX(control_box), dummy, WID_FIX);
 
1538
        gtk_widget_show(dummy);
 
1539
 
 
1540
        dumadj=(GtkAdjustment*) gtk_adjustment_new(0, 0, 100, 0.1, 1, 1);
 
1541
        seq_adj=dumadj;
 
1542
        connect_adj(dumadj, sequencer_move, NULL);      
 
1543
        dummy=gtk_hscale_new(dumadj);
 
1544
        gtk_widget_set_size_request(dummy, 65, 20);
 
1545
        seq_slider=dummy;
 
1546
        g_signal_connect(G_OBJECT(seq_slider), "button-release-event", (GtkSignalFunc) seq_slider_released, NULL);
 
1547
        gtk_scale_set_draw_value(GTK_SCALE(dummy), FALSE);
 
1548
        
 
1549
        gui_set_tooltip(dummy, "Select the start position for the sequencer in song-time.");
 
1550
        gtk_box_pack_start(GTK_BOX(control_box), dummy, WID_DYN);
 
1551
        gtk_widget_show(dummy);
 
1552
        
 
1553
        dummy=gtk_hbox_new(FALSE,2); //gtk_hpaned_new ();
 
1554
        gtk_box_pack_start(GTK_BOX(left_hbox), dummy, WID_DYN);
 
1555
        gtk_widget_show(dummy);
 
1556
        
 
1557
        tt_parent=dummy;
 
1558
 
 
1559
    panel_bar=gtk_hbox_new(TRUE,0);
 
1560
        gtk_box_pack_start(GTK_BOX(left_hbox), panel_bar, WID_FIX);
 
1561
 
 
1562
        control_parent=gtk_hbox_new(FALSE,4);
 
1563
        gtk_box_pack_start(GTK_BOX(tt_parent), control_parent, WID_FIX);
 
1564
        gtk_widget_show(control_parent);
 
1565
 
 
1566
        dummy=gtk_vseparator_new();
 
1567
        gtk_box_pack_start(GTK_BOX(tt_parent), dummy, WID_FIX);
 
1568
        gtk_widget_show(dummy);
 
1569
 
 
1570
        audio_parent=gtk_vbox_new(FALSE,2);
 
1571
        gtk_box_pack_start(GTK_BOX(tt_parent), audio_parent, WID_DYN);
 
1572
        gtk_widget_show(audio_parent);
 
1573
        
 
1574
        dummy=gtk_vseparator_new();
 
1575
        gtk_box_pack_start(GTK_BOX(main_vbox), dummy, WID_FIX);
 
1576
        gtk_widget_show(dummy);
 
1577
                
 
1578
        right_hbox=gtk_vbox_new(FALSE, 5);
 
1579
        gtk_box_pack_start(GTK_BOX(main_vbox), right_hbox, WID_FIX);
 
1580
        gtk_widget_show(right_hbox);
 
1581
 
 
1582
        /* Master */
 
1583
        
 
1584
        dummy=gtk_label_new(NULL);
 
1585
        gtk_label_set_markup(GTK_LABEL(dummy),"<b>Master</b>");
 
1586
        gtk_misc_set_alignment(GTK_MISC(dummy), 0.5, 0.5);
 
1587
        gtk_box_pack_start(GTK_BOX(right_hbox), dummy, WID_FIX);
 
1588
        gtk_widget_show(dummy); 
 
1589
 
 
1590
        dummy=gtk_hseparator_new();
 
1591
        gtk_box_pack_start(GTK_BOX(right_hbox), dummy, WID_FIX);
 
1592
        gtk_widget_show(dummy);
 
1593
 
 
1594
         /* Pitch */
 
1595
         
 
1596
        /*dummy=gtk_label_new("Pitch:");
 
1597
        gtk_box_pack_start(GTK_BOX(control_box), dummy, WID_FIX);
 
1598
        gtk_widget_show(dummy);*/
 
1599
 
 
1600
        dumadj=(GtkAdjustment*) gtk_adjustment_new(globals.pitch, -3, 3, 0.001, 0.001, 0.01);
 
1601
        pitch_adj=dumadj;
 
1602
        connect_adj(dumadj, master_pitch_changed, NULL);
 
1603
        
 
1604
        tX_extdial *pdial=new tX_extdial("Pitch", pitch_adj, &sp_master_pitch, true);
 
1605
        gtk_box_pack_start(GTK_BOX(right_hbox), pdial->get_widget(), WID_FIX);
 
1606
        gui_set_tooltip(pdial->get_entry(), "Use this dial to adjust the master pitch (affecting *all* turntables).");
 
1607
        
 
1608
        dummy=gtk_hseparator_new();
 
1609
        gtk_box_pack_start(GTK_BOX(right_hbox), dummy, WID_FIX);
 
1610
        gtk_widget_show(dummy);
 
1611
        
 
1612
        /* Volume */
 
1613
        master_vol_box=gtk_hbox_new(FALSE, 5);
 
1614
        gtk_box_pack_start(GTK_BOX(right_hbox), master_vol_box, WID_DYN);
 
1615
        gtk_widget_show(master_vol_box);        
 
1616
        
 
1617
        dumadj=(GtkAdjustment*) gtk_adjustment_new(globals.volume, 0, 2, 0.01, 0.05, 0.000);
 
1618
        volume_adj=dumadj;
 
1619
 
 
1620
        connect_adj(dumadj, master_volume_changed, NULL);       
 
1621
        dummy=gtk_vscale_new(dumadj);
 
1622
        gtk_range_set_inverted(GTK_RANGE(dummy), TRUE);
 
1623
        gtk_scale_set_draw_value(GTK_SCALE(dummy), False);
 
1624
        g_signal_connect(G_OBJECT(dummy), "button_press_event", (GtkSignalFunc) tX_seqpar::tX_seqpar_press, &sp_master_volume); 
 
1625
        
 
1626
        gtk_box_pack_end(GTK_BOX(master_vol_box), dummy, WID_FIX);
 
1627
        gtk_widget_show(dummy); 
 
1628
        gui_set_tooltip(dummy, "Adjust the master volume. This parameter will effect *all* turntables in the set.");
 
1629
        
 
1630
        main_flash=gtk_tx_flash_new();
 
1631
        gtk_box_pack_end(GTK_BOX(master_vol_box), main_flash, WID_DYN);
 
1632
        gtk_widget_show(main_flash);
 
1633
 
 
1634
        dummy=gtk_label_new("Volume");
 
1635
        gtk_misc_set_alignment(GTK_MISC(dummy), 0.5, 0.5);
 
1636
        gtk_box_pack_start(GTK_BOX(right_hbox), dummy, WID_FIX);
 
1637
        gtk_widget_show(dummy);
 
1638
 
 
1639
        /* STATUS BOX */ 
 
1640
        dummy=gtk_hseparator_new();
 
1641
        gtk_box_pack_start(GTK_BOX(right_hbox), dummy, WID_FIX);
 
1642
        gtk_widget_show(dummy);
 
1643
        
 
1644
        status_box=gtk_vbox_new(FALSE, 0);
 
1645
        gtk_box_pack_start(GTK_BOX(right_hbox), status_box, WID_FIX);
 
1646
        gtk_widget_show(status_box);
 
1647
        
 
1648
        dummy=gtk_label_new("0");
 
1649
        used_mem=dummy;
 
1650
        gtk_misc_set_alignment(GTK_MISC(dummy), 1, 0.5);
 
1651
        gtk_box_pack_end(GTK_BOX(status_box), dummy, WID_FIX);
 
1652
        gtk_widget_show(dummy);
 
1653
 
 
1654
//      dummy=gtk_label_new("Mem/MB:");
 
1655
//      gtk_misc_set_alignment(GTK_MISC(dummy), 0, 0.5);
 
1656
//      gtk_box_pack_end(GTK_BOX(status_box), dummy, WID_FIX);
 
1657
//      gtk_widget_show(dummy);
 
1658
        
 
1659
        /*add_sep2();
 
1660
 
 
1661
        dummy=gtk_label_new("1");
 
1662
        no_of_vtts=dummy;
 
1663
        gtk_misc_set_alignment(GTK_MISC(dummy), 1, 0.5);
 
1664
        gtk_box_pack_end(GTK_BOX(status_box), dummy, WID_FIX);
 
1665
        gtk_widget_show(dummy);
 
1666
 
 
1667
        dummy=gtk_label_new("Vtts:");
 
1668
        gtk_misc_set_alignment(GTK_MISC(dummy), 0, 0.5);
 
1669
        gtk_box_pack_end(GTK_BOX(status_box), dummy, WID_FIX);
 
1670
        gtk_widget_show(dummy);*/
 
1671
 
 
1672
        add_sep2();
 
1673
 
 
1674
        dummy=gtk_label_new("v"VERSION);
 
1675
        gtk_misc_set_alignment(GTK_MISC(dummy), 1, 0.5);
 
1676
        gtk_box_pack_end(GTK_BOX(status_box), dummy, WID_FIX);
 
1677
        gtk_widget_show(dummy);
 
1678
 
 
1679
        /*dummy=gtk_label_new("Release:");
 
1680
        gtk_misc_set_alignment(GTK_MISC(dummy), 0, 0.5);
 
1681
        gtk_box_pack_end(GTK_BOX(status_box), dummy, WID_FIX);
 
1682
        gtk_widget_show(dummy);*/
 
1683
        
 
1684
        add_sep2();
 
1685
 
 
1686
        dummy=gtk_label_new(NULL);
 
1687
        gtk_label_set_markup(GTK_LABEL(dummy), "<b>Status</b>");
 
1688
        gtk_misc_set_alignment(GTK_MISC(dummy), 0.5, 0.5);
 
1689
        gtk_box_pack_end(GTK_BOX(status_box), dummy, WID_FIX);
 
1690
        gtk_widget_show(dummy);
 
1691
        
 
1692
        /* END GUI */
 
1693
        
 
1694
        gtk_window_set_default_size(GTK_WINDOW(main_window), x, y);     
 
1695
        gtk_widget_set_sensitive(grab_button, 0);
 
1696
 
 
1697
        new_table(NULL, NULL); // to give the user something to start with ;)
 
1698
 
 
1699
        g_signal_connect (G_OBJECT(main_window), "delete-event", (GtkSignalFunc) quit, NULL);
 
1700
        
 
1701
        if (globals.tooltips) gtk_tooltips_enable(gui_tooltips);
 
1702
        else gtk_tooltips_disable(gui_tooltips);
 
1703
}
 
1704
 
 
1705
gfloat old_percent=-1;
 
1706
 
 
1707
void note_destroy(GtkWidget *widget, GtkWidget *mbox)
 
1708
{
 
1709
        gtk_widget_destroy(GTK_WIDGET(mbox));
 
1710
}
 
1711
 
 
1712
void tx_note(const char *message, bool isError, GtkWindow *window)
 
1713
{
 
1714
        if (!window) window=GTK_WINDOW(main_window);
 
1715
        
 
1716
        GtkWidget *dialog=gtk_message_dialog_new(window,
 
1717
                GTK_DIALOG_DESTROY_WITH_PARENT,
 
1718
                isError ? GTK_MESSAGE_ERROR : GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "%s", message);
 
1719
        gtk_dialog_run(GTK_DIALOG(dialog));
 
1720
        gtk_widget_destroy(dialog);     
 
1721
}
 
1722
 
 
1723
 
 
1724
void tx_l_note(const char *message)
 
1725
{
 
1726
        char buffer[4096]="Plugin info:\n\n";
 
1727
        strcat(buffer, message);
 
1728
        
 
1729
        GtkWidget *dialog=gtk_message_dialog_new(GTK_WINDOW(main_window),
 
1730
                GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, "%s", message);
 
1731
        gtk_dialog_run(GTK_DIALOG(dialog));
 
1732
        gtk_widget_destroy(dialog);     
 
1733
}
 
1734
 
 
1735
void add_to_panel_bar(GtkWidget *button) 
 
1736
{
 
1737
        buttons_on_panel_bar++;
 
1738
        gtk_box_pack_start(GTK_BOX(panel_bar), button, WID_DYN);
 
1739
        gtk_widget_show(panel_bar);
 
1740
}
 
1741
 
 
1742
void remove_from_panel_bar(GtkWidget *button) 
 
1743
{
 
1744
        buttons_on_panel_bar--;
 
1745
        gtk_container_remove(GTK_CONTAINER(panel_bar), button);
 
1746
        if (buttons_on_panel_bar==0) gtk_widget_hide(panel_bar);
 
1747
}
 
1748
 
 
1749
/* Fullscreen code... */
 
1750
#define _WIN_LAYER_TOP          -1
 
1751
#define _WIN_LAYER_NORMAL       4
 
1752
#define _NET_WM_STATE_REMOVE    0
 
1753
#define _NET_WM_STATE_ADD       1
 
1754
#define _NET_WM_STATE_TOGGLE    2
 
1755
 
 
1756
void fullscreen_toggle(GtkCheckMenuItem *item, gpointer data) {
 
1757
        XEvent xev;
 
1758
        Window win=GDK_WINDOW_XID(main_window->window);
 
1759
        Display *disp=GDK_WINDOW_XDISPLAY(main_window->window);
 
1760
        
 
1761
        globals.fullscreen_enabled=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(fullscreen_item));
 
1762
        
 
1763
        /* Top layer.. */
 
1764
        xev.xclient.type = ClientMessage;
 
1765
        xev.xclient.serial = 0;
 
1766
        xev.xclient.send_event = True;
 
1767
        xev.xclient.display = disp;
 
1768
        xev.xclient.window = win;
 
1769
        xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_WIN_LAYER");
 
1770
        xev.xclient.format = 32;
 
1771
        xev.xclient.data.l[0] = globals.fullscreen_enabled ? _WIN_LAYER_TOP : _WIN_LAYER_NORMAL ;
 
1772
        XSendEvent(disp, GDK_WINDOW_XID (gdk_get_default_root_window ()),
 
1773
                False, SubstructureRedirectMask | SubstructureNotifyMask,
 
1774
                &xev);
 
1775
        
 
1776
        /* Fullscreen */
 
1777
        xev.xclient.type = ClientMessage;
 
1778
        xev.xclient.serial = 0;
 
1779
        xev.xclient.send_event = True;
 
1780
        xev.xclient.display = disp;
 
1781
        xev.xclient.window = win;
 
1782
        xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_WM_STATE");
 
1783
        xev.xclient.format = 32;
 
1784
        xev.xclient.data.l[0] = globals.fullscreen_enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
 
1785
        xev.xclient.data.l[1] = gdk_x11_atom_to_xatom (gdk_atom_intern ("_NET_WM_STATE_FULLSCREEN", TRUE));
 
1786
        xev.xclient.data.l[2] = gdk_x11_atom_to_xatom (GDK_NONE);
 
1787
        XSendEvent(gdk_display, GDK_WINDOW_XID (gdk_get_default_root_window ()),
 
1788
                False, SubstructureRedirectMask | SubstructureNotifyMask,
 
1789
                &xev);  
 
1790
}
 
1791
 
 
1792
void fullscreen_setup() {
 
1793
        if (globals.fullscreen_enabled) {
 
1794
                fullscreen_toggle(NULL, NULL);
 
1795
        }
 
1796
}
 
1797
 
 
1798
void display_mastergui()
 
1799
{
 
1800
        GtkWidget *top;
 
1801
        gtk_widget_realize(main_window);
 
1802
        tX_set_icon(main_window);
 
1803
        load_knob_pixs();
 
1804
        gtk_widget_show(main_window);
 
1805
        fullscreen_setup();     
 
1806
        top=gtk_widget_get_toplevel(main_window);
 
1807
        top_window=GDK_WINDOW(top->window);
 
1808
        x_window=GDK_WINDOW_XWINDOW(top->window);
 
1809
}
 
1810
 
 
1811
pid_t help_child=0;
 
1812
GTimer *help_timer=NULL;
 
1813
int help_tag=-1;
 
1814
 
 
1815
int help_checker()
 
1816
{
 
1817
        gdouble time;
 
1818
        gulong ms;
 
1819
        int status;
 
1820
        int result=waitpid(help_child, &status, WNOHANG);
 
1821
        
 
1822
        if (result==0) {
 
1823
                time=g_timer_elapsed(help_timer, &ms);
 
1824
                if (time > 5) {
 
1825
                        /* 5 seconds and it's still running - so we assume everything's OK. */
 
1826
                        tX_debug("No longer waiting for gnome-help..");
 
1827
                        gtk_idle_remove(help_tag);
 
1828
                        help_tag=-1;
 
1829
                }
 
1830
        } else {
 
1831
                /* We are still here and the child exited - that could mean trouble. */
 
1832
                tx_note("Couldn't run the gnome-help command (alias \"yelp\") to display the terminatorX manual. Please ensure that \"yelp\" is installed.", true);             
 
1833
                
 
1834
                gtk_idle_remove(help_tag);
 
1835
                help_tag=-1;
 
1836
        }
 
1837
        return TRUE;    
 
1838
}
 
1839
 
 
1840
#ifndef INSTALL_PREFIX
 
1841
#define INSTALL_PREFIX "/usr/local/share"
 
1842
#endif
 
1843
 
 
1844
void display_help()
 
1845
{       
 
1846
        help_child=fork();
 
1847
 
 
1848
        if (help_tag!=-1) {
 
1849
                gtk_idle_remove(help_tag);
 
1850
                if (help_timer) g_timer_destroy(help_timer);
 
1851
                help_child=0;
 
1852
                help_tag=-1;
 
1853
                help_timer=NULL;
 
1854
        }
 
1855
        
 
1856
        if (help_child==0) {
 
1857
                // child
 
1858
                // execlp("gnome-help","gnome-help","ghelp:/" INSTALL_PREFIX "/terminatorX/doc/terminatorX-manual/C/terminatorX-manual.xml", NULL);
 
1859
                execlp("gnome-help","gnome-help","ghelp://" XML_MANUAL, NULL);          
 
1860
                _exit(-1);
 
1861
        } else if (help_child==-1) {
 
1862
                tx_note("System error: couldn't fork() to run the help process.", true);
 
1863
        } else {
 
1864
                help_timer=g_timer_new();
 
1865
                g_timer_start(help_timer);
 
1866
        
 
1867
                help_tag=gtk_idle_add((GtkFunction) help_checker, NULL);
 
1868
        }
 
1869
}
 
1870
 
 
1871
pid_t browser_child=0;
 
1872
GTimer *browser_timer=NULL;
 
1873
int browser_tag=-1;
 
1874
 
 
1875
int browser_checker()
 
1876
{
 
1877
        gdouble time;
 
1878
        gulong ms;
 
1879
        int status;
 
1880
        int result=waitpid(browser_child, &status, WNOHANG);
 
1881
        
 
1882
        if (result==0) {
 
1883
                time=g_timer_elapsed(browser_timer, &ms);
 
1884
                if (time > 5) {
 
1885
                        /* 5 seconds and it's still running - so we assume everything's OK. */
 
1886
                        tX_debug("No longer waiting for a browser..");
 
1887
                        gtk_idle_remove(browser_tag);
 
1888
                        browser_tag=-1;
 
1889
                }
 
1890
        } else {
 
1891
                /* We are still here and the child exited - that could mean trouble. */
 
1892
                tx_note("Failed to run a suitable web browser - if there's one installed on this system, please run it and forward yourself to:\nhttp://terminatorX.org", true);                
 
1893
                
 
1894
                gtk_idle_remove(browser_tag);
 
1895
                browser_tag=-1;
 
1896
        }
 
1897
        return TRUE;    
 
1898
}
 
1899
 
 
1900
void display_browser()
 
1901
{       
 
1902
        browser_child=fork();
 
1903
 
 
1904
        if (browser_tag!=-1) {
 
1905
                gtk_idle_remove(browser_tag);
 
1906
                if (browser_timer) g_timer_destroy(browser_timer);
 
1907
                browser_child=0;
 
1908
                browser_tag=-1;
 
1909
                browser_timer=NULL;
 
1910
        }
 
1911
        
 
1912
        if (browser_child==0) {
 
1913
                // child
 
1914
                execlp("mozilla","mozilla","http://terminatorX.org", NULL);
 
1915
                execlp("netscape","netscape","http://terminatorX.org", NULL);
 
1916
                execlp("galeon","galeon","http://terminatorX.org", NULL);
 
1917
                execlp("konqueror","konqueror","http://terminatorX.org", NULL);         
 
1918
                _exit(-1);
 
1919
        } else if (browser_child==-1) {
 
1920
                tx_note("System error: couldn't fork() to run the browser process.", true);
 
1921
        } else {
 
1922
                browser_timer=g_timer_new();
 
1923
                g_timer_start(browser_timer);
 
1924
        
 
1925
                browser_tag=gtk_idle_add((GtkFunction) browser_checker, NULL);
 
1926
        }
 
1927
}
 
1928
 
 
1929
 
 
1930
 
 
1931
GdkCursor *tX_cursor::cursors[MAX_CURSOR]={NULL, NULL, NULL};
 
1932
tX_cursor::cursor_shape tX_cursor::current_shape=tX_cursor::DEFAULT_CURSOR;
 
1933
 
 
1934
void tX_cursor::set_cursor(cursor_shape shape)
 
1935
{
 
1936
        switch (shape) {
 
1937
                case DEFAULT_CURSOR:
 
1938
                        cursors[shape]=NULL;
 
1939
                        break;
 
1940
                
 
1941
                case WAIT_CURSOR:
 
1942
                        if (!cursors[shape]) cursors[shape]=gdk_cursor_new(GDK_WATCH);
 
1943
                        break;
 
1944
                
 
1945
                case WAIT_A_SECOND_CURSOR:
 
1946
                        /* FIXME: What's that short-time wait cursor's id? */
 
1947
                        if (!cursors[shape]) cursors[shape]=gdk_cursor_new(GDK_WATCH);
 
1948
                        break;
 
1949
                
 
1950
                default:
 
1951
                        tX_debug("No such cursor shape.");
 
1952
                        return;
 
1953
        }
 
1954
        
 
1955
        /* Still here? Ok... */
 
1956
        current_shape=shape;
 
1957
        
 
1958
        gdk_window_set_cursor(main_window->window, cursors[shape]);
 
1959
}
 
1960
 
 
1961
GdkCursor *tX_cursor::get_cursor()
 
1962
{
 
1963
        return cursors[current_shape];
 
1964
}
 
1965
 
 
1966
void tX_cursor::reset_cursor()
 
1967
{
 
1968
        current_shape=DEFAULT_CURSOR;
 
1969
        gdk_window_set_cursor(main_window->window, cursors[current_shape]);
 
1970
}