Merged Arthur's MIDI patch, starting on the menubar, gui fixes and
authorterminatorX <>
Fri, 22 Nov 2002 01:13:04 +0000 (01:13 +0000)
committerterminatorX <>
Fri, 22 Nov 2002 01:13:04 +0000 (01:13 +0000)
cleanups + fixed the scrolled window policy, ./configure fixes - Alex

17 files changed:
acconfig.h [deleted file]
configure.in
src/Makefile.am
src/tX_engine.cc
src/tX_engine.h
src/tX_extdial.cc
src/tX_global.c
src/tX_global.h
src/tX_mastergui.cc
src/tX_midiin.cc [new file with mode: 0644]
src/tX_midiin.h [new file with mode: 0644]
src/tX_seqpar.cc
src/tX_seqpar.h
src/tX_vtt.cc
src/tX_vttgui.cc
src/tX_vttgui.h
src/tX_widget.c

diff --git a/acconfig.h b/acconfig.h
deleted file mode 100644 (file)
index 47a1796..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/* Features */
-
-/* Define if you want keep device open */
-#undef KEEP_DEV_OPEN
-
-/* Define if you want to use sox as input converter */
-#undef USE_SOX_INPUT
-
-/* Define if you want UGLY mp3-input "support" - requires sox as well*/
-#undef USE_MPG123_INPUT
-
-/* Define if you want UGLY ogg-input "support" - also requires sox*/
-#undef USE_OGG123_INPUT
-
-/* Define if you want realtime scheduling when tX is run with root privileges*/
-#undef USE_SCHEDULER
-
-/* Define for debug messages */
-#undef ENABLE_DEBUG_OUTPUT
-
-/* Define for flashes */
-#undef DONT_USE_FLASH
-
-/* Define for 3DNow! Support */
-#undef USE_3DNOW
-
-/* Define for DGA2 Support */
-#undef USE_DGA2
-
-/* Define for Benchmarking reasons */
-#undef CREATE_BENCHMARK
-
-/* Define for Builtin Wavloader */
-#undef USE_BUILTIN_WAV
-
-/* Define for dial knobs instead of scales */
-#undef USE_DIAL
-
-/* Define for big dial knobs */
-#undef USE_BIG_BUTTONS
-
-/* Exec xsetpointer instead of using Xlib-calls. */
-#undef USE_XSETPOINTER
-
-/* Use MAD for mp3 support */
-#undef USE_MAD_INPUT
-
-/* Use libvorbis for ogg support */
-#undef USE_VORBIS_INPUT
-
-/* Use libaudiofile support */
-#undef USE_AUDIOFILE_INPUT
-
-/* Use ALSA*/
-#undef USE_ALSA
-
-/* Use OSS */
-#undef USE_OSS
-
-/* Don't use movqfix */
-#undef OVERRIDE_MOVQ_AUTODETECT
-
-/* Define for supporting old binary tX set files */
-#undef ENABLE_TX_LEGACY
index 128ff45d7a0988d413e0284f5e6b1a78b6bc5cfd..d56dfc8c12aadf1e4b5aba1d423b155208487e7f 100644 (file)
@@ -23,6 +23,7 @@ AC_ARG_ENABLE(mad,            [  --disable-mad           disable mad for mp3 support (defa
 AC_ARG_ENABLE(vorbis,  [  --disable-vorbis        disable libvorbis support (default=auto) ])
 AC_ARG_ENABLE(audiofile,       [  --disable-audiofile     disable audiofile support (default=auto) ])
 AC_ARG_ENABLE(legacy,          [  --disable-legacy        disable support for old terminatorX files (default=on) ])
+AC_ARG_ENABLE(alsamidi,                [  --disable-alsamidi      disable support  ALSA MIDI in (default=auto) ])
 
 dnl Checks for programs.
 AC_PROG_AWK
@@ -41,6 +42,8 @@ OPTION_AUDIOFILE="no"
 OPTION_WAV="no"
 OPTION_GNOME="no"
 OPTION_SCHEDULER="no"
+OPTION_ALSAMIDI="no"
+OPTION_LEGACY="no"
 
 dnl Checks for libraries.
 AC_CHECK_LIB(m, floor,, AC_MSG_ERROR([** math-lib not installed or broken **]))
@@ -157,14 +160,14 @@ AC_PROG_GCC_TRADITIONAL
 
 dnl Eval args
 if test "$enable_closedev" = "no"; then
-       AC_DEFINE(KEEP_DEV_OPEN)
+       AC_DEFINE_UNQUOTED([KEEP_DEV_OPEN], 1, [Define if you want keep device open])
 fi
 
 
 if test "$enable_sox" != "no"; then
        AC_CHECK_PROG(SOX_PROG, sox, yes)
        if test "$SOX_PROG" = "yes"; then
-               AC_DEFINE(USE_SOX_INPUT)
+               AC_DEFINE_UNQUOTED([USE_SOX_INPUT], 1, [Define if you want to use sox as input converter])
                OPTION_SOX="yes"
        fi
 fi
@@ -175,7 +178,7 @@ if test "$enable_mad" != "no"; then
                AC_CHECK_LIB(mad,mad_decoder_init,madlib=yes,madlib=no)
                if test "$madlib" = "yes"; then
                        LIBS="$LIBS -lmad"
-                       AC_DEFINE(USE_MAD_INPUT)
+                       AC_DEFINE_UNQUOTED([USE_MAD_INPUT], 1, [Define to use MAD for mp3 support])
                        OPTION_MAD="yes"
                fi
        fi
@@ -191,7 +194,7 @@ if test "$enable_vorbis" != "no"; then
                        AC_CHECK_LIB(vorbisfile,ov_open_callbacks,vorbisfile_libs=yes,vorbisfile_libs=no)
                        if test "$vorbisfile_libs" = "yes"; then
                                LIBS="$LIBS -lvorbisfile"
-                               AC_DEFINE(USE_VORBIS_INPUT)
+                               AC_DEFINE_UNQUOTED([USE_VORBIS_INPUT], 1, [Define to use libvorbis for ogg support])
                                OPTION_VORBIS="yes"
                        else
                                LIBS=PREV_LIBS
@@ -209,7 +212,7 @@ if test "$enable_audiofile" != "no"; then
                fi
                af_libs=`audiofile-config --libs`
                LIBS="$LIBS $af_libs"
-               AC_DEFINE(USE_AUDIOFILE_INPUT)
+               AC_DEFINE_UNQUOTED([USE_AUDIOFILE_INPUT], 1, [Define to compile libaudiofile support])
                OPTION_AUDIOFILE="yes"
        else
                AC_CHECK_HEADERS(audiofile.h,audiofile_headers=yes,audiofile_headers=no)
@@ -217,7 +220,7 @@ if test "$enable_audiofile" != "no"; then
                        AC_CHECK_LIB(audiofile,afOpenFile,audiofile_libs=yes,audiofile_libs=no)
                        if test "$audiofile_libs" = "yes"; then
                                LIBS="$LIBS -laudiofile"
-                               AC_DEFINE(USE_AUDIOFILE_INPUT)
+                               AC_DEFINE_UNQUOTED([USE_AUDIOFILE_INPUT], 1, [Define to compile libaudiofile support])
                                OPTION_AUDIOFILE="yes"
                        fi
                fi
@@ -228,12 +231,12 @@ if test "$enable_mpg123" != "no"; then
        AC_CHECK_PROG(MPG123_PROG, mpg123, yes)
        if test "$MPG123_PROG" = "yes"; then
                if test "$SOX_PROG" = "yes"; then       
-                       AC_DEFINE(USE_MPG123_INPUT)
+                       AC_DEFINE_UNQUOTED([USE_MPG123_INPUT], 1, [Define mp3-input through mpg123 - requires sox as well])
                        OPTION_MPG123="yes"
                else
                        AC_CHECK_PROG(SOX_PROG, sox, yes)
                        if test "$SOX_PROG" = "yes"; then       
-                               AC_DEFINE(USE_MPG123_INPUT)
+                               AC_DEFINE_UNQUOTED([USE_MPG123_INPUT], 1, [Define mp3-input through mpg123 - requires sox as well])
                                OPTION_MPG123="yes"
                        else
                                AC_MSG_RESULT([** mpg123 support disabled: couldn't find sox! **])
@@ -245,7 +248,7 @@ fi
 if test "$enable_ogg123" != "no"; then
        AC_CHECK_PROG(OGG123_PROG, ogg123, yes)
        if test "$OGG123_PROG" = "yes"; then
-               AC_DEFINE(USE_OGG123_INPUT)
+               AC_DEFINE_UNQUOTED([USE_OGG123_INPUT], 1, [Define if you want UGLY ogg-input "support" - also requires sox])
                OPTION_OGG123="yes"
        fi
 fi
@@ -253,7 +256,7 @@ fi
 if test "$enable_xsetpointer" != "no"; then
        AC_CHECK_PROG(XSETPOINTER_PROG, xsetpointer, yes)
        if test "$XSETPOINTER_PROG" = "yes"; then
-               AC_DEFINE(USE_XSETPOINTER)
+               AC_DEFINE_UNQUOTED([USE_XSETPOINTER], 1, [Exec xsetpointer instead of using Xlib-calls.])
        else
                if test "$enable_xsetpointer" = "yes"; then
                        AC_MSG_ERROR([** xsetpointer not found. **])
@@ -262,7 +265,7 @@ if test "$enable_xsetpointer" != "no"; then
 fi
 
 if test "$enable_movqfix" = "no"; then
-       AC_DEFINE(OVERRIDE_MOVQ_AUTODETECT)
+       AC_DEFINE_UNQUOTED([OVERRIDE_MOVQ_AUTODETECT], 1, [Don't use movqfix])
 fi
 
 using_alsa=no
@@ -292,7 +295,7 @@ if test "$enable_oss" != "no"; then
        AC_CHECK_HEADERS(sys/ioctl.h sys/soundcard.h,oss=yes,oss=no)
        
        if test "$oss" = "yes"; then
-               AC_DEFINE(USE_OSS)
+               AC_DEFINE_UNQUOTED([USE_OSS], 1, [Use OSS])
                using_oss=yes;
        else
                if test "$enable_oss" = "yes"; then
@@ -301,6 +304,28 @@ if test "$enable_oss" != "no"; then
        fi
 fi
 
+if test "$enable_alsamidi" != "no"; then
+    AC_CHECK_LIB(asound, snd_seq_open,alsalib=yes,alsalib=no)
+    AC_CHECK_HEADERS(alsa/asoundlib.h,alsaheader=yes,alsaheader=no)
+
+    if test "$alsalib" = "yes"; then
+           if test "$alsaheader" = "yes"; then
+                   AC_DEFINE_UNQUOTED([USE_ALSA_MIDI_IN], 1, [Define for ALSA MIDI in support])
+                   LIBS="$LIBS -lasound"
+                   OPTION_ALSAMIDI="yes"
+           else 
+                   if test "$enable_alsamidi" = "yes"; then
+                           AC_MSG_ERROR([** Coulnd't find ALSA header file alsa/asoundlib.h **])
+                   fi
+           fi
+    else
+           if test "$enable_alsamidin" = "yes"; then
+                   AC_MSG_ERROR([** Couldn't find ALSA library libasound. **])
+           fi
+    fi
+fi
+
+
 dnl if test "$using_alsa" = "yes"; then
 dnl    AC_MSG_RESULT([termnatorX audiodevice: using ALSA.])
 dnl fi
@@ -317,29 +342,29 @@ fi
        
 if test "$enable_wav" != "no";
 then
-       AC_DEFINE(USE_BUILTIN_WAV)
+       AC_DEFINE_UNQUOTED([USE_BUILTIN_WAV], 1, [Define to enable the built-in wav loading routines])
        OPTION_WAV="yes"
 fi
 
-if test "$enable_flash" = "no"; then
-       AC_DEFINE(DONT_USE_FLASH)
-fi 
+dnl if test "$enable_flash" = "no"; then
+dnl    AC_DEFINE(DONT_USE_FLASH)
+dnl fi 
 
 if test "$enable_3dnow" = "yes"; then
-       AC_DEFINE(USE_3DNOW)
+       AC_DEFINE_UNQUOTED([USE_3DNOW], 1, [Do not define this])
 fi 
 
 if test "$enable_scheduler" != "no"; then
        OPTION_SCHEDULER="yes";
-       AC_DEFINE(USE_SCHEDULER)
+       AC_DEFINE_UNQUOTED([USE_SCHEDULER], 1, [Define this to compile with rt scheduling support])
 fi
 
 if test "$enable_debug" = yes; then
-       AC_DEFINE(ENABLE_DEBUG_OUTPUT)
+       AC_DEFINE_UNQUOTED([ENABLE_DEBUG_OUTPUT], 1, [Define this to enable debug output.])
 fi
 
 if test "$enable_benchmark" = yes; then
-       AC_DEFINE(CREATE_BENCHMARK)
+       AC_DEFINE_UNQUOTED([CREATE_BENCHMARK], 1, [Define this to build an performance benchmark - WARNING: You cannot use the resulting binary for normal operation])
 fi
 
 dnl AC_MSG_CHECKING(whether to use dials)
@@ -347,24 +372,25 @@ dnl if test "$enable_dial" = no; then
 dnl    AC_MSG_RESULT(no)
 dnl else
 dnl    AC_MSG_RESULT(yes)
-       AC_DEFINE(USE_DIAL)
+       AC_DEFINE_UNQUOTED([USE_DIAL], 1, [Keep this defined])
 dnl fi
 
 AC_MSG_CHECKING(for necessary scratching skillz)
 AC_MSG_RESULT(yes)
 
-if test "$enable_bigdial" = yes; then
-       AC_DEFINE(USE_DIAL)
-       AC_DEFINE(USE_BIG_BUTTONS)
-fi
+dnl if test "$enable_bigdial" = yes; then
+dnl    AC_DEFINE(USE_DIAL)
+dnl    AC_DEFINE(USE_BIG_BUTTONS)
+dnl fi
 
 if test "$enable_legacy" != no; then
-       AC_DEFINE(ENABLE_TX_LEGACY)
+       AC_DEFINE_UNQUOTED([ENABLE_TX_LEGACY], 1, [Define this to enable support for old tX set files])
+       OPTION_LEGACY="yes"
 fi
 
-if test "$enable_dga2" = yes; then
-       AC_DEFINE(USE_DGA2)
-fi
+dnl if test "$enable_dga2" = yes; then
+dnl    AC_DEFINE(USE_DGA2)
+dnl fi
 
 AC_MSG_CHECKING(for GNOME)
        AC_MSG_RESULT([in progress])
@@ -455,7 +481,7 @@ if test "$enable_dga2" = yes; then
 fi
 AC_OUTPUT(Makefile src/Makefile gnome-support/Makefile gnome-support/terminatorX.keys src/gui_icons/Makefile src/smallknob/Makefile doc/Makefile doc/img/Makefile terminatorX.spec terminatorX.1)
 
-function option_info() {
+option_info() {
        echo "$option support: $option_val"
        if test "$option_val" != "yes"; then
                echo "  - If you want $option support get $option from"
@@ -492,6 +518,10 @@ option_info;
 option=audiofile; option_val=$OPTION_AUDIOFILE; option_url=http://www.68k.org/~michael/audiofile/
 option_info;
 
+option="ALSA (MIDI in)"; option_val=$OPTION_ALSAMIDI; option_url=http://www.alsa-project.org
+option_info;
+
+echo "legacy files supprt: $OPTION_LEGACY"
 echo "builtin-wav support: $OPTION_WAV"
 echo "enhanced scheduling support: $OPTION_SCHEDULER"
 echo "GNOME support: $OPTION_GNOME"
index c8fef9e8f6df97e5155fe6288f60498bd0bc094e..1cd13304fa45a33999d51724651215920867b129 100644 (file)
@@ -30,4 +30,5 @@ terminatorX_SOURCES = tX_endian.c tX_dialog.cc tX_widget.c wav_write.c \
                        tX_knobloader.h tX_knobloader.c tX_dial.c tX_dial.h \
                        tX_extdial.h tX_extdial.cc tX_panel.h tX_panel.cc \
                        tX_ladspa.h tX_ladspa.cc tX_vttfx.h tX_vttfx.cc \
-                       tX_legacy_vtt.cc tX_legacy_global.c
+                       tX_legacy_vtt.cc tX_legacy_global.c \
+                       tX_midiin.h tX_midiin.cc
index 24f4543c3825d53560d819f320dcbd4bed0c80fa..91717c0216bde42186fce7e222175e92de57496e 100644 (file)
@@ -106,6 +106,10 @@ void tX_engine :: loop() {
                                        grab_request=false;
                                }
                        }
+
+#ifdef USE_ALSA_MIDI_IN                        
+                       midi->check_event();
+#endif                 
                
                        /* Playback the audio... */
                        device->play(temp);
@@ -203,6 +207,9 @@ tX_engine :: tX_engine() {
        }
        
        mouse=new tx_mouse();
+#ifdef USE_ALSA_MIDI_IN        
+       midi=new tX_midiin();
+#endif 
        tape=new tx_tapedeck();
        device=NULL;
        recording=false;
@@ -259,7 +266,7 @@ tX_engine_error tX_engine :: run() {
        for (vtt=vtt_class::main_list.begin(); vtt!=vtt_class::main_list.end(); vtt++) {
                if ((*vtt)->autotrigger) (*vtt)->trigger();
        }
-       
+
        sequencer.forward_to_start_timestamp(1);        
        stop_flag=false;
        /* Trigger the engine thread... */
index e0d60a1c9f29fe1a9ec7b1020526d0d9b9734004..a48c2cc945679b23f68d227659268cdd0079d3df 100644 (file)
@@ -27,6 +27,7 @@
 #include "tX_tape.h"
 #include "tX_mouse.h"
 #include "tX_audiodevice.h"
+#include "tX_midiin.h"
 
 #define ENG_ERR 4
 
@@ -72,6 +73,11 @@ class tX_engine {
        bool grab_active;
        
        public:
+
+#ifdef USE_ALSA_MIDI_IN
+       tX_midiin *midi;
+#endif 
+
        tX_engine();
        ~tX_engine();
        
index 7e6ae539c588e2fee8cb1d1d67911c3efed22f22..8aa2d25c5c000e935d883e425458b752ce90519d 100644 (file)
@@ -35,14 +35,13 @@ tX_extdial :: tX_extdial(const char *l, GtkAdjustment *a)
        mainbox=gtk_vbox_new(FALSE, 0);
        subbox=gtk_hbox_new(TRUE, 0);
        gtk_box_pack_start(GTK_BOX(subbox), dial, WID_FIX);
-       gtk_box_pack_start(GTK_BOX(subbox), entry, WID_FIX);
+       gtk_box_pack_start(GTK_BOX(subbox), entry, WID_DYN);
        gtk_box_pack_start(GTK_BOX(mainbox), subbox, WID_FIX);
        gtk_box_pack_start(GTK_BOX(mainbox), label, WID_FIX);
-//     gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.9);
        
        gtk_widget_show(label);
        gtk_widget_show(entry);
-       gtk_widget_set_usize(entry, 33, entry->requisition.height);
+       gtk_entry_set_width_chars(GTK_ENTRY(entry), 4);
        gtk_widget_show(dial);
        gtk_widget_show(subbox);
        gtk_widget_show(mainbox);
index 804edcabc4ec828b65cbd76e9cbe07df65038d63..246d3b0194916d6ddf3f09825686058015e43f8c 100644 (file)
@@ -123,7 +123,8 @@ void set_global_defaults() {
        globals.use_stdout_cmdline=0;
        globals.current_path = NULL;
        globals.pitch=1.0;
-       globals.volume=1.0;     
+       globals.volume=1.0;
+       globals.fullscreen_enabled=1;
        if (!globals.true_block_size) globals.true_block_size=1<globals.buff_size;
 
 }
@@ -187,6 +188,7 @@ int load_globals_xml() {
                        restore_string("tables_filename", globals.tables_filename);
                        restore_string("record_filename", globals.record_filename);
                        restore_string("file_editor", globals.file_editor);
+                       restore_int("fullscreen_enabled", globals.fullscreen_enabled);
 
                        if (!elementFound) {
                                fprintf(stderr, "tX: Unhandled XML element: \"%s\"\n", cur->name);
@@ -194,7 +196,6 @@ int load_globals_xml() {
                }
        }
 
-       puts(globals.audio_device);
        xmlFreeDoc(doc);
        
        return 0;
@@ -241,6 +242,7 @@ void store_globals() {
                store_string("tables_filename", globals.tables_filename);
                store_string("record_filename", globals.record_filename);
                store_string("file_editor", globals.file_editor);
+               store_int("fullscreen_enabled", globals.fullscreen_enabled);
                
                fprintf(rc,"</terminatorXrc>\n");
        }
index 8c76fb2115a74144dd32f228b7c5fab302024856..4c89b12ea29b571e3b36ba529c265b97bb3f0f9f 100644 (file)
@@ -130,6 +130,8 @@ typedef struct {
        /* ALSA specific options */
        int audiodevice_alsa_card;
        int audiodevice_alsa_pcm;               
+       
+       int fullscreen_enabled;
 } tx_global;
 
 extern tx_global globals;
index 11bd9a6998282530a8ab9eb58c9da0cadc37a0f8..4d995c189a1d9de21d1d364401e9710650aa3402 100644 (file)
@@ -28,6 +28,7 @@
 #include <math.h>
 #include <unistd.h>
 #include <string.h>
+#include <gdk/gdkkeysyms.h>
 #include "version.h"
 #include "tX_global.h"
 #include "tX_engine.h"
@@ -65,7 +66,7 @@ GtkWidget *grab_button;
 GtkWidget *main_flash_l;
 GtkWidget *main_flash_r;
 GtkWidget *rec_btn;
-GtkWidget *fullscreen_button;
+GtkWidget *fullscreen_item;
 
 GtkWidget *seq_rec_btn;
 GtkWidget *seq_play_btn;
@@ -93,7 +94,7 @@ GtkWidget *SaveSet;
 
 GtkWidget *engine_btn;
 
-bool tX_fullscreen_status=false;
+GtkWidget *main_menubar;
 
 int rec_dont_care=0;
 gint update_tag;
@@ -801,8 +802,117 @@ void sequencer_move(GtkWidget *wid, void *d)
        gtk_box_pack_end(GTK_BOX(smaller_box), dummy, WID_FIX);\
        gtk_widget_show(dummy);\
 
+void fullscreen_toggle(GtkCheckMenuItem *item, gpointer data);
+
+void create_master_menu() {
+       GtkWidget *menu_item;
+       GtkWidget *sub_menu;
+       GtkAccelGroup* accel_group=gtk_accel_group_new();
+       gtk_window_add_accel_group(GTK_WINDOW(main_window), accel_group);
+      /*gtk_signal_connect (GTK_OBJECT (dummy), "drag_data_received",
+        gtk_signal_connect(GTK_OBJECT(dummy), "clicked", GtkSignalFunc(new_table), NULL);       
+        gtk_signal_connect(GTK_OBJECT(dummy), "clicked", GtkSignalFunc(load_tables), NULL);     
+        gtk_signal_connect (GTK_OBJECT (dummy), "drag_data_received",
+        gtk_signal_connect(GTK_OBJECT(dummy), "clicked", GtkSignalFunc(save_tables), NULL);     
+        gtk_signal_connect (GTK_OBJECT(dummy), "clicked", (GtkSignalFunc) display_options, NULL);
+        gtk_signal_connect (GTK_OBJECT(dummy), "clicked", (GtkSignalFunc) mplcfitx, NULL);      
+        gtk_signal_connect (GTK_OBJECT(dummy), "clicked", (GtkSignalFunc) quit, NULL);
+*/
+       /* FILE */
+       menu_item = gtk_menu_item_new_with_mnemonic ("_File");
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (main_menubar), menu_item);
+
+       sub_menu = gtk_menu_new ();
+       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
+
+       menu_item = gtk_image_menu_item_new_from_stock ("gtk-new", accel_group);
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+
+       menu_item = gtk_image_menu_item_new_from_stock ("gtk-open", accel_group);
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+       g_signal_connect(menu_item, "activate", (GCallback) load_tables, NULL);
+
+       menu_item = gtk_image_menu_item_new_from_stock ("gtk-save", accel_group);
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+       g_signal_connect(menu_item, "activate", (GCallback) save_tables, NULL);
+
+       /*menu_item = gtk_image_menu_item_new_from_stock ("gtk-save-as", accel_group);
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);*/
+
+       menu_item = gtk_menu_item_new ();
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+       gtk_widget_set_sensitive (menu_item, FALSE);
+
+       menu_item = gtk_image_menu_item_new_from_stock ("gtk-quit", accel_group);
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+       g_signal_connect(menu_item, "activate", (GCallback) quit, NULL);
+
+       /* Turntables */
+       menu_item = gtk_menu_item_new_with_mnemonic ("_Turntables");
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (main_menubar), menu_item);
+       
+       sub_menu = gtk_menu_new ();
+       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
+
+       menu_item = gtk_menu_item_new_with_mnemonic("_Add Turntable");
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+       g_signal_connect(menu_item, "activate", (GCallback) new_table, NULL);
+
+       /* Options */
+       menu_item = gtk_menu_item_new_with_mnemonic ("_Options");
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (main_menubar), menu_item);
+
+       sub_menu = gtk_menu_new ();
+       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
+               
+       menu_item = gtk_check_menu_item_new_with_mnemonic("_Fullscreen");
+       fullscreen_item = menu_item;
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+
+       gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menu_item), globals.fullscreen_enabled);
+       gtk_widget_add_accelerator (menu_item, "activate", accel_group, GDK_F11, (GdkModifierType) 0, GTK_ACCEL_VISIBLE);
+       g_signal_connect(menu_item, "activate", (GCallback) fullscreen_toggle, NULL);
+       //GtkWidget *label=gtk_accel_label_new("F11");
+       //gtk_accel_label_set_accel_widget(GTK_ACCEL_LABEL(label), menu_item);
+       
+       menu_item = gtk_menu_item_new ();
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+       gtk_widget_set_sensitive (menu_item, FALSE);
+
+       menu_item = gtk_menu_item_new_with_mnemonic("_Preferences");
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+       g_signal_connect(menu_item, "activate", (GCallback) display_options, NULL);
+
+       /* HELP */ 
+       menu_item = gtk_menu_item_new_with_mnemonic ("_Help");
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (main_menubar), menu_item);
+
+       sub_menu = gtk_menu_new ();
+       gtk_menu_item_set_submenu (GTK_MENU_ITEM (menu_item), sub_menu);
+
+       menu_item = gtk_menu_item_new_with_mnemonic ("_About");
+       gtk_widget_show (menu_item);
+       gtk_container_add (GTK_CONTAINER (sub_menu), menu_item);
+       g_signal_connect(menu_item, "activate", (GCallback) mplcfitx, NULL);
+}
+
 void create_mastergui(int x, int y)
 {
+       GtkWidget *mother_of_all_boxen;
        GtkWidget *main_vbox;
        GtkWidget *right_hbox;
        GtkWidget *left_hbox;
@@ -830,9 +940,18 @@ void create_mastergui(int x, int y)
 
        gtk_widget_realize(main_window);
        
-       main_vbox=gtk_hbox_new(FALSE, 5);
+       mother_of_all_boxen=gtk_vbox_new(FALSE, 5);
+       gtk_container_add(GTK_CONTAINER(main_window), mother_of_all_boxen);
+       gtk_widget_show(mother_of_all_boxen);   
+       
+       main_menubar=gtk_menu_bar_new();
+       gtk_box_pack_start(GTK_BOX(mother_of_all_boxen), main_menubar, WID_FIX);
+       gtk_widget_show(main_menubar);  
+       
+       create_master_menu();
        
-       gtk_container_add(GTK_CONTAINER(main_window), main_vbox);
+       main_vbox=gtk_hbox_new(FALSE, 5);
+       gtk_box_pack_start(GTK_BOX(mother_of_all_boxen), main_vbox, WID_DYN);
        gtk_widget_show(main_vbox);
        
        left_hbox=gtk_vbox_new(FALSE, 5);
@@ -941,7 +1060,7 @@ void create_mastergui(int x, int y)
        gtk_box_pack_start(GTK_BOX(sequencer_box), dummy, WID_DYN);
        gtk_widget_show(dummy);
        
-       dummy=gtk_hbox_new(FALSE,2);
+       dummy=gtk_hbox_new(FALSE,2); //gtk_hpaned_new ();
        gtk_box_pack_start(GTK_BOX(left_hbox), dummy, WID_DYN);
        gtk_widget_show(dummy);
        
@@ -952,6 +1071,7 @@ void create_mastergui(int x, int y)
 
        control_parent=gtk_hbox_new(FALSE,0);
        gtk_box_pack_start(GTK_BOX(tt_parent), control_parent, WID_FIX);
+       //gtk_paned_pack1(GTK_PANED(tt_parent), control_parent, FALSE, FALSE);
        gtk_widget_show(control_parent);
 
        dummy=gtk_vseparator_new();
@@ -960,6 +1080,7 @@ void create_mastergui(int x, int y)
 
        audio_parent=gtk_vbox_new(FALSE,0);
        gtk_box_pack_start(GTK_BOX(tt_parent), audio_parent, WID_DYN);
+       //gtk_paned_pack2(GTK_PANED(tt_parent), audio_parent, TRUE, FALSE);
        gtk_widget_show(audio_parent);
        
        dummy=gtk_vseparator_new();
@@ -969,7 +1090,7 @@ void create_mastergui(int x, int y)
        right_hbox=gtk_vbox_new(FALSE, 5);
        gtk_box_pack_start(GTK_BOX(main_vbox), right_hbox, WID_FIX);
        gtk_widget_show(right_hbox);
-       
+/*     
        dummy=gtk_button_new_with_label("Add Turntable");
        AddTable=dummy; 
        gtk_box_pack_start(GTK_BOX(right_hbox), dummy, WID_FIX);
@@ -1026,11 +1147,8 @@ void create_mastergui(int x, int y)
        gui_set_tooltip(dummy, "Click here to exit terminatorX.");
        gtk_signal_connect (GTK_OBJECT(dummy), "clicked", (GtkSignalFunc) quit, NULL);
 
-       fullscreen_button=gtk_button_new_with_label("Fullscreen");
-       gtk_box_pack_start(GTK_BOX(right_hbox), fullscreen_button, WID_FIX);
-       
        add_sep();              
-
+*/
        small_box=gtk_hbox_new(FALSE, 5);
        gtk_box_pack_start(GTK_BOX(right_hbox), small_box, WID_DYN);
        gtk_widget_show(small_box);
@@ -1189,12 +1307,12 @@ void remove_from_panel_bar(GtkWidget *button) {
 #define _NET_WM_STATE_ADD      1
 #define _NET_WM_STATE_TOGGLE   2
 
-void fullscreen_toggle() {
+void fullscreen_toggle(GtkCheckMenuItem *item, gpointer data) {
        XEvent xev;
        Window win=GDK_WINDOW_XID(main_window->window);
        Display *disp=GDK_WINDOW_XDISPLAY(main_window->window);
        
-       tX_fullscreen_status=!tX_fullscreen_status;
+       globals.fullscreen_enabled=gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(fullscreen_item));
        
        /* Top layer.. */
        xev.xclient.type = ClientMessage;
@@ -1204,7 +1322,7 @@ void fullscreen_toggle() {
        xev.xclient.window = win;
        xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_WIN_LAYER");
        xev.xclient.format = 32;
-       xev.xclient.data.l[0] = tX_fullscreen_status ? _WIN_LAYER_TOP : _WIN_LAYER_NORMAL ;
+       xev.xclient.data.l[0] = globals.fullscreen_enabled ? _WIN_LAYER_TOP : _WIN_LAYER_NORMAL ;
        XSendEvent(disp, GDK_WINDOW_XID (gdk_get_default_root_window ()),
                False, SubstructureRedirectMask | SubstructureNotifyMask,
                &xev);
@@ -1217,7 +1335,7 @@ void fullscreen_toggle() {
        xev.xclient.window = win;
        xev.xclient.message_type = gdk_x11_get_xatom_by_name ("_NET_WM_STATE");
        xev.xclient.format = 32;
-       xev.xclient.data.l[0] = tX_fullscreen_status ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
+       xev.xclient.data.l[0] = globals.fullscreen_enabled ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
        xev.xclient.data.l[1] = gdk_x11_atom_to_xatom (gdk_atom_intern ("_NET_WM_STATE_FULLSCREEN", TRUE));
        xev.xclient.data.l[2] = gdk_x11_atom_to_xatom (GDK_NONE);
        XSendEvent(gdk_display, GDK_WINDOW_XID (gdk_get_default_root_window ()),
@@ -1225,13 +1343,10 @@ void fullscreen_toggle() {
                &xev);  
 }
 
-#include <gdk/gdkkeysyms.h>
-
 void fullscreen_setup() {
-       GtkAccelGroup* accel_group=gtk_accel_group_new();
-       gtk_widget_add_accelerator (fullscreen_button, "activate", accel_group, GDK_F11, (GdkModifierType) 0, (GtkAccelFlags) 0);
-       g_signal_connect(fullscreen_button, "activate", (GCallback) fullscreen_toggle, NULL);
-       gtk_window_add_accel_group(GTK_WINDOW(main_window), accel_group);
+       if (globals.fullscreen_enabled) {
+               fullscreen_toggle(NULL, NULL);
+       }
 }
 
 void display_mastergui()
@@ -1240,8 +1355,8 @@ void display_mastergui()
        gtk_widget_realize(main_window);
        tX_set_icon(main_window, "terminatorX");
        load_knob_pixs(main_window);
-       fullscreen_setup();
        gtk_widget_show(main_window);
+       fullscreen_setup();     
        top=gtk_widget_get_toplevel(main_window);
        xwindow=GDK_WINDOW_XWINDOW(top->window);
 }
diff --git a/src/tX_midiin.cc b/src/tX_midiin.cc
new file mode 100644 (file)
index 0000000..d870f44
--- /dev/null
@@ -0,0 +1,319 @@
+/*
+  terminatorX - realtime audio scratching software
+  Copyright (C) 2002 Arthur Peters
+       
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+  File: tX_midiin.cc
+  Description: Implements MIDI input to control turntable parameters.
+*/    
+
+#include "tX_midiin.h"
+#include "tX_vtt.h"
+
+#ifdef USE_ALSA_MIDI_IN
+#include "tX_global.h"
+#include <iostream>
+
+using namespace std;
+
+void tX_midievent::print( const char* prefix ) const
+{
+       cerr << prefix << ": channel=" << channel << ", type=" << type << ", number=" << number
+                << ", value=" << value << ", is_noteon=" << is_noteon << endl;          
+}
+
+
+tX_midiin::tX_midiin()
+{
+       
+       int portid;
+
+       if (snd_seq_open(&ALSASeqHandle, "default", SND_SEQ_OPEN_INPUT, 0) < 0) {
+               tX_error("tx_midiin(): failed to open the default sequencer device.");
+               return;
+       }
+       snd_seq_set_client_name(ALSASeqHandle, "TerminatorX");
+       portid =
+               snd_seq_create_simple_port(ALSASeqHandle,
+                                                                  "Control Input",
+                                                                  SND_SEQ_PORT_CAP_WRITE
+                                                                  | SND_SEQ_PORT_CAP_SUBS_WRITE,
+                                                                  SND_SEQ_PORT_TYPE_APPLICATION);
+       if (portid < 0) {
+               cerr << "Error creating sequencer port." << endl;
+               return;
+       }
+
+       snd_seq_nonblock( ALSASeqHandle, 1 );
+  
+       tX_debug("tX_midiin(): sequencer successfully opened."); 
+}
+
+tX_midiin::~tX_midiin()
+{
+       snd_seq_close(ALSASeqHandle);
+       tX_debug("tX_midiin(): sequencer closed."); 
+}
+
+int tX_midiin::check_event()
+{
+       snd_seq_event_t *ev;
+       
+       while( snd_seq_event_input(ALSASeqHandle, &ev) != -EAGAIN )
+       {
+
+               //MidiEvent::type MessageType=MidiEvent::NONE;
+               //int Volume=0,Note=0,EventDevice=0;
+               tX_midievent event;
+               event.is_noteon = false;
+               bool event_usable = true;
+               
+               switch (ev->type) {
+                       case SND_SEQ_EVENT_CONTROLLER: 
+                               event.type = tX_midievent::CC;
+                               event.number = ev->data.control.param;
+                               event.value = ev->data.control.value / 127.0;
+                               event.channel = ev->data.control.channel;
+                               break;
+                       case SND_SEQ_EVENT_PITCHBEND:
+                               event.type = tX_midievent::PITCHBEND;
+                               event.number = ev->data.control.param;
+                               event.value = ev->data.control.value / 127.0;
+                               event.channel = ev->data.control.channel;
+                               break;
+                       case SND_SEQ_EVENT_NOTEON:
+                               event.type = tX_midievent::NOTE;
+                               event.number = ev->data.note.note;
+                               event.value = ev->data.note.velocity / 127.0;
+                               event.channel = ev->data.note.channel;
+
+                               event.is_noteon = true;
+                               if( event.value == 0 )
+                                       event.is_noteon = false;
+                               break;
+                       case SND_SEQ_EVENT_NOTEOFF: 
+                               event.type = tX_midievent::NOTE;
+                               event.number = ev->data.note.note;
+                               event.value = ev->data.note.velocity / 127.0;
+                               event.channel = ev->data.note.channel;
+                               
+                               event.is_noteon = false;
+                               break;
+                       default:
+                               event_usable = false;
+               }
+
+               snd_seq_free_event(ev);
+               
+               if( event_usable )
+               {
+                       if (event.channel<0 || event.channel>15)
+                       {
+                               tX_error("tX_midiin::check_event(): invaild event channel %i.", event.channel);
+                               return -1;
+                       }
+
+                       //cerr << event.type << ", " << event.number << ", " << event.value << endl;
+                       //event.print( __FUNCTION__ );
+
+                       list <tX_seqpar *> :: iterator sp;
+
+                       for (sp=tX_seqpar::all.begin(); sp!=tX_seqpar::all.end(); sp++) {
+                               if ( (*sp)->bound_midi_event.type_matches (event) ) {
+                                       (*sp)->handle_midi_input (event);
+                               }
+                       }
+
+                       last_event = event;
+               }
+
+       }
+       return 1;
+}
+
+void tX_midiin::configure_bindings( vtt_class* vtt )
+{
+       list <tX_seqpar *> :: iterator sp;
+
+       /*
+       tX_midievent event = {0,tX_midievent::CC,0,0,0};
+       event.type = tX_midievent::CC;
+       event.number = 11;
+       event.channel = 0;
+       */
+
+       GType types[3] = { G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER };
+       GtkListStore* model = gtk_list_store_newv(3, types);
+       GtkTreeIter iter;
+       char tempstr[128];
+       
+       for (sp=tX_seqpar::all.begin(); sp!=tX_seqpar::all.end(); sp++) {
+               if (((*sp)->is_mappable) && ((*sp)->vtt) == (void*) vtt) {
+                       
+                       snprintf( tempstr, sizeof(tempstr), "Type: %d, Number: %d, Channel: %d",
+                                         (*sp)->bound_midi_event.type, (*sp)->bound_midi_event.number,
+                                         (*sp)->bound_midi_event.channel );
+
+                       gtk_list_store_append( model, &iter );
+                       gtk_list_store_set( model, &iter,
+                                                               0, (*sp)->get_name(),
+                                                               1, tempstr,
+                                                               2, (*sp),
+                                                               -1 );
+
+                       //cerr << (*sp)->get_name() << endl;
+               }
+       }
+
+       // it will delete itself.
+       new midi_binding_gui(GTK_TREE_MODEL(model), this);
+
+       //cerr << "window created." << endl;
+
+       return;
+}
+
+tX_midiin::midi_binding_gui::midi_binding_gui ( GtkTreeModel* _model, tX_midiin* _midi )
+       : model(_model), midi( _midi )
+{
+  GtkWidget *hbox1;
+  GtkWidget *scrolledwindow1;
+  GtkWidget *vbox1;
+  GtkWidget *label1;
+  GtkWidget *frame1;
+
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title (GTK_WINDOW (window), "Configure MIDI Bindings");
+
+  hbox1 = gtk_hbox_new (FALSE, 0);
+  gtk_widget_show (hbox1);
+  gtk_container_add (GTK_CONTAINER (window), hbox1);
+
+  scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_show (scrolledwindow1);
+  gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow1, TRUE, TRUE, 0);
+
+  parameter_treeview = gtk_tree_view_new_with_model (model);
+    gtk_widget_show (parameter_treeview);
+  gtk_container_add (GTK_CONTAINER (scrolledwindow1), parameter_treeview);
+
+  GtkCellRenderer   *renderer = gtk_cell_renderer_text_new ();
+  gtk_tree_view_insert_column_with_attributes( GTK_TREE_VIEW( parameter_treeview ),
+                                                                                          -1, "Parameter", renderer,
+                                                                                          "text", 0,
+                                                                                          NULL );
+  gtk_tree_view_insert_column_with_attributes( GTK_TREE_VIEW( parameter_treeview ),
+                                                                                          -1, "Event", renderer,
+                                                                                          "text", 1,
+                                                                                          NULL );
+  gtk_tree_view_set_headers_visible( GTK_TREE_VIEW(parameter_treeview), TRUE );
+
+  vbox1 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_show (vbox1);
+  gtk_box_pack_start (GTK_BOX (hbox1), vbox1, FALSE, FALSE, 0);
+
+  label1 = gtk_label_new ("Selected MIDI Event:");
+  gtk_widget_show (label1);
+  gtk_box_pack_start (GTK_BOX (vbox1), label1, FALSE, FALSE, 0);
+  gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_LEFT);
+
+  frame1 = gtk_frame_new (NULL);
+  gtk_widget_show (frame1);
+  gtk_box_pack_start (GTK_BOX (vbox1), frame1, TRUE, TRUE, 0);
+  gtk_container_set_border_width (GTK_CONTAINER (frame1), 1);
+  gtk_frame_set_label_align (GTK_FRAME (frame1), 0, 0);
+  gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
+
+  midi_event_info = gtk_label_new ("Use a MIDI thing to select it.");
+  gtk_widget_show (midi_event_info);
+  gtk_container_add (GTK_CONTAINER (frame1), midi_event_info);
+  gtk_label_set_justify (GTK_LABEL (midi_event_info), GTK_JUSTIFY_LEFT);
+
+  bind_button = gtk_button_new_with_mnemonic ("Bind");
+  gtk_widget_show (bind_button);
+  gtk_box_pack_start (GTK_BOX (vbox1), bind_button, FALSE, FALSE, 0);
+
+  GtkWidget* close_button = gtk_button_new_with_mnemonic ("Close");
+  gtk_widget_show (close_button);
+  gtk_box_pack_start (GTK_BOX (vbox1), close_button, FALSE, FALSE, 0);
+
+  gtk_signal_connect(GTK_OBJECT(bind_button), "clicked", (GtkSignalFunc) bind_clicked, (void *) this);
+  gtk_signal_connect(GTK_OBJECT(close_button), "clicked", (GtkSignalFunc) close_clicked, (void *) this);
+
+  timer_tag = gtk_timeout_add( 100, (GtkFunction) timer, (void *) this);
+
+  gtk_widget_show_all( GTK_WIDGET( window ) );
+}
+
+void tX_midiin::midi_binding_gui::bind_clicked( GtkButton *button, gpointer _this )
+{
+       tX_midiin::midi_binding_gui* this_ = (tX_midiin::midi_binding_gui*)_this;
+       GtkTreeModel* model;
+       GtkTreeSelection* selection;
+       GtkTreeIter iter;
+       tX_seqpar* param;
+
+       selection = gtk_tree_view_get_selection( GTK_TREE_VIEW(this_->parameter_treeview) );
+       gtk_tree_selection_get_selected( selection, &model, &iter );
+       gtk_tree_model_get( model, &iter, 2, &param, -1 );
+
+       param->bound_midi_event = this_->last_event;
+}
+
+void tX_midiin::midi_binding_gui::close_clicked( GtkButton *button, gpointer _this )
+{
+       tX_midiin::midi_binding_gui* this_ = (tX_midiin::midi_binding_gui*)_this;
+       
+       gtk_widget_hide( this_->window );
+
+       delete this_;
+}
+
+gint tX_midiin::midi_binding_gui::timer( gpointer _this )
+{
+       tX_midiin::midi_binding_gui* this_ = (tX_midiin::midi_binding_gui*)_this;
+
+       this_->midi->check_event();
+       
+       tX_midievent tmpevent = this_->midi->get_last_event();
+
+       if( tmpevent.type_matches( this_->last_event ) )
+               return TRUE;
+       
+       this_->last_event = tmpevent;
+       this_->last_event.clear_non_type();
+
+       snprintf( this_->tempstr, sizeof(this_->tempstr),
+                         "Type: %d (CC=%d, NOTE=%d)\nNumber: %d\nChannel: %d\n",
+                         this_->last_event.type, tX_midievent::CC, tX_midievent::NOTE,
+                         this_->last_event.number,
+                         this_->last_event.channel );
+
+       gtk_label_set_text( GTK_LABEL(this_->midi_event_info), this_->tempstr );
+
+       return TRUE;
+}
+
+tX_midiin::midi_binding_gui::~midi_binding_gui ()
+{
+       gtk_timeout_remove( timer_tag );
+
+       //g_object_unref( window );
+       gtk_widget_destroy( window );
+}
+
+#endif // USE_ALSA_MIDI_IN
diff --git a/src/tX_midiin.h b/src/tX_midiin.h
new file mode 100644 (file)
index 0000000..54febe3
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+    terminatorX - realtime audio scratching software
+    Copyright (C) 2002 Arthur Peters
+       
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+    File: tX_midiin.h
+    Description: Header to tX_midiin.cc
+*/    
+
+#ifndef _tx_midiin_h
+#define _tx_midiin_h 1
+
+#include <config.h>
+#ifdef USE_ALSA_MIDI_IN
+
+#include <alsa/asoundlib.h>
+#include <gtk/gtk.h>
+
+class vtt_class;
+
+class tX_midievent
+{
+  public:
+       int channel;
+       enum
+       {
+               NONE=0,
+               CC=1,
+               NOTE,
+               PITCHBEND,
+       } type;
+       int number; // note # or controller #
+       
+       float value; // controller value or note velocity
+       bool is_noteon; // note on or off?
+
+       bool type_matches( const tX_midievent& other ) const
+       {
+               return channel == other.channel && type == other.type && number == other.number;
+       }
+
+       void clear_non_type()
+       {
+               value = 0;
+               is_noteon = false;
+       }
+
+       void print( const char* prefix ) const;
+};
+
+class tX_midiin
+{
+       snd_seq_t *ALSASeqHandle;
+       tX_midievent last_event;
+               
+  public:
+       tX_midiin();
+       ~tX_midiin();
+
+       int check_event();
+
+       void configure_bindings( vtt_class* );
+
+       const tX_midievent& get_last_event()
+       {
+               return last_event;
+       }
+
+  private:
+
+       class midi_binding_gui
+       {
+         public:
+               midi_binding_gui( GtkTreeModel* _model, tX_midiin* _midi );
+               ~midi_binding_gui();
+
+               GtkWidget *window;
+               
+               GtkWidget *parameter_treeview;
+               GtkWidget *midi_event_info;
+               GtkWidget *bind_button;
+
+               GtkTreeModel* model;
+
+               tX_midiin* midi;
+
+               tX_midievent last_event;
+
+               static void bind_clicked( GtkButton *button, gpointer _this );
+               static void close_clicked( GtkButton *button, gpointer _this );
+               static gint timer( gpointer _this );
+
+         private:
+               char tempstr[128];
+
+               gint timer_tag;
+       };
+};
+
+#endif // USE_ALSA_MIDI_IN
+
+#endif // ndef _tx_midiin_h 
index 6f42f29966464e2608fe0478f1a3cf1a6d823d99..57d5306a81ab4b7fe0abeebe3a3a09cffcbc19dc 100644 (file)
@@ -46,6 +46,7 @@ void tX_seqpar :: default_constructor()
        max_value=0;
        min_value=0;
        scale_value=0;
+       is_boolean=false;
        is_mappable=1;
        all.push_back(this);
        last_event_recorded=NULL;
@@ -105,6 +106,40 @@ void tX_seqpar :: handle_mouse_input(float adjustment)
        receive_input_value(tmpvalue);
 }
 
+#ifdef USE_ALSA_MIDI_IN
+void tX_seqpar :: handle_midi_input( const tX_midievent& event )
+{
+       float tmpvalue = -1000;
+
+       //event.print( (string(__FUNCTION__) + " - " + get_name()).c_str() );
+       
+       if( !is_boolean )
+       {
+               if( event.type == tX_midievent::CC || event.type == tX_midievent::PITCHBEND )
+               {       
+                       tmpvalue = event.value * (max_value-min_value) + min_value;
+               }
+               else if( event.type == tX_midievent::NOTE )
+               {
+                       tmpvalue = event.is_noteon;
+               }
+               else
+               {
+                       return;
+               }
+
+               if (tmpvalue>max_value) tmpvalue=max_value;
+               if (tmpvalue<min_value) tmpvalue=min_value;
+       }
+       else
+       {
+               tmpvalue=event.value;
+       }
+               
+       receive_input_value(tmpvalue);
+}
+#endif
+
 void tX_seqpar :: set_vtt (void *mytt)
 {
        vtt=mytt;
@@ -486,7 +521,8 @@ const char * tX_seqpar_vtt_pitch :: get_name()
 
 tX_seqpar_vtt_trigger :: tX_seqpar_vtt_trigger()
 {
-       set_mapping_parameters(0, 0, 0, 0);
+       set_mapping_parameters(0.01, 0, 1, 1);
+       is_boolean=true;
 }
 
 void tX_seqpar_vtt_trigger :: do_exec(const float value)
@@ -505,6 +541,8 @@ const char * tX_seqpar_vtt_trigger :: get_name()
 tX_seqpar_vtt_loop :: tX_seqpar_vtt_loop()
 {
        set_mapping_parameters(0, 0, 0, 0);
+       
+       is_boolean=true;
 }
 
 void tX_seqpar_vtt_loop :: do_exec(const float value)
@@ -570,7 +608,8 @@ const char * tX_seqpar_vtt_sync_cycles :: get_name()
 
 tX_seqpar_vtt_lp_enable :: tX_seqpar_vtt_lp_enable()
 {
-       set_mapping_parameters(0,0,0,0);
+       set_mapping_parameters(0.01,0,1,1);
+       is_boolean=true;
 }
 
 void tX_seqpar_vtt_lp_enable :: do_exec(const float value)
@@ -664,7 +703,8 @@ void tX_seqpar_vtt_lp_freq :: do_update_graphics ()
 
 tX_seqpar_vtt_ec_enable :: tX_seqpar_vtt_ec_enable()
 {
-       set_mapping_parameters(1.0, 0, 0, 0);
+       set_mapping_parameters(0.01,0,1,1);
+       is_boolean=true;
 }
 
 void tX_seqpar_vtt_ec_enable :: do_exec(const float value)
@@ -783,7 +823,8 @@ const char * tX_seqpar_vtt_ec_volume :: get_name()
 
 tX_seqpar_vtt_mute :: tX_seqpar_vtt_mute()
 {
-       set_mapping_parameters(0,0,0,0);
+       set_mapping_parameters(0.01,0,1,1);
+       is_boolean=true;
 }
 
 void tX_seqpar_vtt_mute :: do_exec(const float value)
index 9f34193a8a25e44090d274431f8daf6399c8241d..311bda19d60cefdd84b597bd6546c72cc0a69c38 100644 (file)
@@ -25,6 +25,7 @@
 #include <list>
 #include <gtk/gtk.h>
 #include "tX_extdial.h"
+#include "tX_midiin.h"
 
 #ifndef _tx_seqpar_h
 #define _tx_seqpar_h 1
@@ -40,6 +41,10 @@ class tX_seqpar
        public:
        static list <tX_seqpar *> all;
        void *vtt; /* have to make this void as tX_vtt.h includes this */
+
+#ifdef USE_ALSA_MIDI_IN
+       tX_midievent bound_midi_event;
+#endif 
        protected:
        static list <tX_seqpar *> update;
        static pthread_mutex_t update_lock;
@@ -103,7 +108,10 @@ class tX_seqpar
        
        /* slot for mouse and keyboard actions (updating graphics) */
        virtual void handle_mouse_input(float adjustment);
-       void receive_input_value(const float value); 
+       void receive_input_value(const float value);
+#ifdef USE_ALSA_MIDI_IN        
+       virtual void handle_midi_input( const tX_midievent& );
+#endif 
        
        /* Make it so ;) */
        static void materialize_forward_values();
@@ -117,6 +125,9 @@ class tX_seqpar
        float max_value;
        float min_value;
        float scale_value;
+
+       bool is_boolean;
+       
        public:
        int is_mappable;        
 };
index a792ef4122201c19b036f18cd4e9fc86602e32d1..17552221aba157d358d984088bf8617f44c787d2 100644 (file)
@@ -546,7 +546,9 @@ vtt_fx_ladspa * vtt_class :: add_effect (LADSPA_Plugin *plugin)
 
 void vtt_class :: calc_speed()
 {
-       do_mute=fade_out=fade_in=0;
+       do_mute=0;
+       fade_out=0;
+       fade_in=0;
 
        if (speed != speed_target)
        {
index 259734414748e1385dc03b785cd34916f07c8729..50311c87d84fd395642962761701955240242fa1 100644 (file)
@@ -47,6 +47,7 @@
 #include "tX_extdial.h"
 #include "tX_panel.h"
 #include "tX_ladspa.h"
+#include "tX_engine.h"
 
 #ifdef USE_DIAL
 #include "tX_dial.h"
@@ -388,6 +389,13 @@ void ec_enabled(GtkWidget *wid, vtt_class *vtt)
        vtt->sp_ec_enable.receive_gui_value(GTK_TOGGLE_BUTTON(wid)->active);
 }
 
+#ifdef USE_ALSA_MIDI_IN
+void midi_mapping_clicked(GtkWidget *wid, vtt_class *vtt)
+{
+       engine->midi->configure_bindings(vtt);
+}
+#endif
+
 void ec_length_changed(GtkWidget *wid, vtt_class *vtt)
 {
        vtt->sp_ec_length.receive_gui_value(GTK_ADJUSTMENT(wid)->value);
@@ -698,6 +706,9 @@ void gui_connect_signals(vtt_class *vtt)
        connect_adj(lp_freq, lp_freq_changed);
        
        connect_button(ec_enable, ec_enabled);
+#ifdef USE_ALSA_MIDI_IN        
+       connect_button(midi_mapping, midi_mapping_clicked);
+#endif 
        connect_adj(ec_length, ec_length_changed);
        connect_adj(ec_feedback, ec_feedback_changed);
        connect_adj(ec_pan, ec_pan_changed);
@@ -779,9 +790,15 @@ void build_vtt_gui(vtt_class *vtt)
        g->mouse_mapping=gtk_button_new_with_label("Mouse Mapping");
        gtk_widget_show(g->mouse_mapping);
        gui_set_tooltip(g->mouse_mapping, "Determines what parameters should be affected on mouse moition in mouse grab mode.");
-   
        gtk_box_pack_start(GTK_BOX(tempbox), g->mouse_mapping, WID_DYN);
 
+#ifdef USE_ALSA_MIDI_IN
+       g->midi_mapping=gtk_button_new_with_label("MIDI Mapping");
+       gtk_widget_show(g->midi_mapping);
+       gui_set_tooltip(g->midi_mapping, "Determines what parameters should be bound to what MIDI events.");
+       gtk_box_pack_start(GTK_BOX(tempbox), g->midi_mapping, WID_DYN);
+#endif
+
        tempbox=gtk_hbox_new(FALSE, 2);
 
        g->display=gtk_tx_new(vtt->buffer, vtt->samples_in_buffer);
@@ -823,7 +840,7 @@ void build_vtt_gui(vtt_class *vtt)
        g->scrolled_win=gtk_scrolled_window_new (NULL, NULL);
        gtk_container_set_border_width (GTK_CONTAINER (g->scrolled_win), 0);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (g->scrolled_win),
-                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+                                    GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
        gtk_widget_show(g->scrolled_win);
        gtk_box_pack_start(GTK_BOX(g->control_box), g->scrolled_win, WID_DYN);
                                    
index f7c7cb598c171b4e5925884988ed909cfba484bf..875118a74a4d4de6d918e01cecbaac639ad40ed9 100644 (file)
@@ -118,7 +118,11 @@ typedef struct vtt_gui
        GtkWidget *mouse_mapping_menu;
        GtkWidget *mouse_mapping_menu_x;
        GtkWidget *mouse_mapping_menu_y;
-       
+
+#ifdef USE_ALSA_MIDI_IN
+       GtkWidget *midi_mapping;
+#endif 
+
        GtkWidget *audio_minimized_panel_bar_button;
        GtkWidget *control_minimized_panel_bar_button;
 
index beb363891402a4d82a2f6441ee97dd523792d8d9..d49423f26f989c8802b5a320f50282f182c8a416 100644 (file)
@@ -30,6 +30,7 @@
 #include "tX_types.h"
 #include "tX_global.h"
 #include <malloc.h>
+#include <stdlib.h>
 
 #ifndef WIN32
 #include <unistd.h>